linux/drivers/iio/gyro/st_gyro_core.c
<<
>>
Prefs
   1/*
   2 * STMicroelectronics gyroscopes driver
   3 *
   4 * Copyright 2012-2013 STMicroelectronics Inc.
   5 *
   6 * Denis Ciocca <denis.ciocca@st.com>
   7 *
   8 * Licensed under the GPL-2.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/slab.h>
  14#include <linux/errno.h>
  15#include <linux/types.h>
  16#include <linux/mutex.h>
  17#include <linux/interrupt.h>
  18#include <linux/i2c.h>
  19#include <linux/gpio.h>
  20#include <linux/irq.h>
  21#include <linux/delay.h>
  22#include <linux/iio/iio.h>
  23#include <linux/iio/sysfs.h>
  24#include <linux/iio/trigger.h>
  25#include <linux/iio/buffer.h>
  26
  27#include <linux/iio/common/st_sensors.h>
  28#include "st_gyro.h"
  29
  30/* DEFAULT VALUE FOR SENSORS */
  31#define ST_GYRO_DEFAULT_OUT_X_L_ADDR            0x28
  32#define ST_GYRO_DEFAULT_OUT_Y_L_ADDR            0x2a
  33#define ST_GYRO_DEFAULT_OUT_Z_L_ADDR            0x2c
  34
  35/* FULLSCALE */
  36#define ST_GYRO_FS_AVL_250DPS                   250
  37#define ST_GYRO_FS_AVL_500DPS                   500
  38#define ST_GYRO_FS_AVL_2000DPS                  2000
  39
  40/* CUSTOM VALUES FOR SENSOR 1 */
  41#define ST_GYRO_1_WAI_EXP                       0xd3
  42#define ST_GYRO_1_ODR_ADDR                      0x20
  43#define ST_GYRO_1_ODR_MASK                      0xc0
  44#define ST_GYRO_1_ODR_AVL_100HZ_VAL             0x00
  45#define ST_GYRO_1_ODR_AVL_200HZ_VAL             0x01
  46#define ST_GYRO_1_ODR_AVL_400HZ_VAL             0x02
  47#define ST_GYRO_1_ODR_AVL_800HZ_VAL             0x03
  48#define ST_GYRO_1_PW_ADDR                       0x20
  49#define ST_GYRO_1_PW_MASK                       0x08
  50#define ST_GYRO_1_FS_ADDR                       0x23
  51#define ST_GYRO_1_FS_MASK                       0x30
  52#define ST_GYRO_1_FS_AVL_250_VAL                0x00
  53#define ST_GYRO_1_FS_AVL_500_VAL                0x01
  54#define ST_GYRO_1_FS_AVL_2000_VAL               0x02
  55#define ST_GYRO_1_FS_AVL_250_GAIN               IIO_DEGREE_TO_RAD(8750)
  56#define ST_GYRO_1_FS_AVL_500_GAIN               IIO_DEGREE_TO_RAD(17500)
  57#define ST_GYRO_1_FS_AVL_2000_GAIN              IIO_DEGREE_TO_RAD(70000)
  58#define ST_GYRO_1_BDU_ADDR                      0x23
  59#define ST_GYRO_1_BDU_MASK                      0x80
  60#define ST_GYRO_1_DRDY_IRQ_ADDR                 0x22
  61#define ST_GYRO_1_DRDY_IRQ_MASK                 0x08
  62#define ST_GYRO_1_MULTIREAD_BIT                 true
  63
  64/* CUSTOM VALUES FOR SENSOR 2 */
  65#define ST_GYRO_2_WAI_EXP                       0xd4
  66#define ST_GYRO_2_ODR_ADDR                      0x20
  67#define ST_GYRO_2_ODR_MASK                      0xc0
  68#define ST_GYRO_2_ODR_AVL_95HZ_VAL              0x00
  69#define ST_GYRO_2_ODR_AVL_190HZ_VAL             0x01
  70#define ST_GYRO_2_ODR_AVL_380HZ_VAL             0x02
  71#define ST_GYRO_2_ODR_AVL_760HZ_VAL             0x03
  72#define ST_GYRO_2_PW_ADDR                       0x20
  73#define ST_GYRO_2_PW_MASK                       0x08
  74#define ST_GYRO_2_FS_ADDR                       0x23
  75#define ST_GYRO_2_FS_MASK                       0x30
  76#define ST_GYRO_2_FS_AVL_250_VAL                0x00
  77#define ST_GYRO_2_FS_AVL_500_VAL                0x01
  78#define ST_GYRO_2_FS_AVL_2000_VAL               0x02
  79#define ST_GYRO_2_FS_AVL_250_GAIN               IIO_DEGREE_TO_RAD(8750)
  80#define ST_GYRO_2_FS_AVL_500_GAIN               IIO_DEGREE_TO_RAD(17500)
  81#define ST_GYRO_2_FS_AVL_2000_GAIN              IIO_DEGREE_TO_RAD(70000)
  82#define ST_GYRO_2_BDU_ADDR                      0x23
  83#define ST_GYRO_2_BDU_MASK                      0x80
  84#define ST_GYRO_2_DRDY_IRQ_ADDR                 0x22
  85#define ST_GYRO_2_DRDY_IRQ_MASK                 0x08
  86#define ST_GYRO_2_MULTIREAD_BIT                 true
  87
  88static const struct iio_chan_spec st_gyro_16bit_channels[] = {
  89        ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_X,
  90                IIO_MOD_X, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
  91                                                ST_GYRO_DEFAULT_OUT_X_L_ADDR),
  92        ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Y,
  93                IIO_MOD_Y, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
  94                                                ST_GYRO_DEFAULT_OUT_Y_L_ADDR),
  95        ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Z,
  96                IIO_MOD_Z, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
  97                                                ST_GYRO_DEFAULT_OUT_Z_L_ADDR),
  98        IIO_CHAN_SOFT_TIMESTAMP(3)
  99};
 100
 101static const struct st_sensors st_gyro_sensors[] = {
 102        {
 103                .wai = ST_GYRO_1_WAI_EXP,
 104                .sensors_supported = {
 105                        [0] = L3G4200D_GYRO_DEV_NAME,
 106                        [1] = LSM330DL_GYRO_DEV_NAME,
 107                },
 108                .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
 109                .odr = {
 110                        .addr = ST_GYRO_1_ODR_ADDR,
 111                        .mask = ST_GYRO_1_ODR_MASK,
 112                        .odr_avl = {
 113                                { 100, ST_GYRO_1_ODR_AVL_100HZ_VAL, },
 114                                { 200, ST_GYRO_1_ODR_AVL_200HZ_VAL, },
 115                                { 400, ST_GYRO_1_ODR_AVL_400HZ_VAL, },
 116                                { 800, ST_GYRO_1_ODR_AVL_800HZ_VAL, },
 117                        },
 118                },
 119                .pw = {
 120                        .addr = ST_GYRO_1_PW_ADDR,
 121                        .mask = ST_GYRO_1_PW_MASK,
 122                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 123                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 124                },
 125                .enable_axis = {
 126                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 127                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 128                },
 129                .fs = {
 130                        .addr = ST_GYRO_1_FS_ADDR,
 131                        .mask = ST_GYRO_1_FS_MASK,
 132                        .fs_avl = {
 133                                [0] = {
 134                                        .num = ST_GYRO_FS_AVL_250DPS,
 135                                        .value = ST_GYRO_1_FS_AVL_250_VAL,
 136                                        .gain = ST_GYRO_1_FS_AVL_250_GAIN,
 137                                },
 138                                [1] = {
 139                                        .num = ST_GYRO_FS_AVL_500DPS,
 140                                        .value = ST_GYRO_1_FS_AVL_500_VAL,
 141                                        .gain = ST_GYRO_1_FS_AVL_500_GAIN,
 142                                },
 143                                [2] = {
 144                                        .num = ST_GYRO_FS_AVL_2000DPS,
 145                                        .value = ST_GYRO_1_FS_AVL_2000_VAL,
 146                                        .gain = ST_GYRO_1_FS_AVL_2000_GAIN,
 147                                },
 148                        },
 149                },
 150                .bdu = {
 151                        .addr = ST_GYRO_1_BDU_ADDR,
 152                        .mask = ST_GYRO_1_BDU_MASK,
 153                },
 154                .drdy_irq = {
 155                        .addr = ST_GYRO_1_DRDY_IRQ_ADDR,
 156                        .mask = ST_GYRO_1_DRDY_IRQ_MASK,
 157                },
 158                .multi_read_bit = ST_GYRO_1_MULTIREAD_BIT,
 159                .bootime = 2,
 160        },
 161        {
 162                .wai = ST_GYRO_2_WAI_EXP,
 163                .sensors_supported = {
 164                        [0] = L3GD20_GYRO_DEV_NAME,
 165                        [1] = L3GD20H_GYRO_DEV_NAME,
 166                        [2] = LSM330D_GYRO_DEV_NAME,
 167                        [3] = LSM330DLC_GYRO_DEV_NAME,
 168                        [4] = L3G4IS_GYRO_DEV_NAME,
 169                        [5] = LSM330_GYRO_DEV_NAME,
 170                },
 171                .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
 172                .odr = {
 173                        .addr = ST_GYRO_2_ODR_ADDR,
 174                        .mask = ST_GYRO_2_ODR_MASK,
 175                        .odr_avl = {
 176                                { 95, ST_GYRO_2_ODR_AVL_95HZ_VAL, },
 177                                { 190, ST_GYRO_2_ODR_AVL_190HZ_VAL, },
 178                                { 380, ST_GYRO_2_ODR_AVL_380HZ_VAL, },
 179                                { 760, ST_GYRO_2_ODR_AVL_760HZ_VAL, },
 180                        },
 181                },
 182                .pw = {
 183                        .addr = ST_GYRO_2_PW_ADDR,
 184                        .mask = ST_GYRO_2_PW_MASK,
 185                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 186                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 187                },
 188                .enable_axis = {
 189                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 190                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 191                },
 192                .fs = {
 193                        .addr = ST_GYRO_2_FS_ADDR,
 194                        .mask = ST_GYRO_2_FS_MASK,
 195                        .fs_avl = {
 196                                [0] = {
 197                                        .num = ST_GYRO_FS_AVL_250DPS,
 198                                        .value = ST_GYRO_2_FS_AVL_250_VAL,
 199                                        .gain = ST_GYRO_2_FS_AVL_250_GAIN,
 200                                },
 201                                [1] = {
 202                                        .num = ST_GYRO_FS_AVL_500DPS,
 203                                        .value = ST_GYRO_2_FS_AVL_500_VAL,
 204                                        .gain = ST_GYRO_2_FS_AVL_500_GAIN,
 205                                },
 206                                [2] = {
 207                                        .num = ST_GYRO_FS_AVL_2000DPS,
 208                                        .value = ST_GYRO_2_FS_AVL_2000_VAL,
 209                                        .gain = ST_GYRO_2_FS_AVL_2000_GAIN,
 210                                },
 211                        },
 212                },
 213                .bdu = {
 214                        .addr = ST_GYRO_2_BDU_ADDR,
 215                        .mask = ST_GYRO_2_BDU_MASK,
 216                },
 217                .drdy_irq = {
 218                        .addr = ST_GYRO_2_DRDY_IRQ_ADDR,
 219                        .mask = ST_GYRO_2_DRDY_IRQ_MASK,
 220                },
 221                .multi_read_bit = ST_GYRO_2_MULTIREAD_BIT,
 222                .bootime = 2,
 223        },
 224};
 225
 226static int st_gyro_read_raw(struct iio_dev *indio_dev,
 227                        struct iio_chan_spec const *ch, int *val,
 228                                                        int *val2, long mask)
 229{
 230        int err;
 231        struct st_sensor_data *gdata = iio_priv(indio_dev);
 232
 233        switch (mask) {
 234        case IIO_CHAN_INFO_RAW:
 235                err = st_sensors_read_info_raw(indio_dev, ch, val);
 236                if (err < 0)
 237                        goto read_error;
 238
 239                return IIO_VAL_INT;
 240        case IIO_CHAN_INFO_SCALE:
 241                *val = 0;
 242                *val2 = gdata->current_fullscale->gain;
 243                return IIO_VAL_INT_PLUS_MICRO;
 244        default:
 245                return -EINVAL;
 246        }
 247
 248read_error:
 249        return err;
 250}
 251
 252static int st_gyro_write_raw(struct iio_dev *indio_dev,
 253                struct iio_chan_spec const *chan, int val, int val2, long mask)
 254{
 255        int err;
 256
 257        switch (mask) {
 258        case IIO_CHAN_INFO_SCALE:
 259                err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
 260                break;
 261        default:
 262                err = -EINVAL;
 263        }
 264
 265        return err;
 266}
 267
 268static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
 269static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 270static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
 271
 272static struct attribute *st_gyro_attributes[] = {
 273        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 274        &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
 275        &iio_dev_attr_sampling_frequency.dev_attr.attr,
 276        NULL,
 277};
 278
 279static const struct attribute_group st_gyro_attribute_group = {
 280        .attrs = st_gyro_attributes,
 281};
 282
 283static const struct iio_info gyro_info = {
 284        .driver_module = THIS_MODULE,
 285        .attrs = &st_gyro_attribute_group,
 286        .read_raw = &st_gyro_read_raw,
 287        .write_raw = &st_gyro_write_raw,
 288};
 289
 290#ifdef CONFIG_IIO_TRIGGER
 291static const struct iio_trigger_ops st_gyro_trigger_ops = {
 292        .owner = THIS_MODULE,
 293        .set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
 294};
 295#define ST_GYRO_TRIGGER_OPS (&st_gyro_trigger_ops)
 296#else
 297#define ST_GYRO_TRIGGER_OPS NULL
 298#endif
 299
 300int st_gyro_common_probe(struct iio_dev *indio_dev)
 301{
 302        int err;
 303        struct st_sensor_data *gdata = iio_priv(indio_dev);
 304
 305        indio_dev->modes = INDIO_DIRECT_MODE;
 306        indio_dev->info = &gyro_info;
 307
 308        err = st_sensors_check_device_support(indio_dev,
 309                                ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
 310        if (err < 0)
 311                goto st_gyro_common_probe_error;
 312
 313        gdata->multiread_bit = gdata->sensor->multi_read_bit;
 314        indio_dev->channels = gdata->sensor->ch;
 315        indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
 316
 317        gdata->current_fullscale = (struct st_sensor_fullscale_avl *)
 318                                                &gdata->sensor->fs.fs_avl[0];
 319        gdata->odr = gdata->sensor->odr.odr_avl[0].hz;
 320
 321        err = st_sensors_init_sensor(indio_dev);
 322        if (err < 0)
 323                goto st_gyro_common_probe_error;
 324
 325        if (gdata->get_irq_data_ready(indio_dev) > 0) {
 326                err = st_gyro_allocate_ring(indio_dev);
 327                if (err < 0)
 328                        goto st_gyro_common_probe_error;
 329
 330                err = st_sensors_allocate_trigger(indio_dev,
 331                                                  ST_GYRO_TRIGGER_OPS);
 332                if (err < 0)
 333                        goto st_gyro_probe_trigger_error;
 334        }
 335
 336        err = iio_device_register(indio_dev);
 337        if (err)
 338                goto st_gyro_device_register_error;
 339
 340        return err;
 341
 342st_gyro_device_register_error:
 343        if (gdata->get_irq_data_ready(indio_dev) > 0)
 344                st_sensors_deallocate_trigger(indio_dev);
 345st_gyro_probe_trigger_error:
 346        if (gdata->get_irq_data_ready(indio_dev) > 0)
 347                st_gyro_deallocate_ring(indio_dev);
 348st_gyro_common_probe_error:
 349        return err;
 350}
 351EXPORT_SYMBOL(st_gyro_common_probe);
 352
 353void st_gyro_common_remove(struct iio_dev *indio_dev)
 354{
 355        struct st_sensor_data *gdata = iio_priv(indio_dev);
 356
 357        iio_device_unregister(indio_dev);
 358        if (gdata->get_irq_data_ready(indio_dev) > 0) {
 359                st_sensors_deallocate_trigger(indio_dev);
 360                st_gyro_deallocate_ring(indio_dev);
 361        }
 362        iio_device_free(indio_dev);
 363}
 364EXPORT_SYMBOL(st_gyro_common_remove);
 365
 366MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
 367MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
 368MODULE_LICENSE("GPL v2");
 369