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