linux/drivers/iio/gyro/st_gyro_core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * STMicroelectronics gyroscopes driver
   4 *
   5 * Copyright 2012-2013 STMicroelectronics Inc.
   6 *
   7 * Denis Ciocca <denis.ciocca@st.com>
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/slab.h>
  13#include <linux/errno.h>
  14#include <linux/types.h>
  15#include <linux/mutex.h>
  16#include <linux/interrupt.h>
  17#include <linux/i2c.h>
  18#include <linux/gpio.h>
  19#include <linux/irq.h>
  20#include <linux/delay.h>
  21#include <linux/iio/iio.h>
  22#include <linux/iio/sysfs.h>
  23#include <linux/iio/trigger.h>
  24#include <linux/iio/buffer.h>
  25
  26#include <linux/iio/common/st_sensors.h>
  27#include "st_gyro.h"
  28
  29#define ST_GYRO_NUMBER_DATA_CHANNELS            3
  30
  31/* DEFAULT VALUE FOR SENSORS */
  32#define ST_GYRO_DEFAULT_OUT_X_L_ADDR            0x28
  33#define ST_GYRO_DEFAULT_OUT_Y_L_ADDR            0x2a
  34#define ST_GYRO_DEFAULT_OUT_Z_L_ADDR            0x2c
  35
  36/* FULLSCALE */
  37#define ST_GYRO_FS_AVL_245DPS                   245
  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
  42static const struct iio_chan_spec st_gyro_16bit_channels[] = {
  43        ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL,
  44                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  45                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
  46                        ST_GYRO_DEFAULT_OUT_X_L_ADDR),
  47        ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL,
  48                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  49                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
  50                        ST_GYRO_DEFAULT_OUT_Y_L_ADDR),
  51        ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL,
  52                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  53                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
  54                        ST_GYRO_DEFAULT_OUT_Z_L_ADDR),
  55        IIO_CHAN_SOFT_TIMESTAMP(3)
  56};
  57
  58static const struct st_sensor_settings st_gyro_sensors_settings[] = {
  59        {
  60                .wai = 0xd3,
  61                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
  62                .sensors_supported = {
  63                        [0] = L3G4200D_GYRO_DEV_NAME,
  64                        [1] = LSM330DL_GYRO_DEV_NAME,
  65                },
  66                .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
  67                .odr = {
  68                        .addr = 0x20,
  69                        .mask = 0xc0,
  70                        .odr_avl = {
  71                                { .hz = 100, .value = 0x00, },
  72                                { .hz = 200, .value = 0x01, },
  73                                { .hz = 400, .value = 0x02, },
  74                                { .hz = 800, .value = 0x03, },
  75                        },
  76                },
  77                .pw = {
  78                        .addr = 0x20,
  79                        .mask = 0x08,
  80                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
  81                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
  82                },
  83                .enable_axis = {
  84                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
  85                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
  86                },
  87                .fs = {
  88                        .addr = 0x23,
  89                        .mask = 0x30,
  90                        .fs_avl = {
  91                                [0] = {
  92                                        .num = ST_GYRO_FS_AVL_250DPS,
  93                                        .value = 0x00,
  94                                        .gain = IIO_DEGREE_TO_RAD(8750),
  95                                },
  96                                [1] = {
  97                                        .num = ST_GYRO_FS_AVL_500DPS,
  98                                        .value = 0x01,
  99                                        .gain = IIO_DEGREE_TO_RAD(17500),
 100                                },
 101                                [2] = {
 102                                        .num = ST_GYRO_FS_AVL_2000DPS,
 103                                        .value = 0x02,
 104                                        .gain = IIO_DEGREE_TO_RAD(70000),
 105                                },
 106                        },
 107                },
 108                .bdu = {
 109                        .addr = 0x23,
 110                        .mask = 0x80,
 111                },
 112                .drdy_irq = {
 113                        .int2 = {
 114                                .addr = 0x22,
 115                                .mask = 0x08,
 116                        },
 117                        /*
 118                         * The sensor has IHL (active low) and open
 119                         * drain settings, but only for INT1 and not
 120                         * for the DRDY line on INT2.
 121                         */
 122                        .stat_drdy = {
 123                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 124                                .mask = 0x07,
 125                        },
 126                },
 127                .sim = {
 128                        .addr = 0x23,
 129                        .value = BIT(0),
 130                },
 131                .multi_read_bit = true,
 132                .bootime = 2,
 133        },
 134        {
 135                .wai = 0xd4,
 136                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 137                .sensors_supported = {
 138                        [0] = L3GD20_GYRO_DEV_NAME,
 139                        [1] = LSM330D_GYRO_DEV_NAME,
 140                        [2] = LSM330DLC_GYRO_DEV_NAME,
 141                        [3] = L3G4IS_GYRO_DEV_NAME,
 142                        [4] = LSM330_GYRO_DEV_NAME,
 143                        [5] = LSM9DS0_GYRO_DEV_NAME,
 144                },
 145                .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
 146                .odr = {
 147                        .addr = 0x20,
 148                        .mask = 0xc0,
 149                        .odr_avl = {
 150                                { .hz = 95, .value = 0x00, },
 151                                { .hz = 190, .value = 0x01, },
 152                                { .hz = 380, .value = 0x02, },
 153                                { .hz = 760, .value = 0x03, },
 154                        },
 155                },
 156                .pw = {
 157                        .addr = 0x20,
 158                        .mask = 0x08,
 159                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 160                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 161                },
 162                .enable_axis = {
 163                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 164                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 165                },
 166                .fs = {
 167                        .addr = 0x23,
 168                        .mask = 0x30,
 169                        .fs_avl = {
 170                                [0] = {
 171                                        .num = ST_GYRO_FS_AVL_250DPS,
 172                                        .value = 0x00,
 173                                        .gain = IIO_DEGREE_TO_RAD(8750),
 174                                },
 175                                [1] = {
 176                                        .num = ST_GYRO_FS_AVL_500DPS,
 177                                        .value = 0x01,
 178                                        .gain = IIO_DEGREE_TO_RAD(17500),
 179                                },
 180                                [2] = {
 181                                        .num = ST_GYRO_FS_AVL_2000DPS,
 182                                        .value = 0x02,
 183                                        .gain = IIO_DEGREE_TO_RAD(70000),
 184                                },
 185                        },
 186                },
 187                .bdu = {
 188                        .addr = 0x23,
 189                        .mask = 0x80,
 190                },
 191                .drdy_irq = {
 192                        .int2 = {
 193                                .addr = 0x22,
 194                                .mask = 0x08,
 195                        },
 196                        /*
 197                         * The sensor has IHL (active low) and open
 198                         * drain settings, but only for INT1 and not
 199                         * for the DRDY line on INT2.
 200                         */
 201                        .stat_drdy = {
 202                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 203                                .mask = 0x07,
 204                        },
 205                },
 206                .sim = {
 207                        .addr = 0x23,
 208                        .value = BIT(0),
 209                },
 210                .multi_read_bit = true,
 211                .bootime = 2,
 212        },
 213        {
 214                .wai = 0xd7,
 215                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 216                .sensors_supported = {
 217                        [0] = L3GD20H_GYRO_DEV_NAME,
 218                },
 219                .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
 220                .odr = {
 221                        .addr = 0x20,
 222                        .mask = 0xc0,
 223                        .odr_avl = {
 224                                { .hz = 100, .value = 0x00, },
 225                                { .hz = 200, .value = 0x01, },
 226                                { .hz = 400, .value = 0x02, },
 227                                { .hz = 800, .value = 0x03, },
 228                        },
 229                },
 230                .pw = {
 231                        .addr = 0x20,
 232                        .mask = 0x08,
 233                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 234                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 235                },
 236                .enable_axis = {
 237                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 238                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 239                },
 240                .fs = {
 241                        .addr = 0x23,
 242                        .mask = 0x30,
 243                        .fs_avl = {
 244                                [0] = {
 245                                        .num = ST_GYRO_FS_AVL_245DPS,
 246                                        .value = 0x00,
 247                                        .gain = IIO_DEGREE_TO_RAD(8750),
 248                                },
 249                                [1] = {
 250                                        .num = ST_GYRO_FS_AVL_500DPS,
 251                                        .value = 0x01,
 252                                        .gain = IIO_DEGREE_TO_RAD(17500),
 253                                },
 254                                [2] = {
 255                                        .num = ST_GYRO_FS_AVL_2000DPS,
 256                                        .value = 0x02,
 257                                        .gain = IIO_DEGREE_TO_RAD(70000),
 258                                },
 259                        },
 260                },
 261                .bdu = {
 262                        .addr = 0x23,
 263                        .mask = 0x80,
 264                },
 265                .drdy_irq = {
 266                        .int2 = {
 267                                .addr = 0x22,
 268                                .mask = 0x08,
 269                        },
 270                        /*
 271                         * The sensor has IHL (active low) and open
 272                         * drain settings, but only for INT1 and not
 273                         * for the DRDY line on INT2.
 274                         */
 275                        .stat_drdy = {
 276                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 277                                .mask = 0x07,
 278                        },
 279                },
 280                .sim = {
 281                        .addr = 0x23,
 282                        .value = BIT(0),
 283                },
 284                .multi_read_bit = true,
 285                .bootime = 2,
 286        },
 287};
 288
 289static int st_gyro_read_raw(struct iio_dev *indio_dev,
 290                        struct iio_chan_spec const *ch, int *val,
 291                                                        int *val2, long mask)
 292{
 293        int err;
 294        struct st_sensor_data *gdata = iio_priv(indio_dev);
 295
 296        switch (mask) {
 297        case IIO_CHAN_INFO_RAW:
 298                err = st_sensors_read_info_raw(indio_dev, ch, val);
 299                if (err < 0)
 300                        goto read_error;
 301
 302                return IIO_VAL_INT;
 303        case IIO_CHAN_INFO_SCALE:
 304                *val = 0;
 305                *val2 = gdata->current_fullscale->gain;
 306                return IIO_VAL_INT_PLUS_MICRO;
 307        case IIO_CHAN_INFO_SAMP_FREQ:
 308                *val = gdata->odr;
 309                return IIO_VAL_INT;
 310        default:
 311                return -EINVAL;
 312        }
 313
 314read_error:
 315        return err;
 316}
 317
 318static int st_gyro_write_raw(struct iio_dev *indio_dev,
 319                struct iio_chan_spec const *chan, int val, int val2, long mask)
 320{
 321        int err;
 322
 323        switch (mask) {
 324        case IIO_CHAN_INFO_SCALE:
 325                err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
 326                break;
 327        case IIO_CHAN_INFO_SAMP_FREQ:
 328                if (val2)
 329                        return -EINVAL;
 330                mutex_lock(&indio_dev->mlock);
 331                err = st_sensors_set_odr(indio_dev, val);
 332                mutex_unlock(&indio_dev->mlock);
 333                return err;
 334        default:
 335                err = -EINVAL;
 336        }
 337
 338        return err;
 339}
 340
 341static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 342static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
 343
 344static struct attribute *st_gyro_attributes[] = {
 345        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 346        &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
 347        NULL,
 348};
 349
 350static const struct attribute_group st_gyro_attribute_group = {
 351        .attrs = st_gyro_attributes,
 352};
 353
 354static const struct iio_info gyro_info = {
 355        .attrs = &st_gyro_attribute_group,
 356        .read_raw = &st_gyro_read_raw,
 357        .write_raw = &st_gyro_write_raw,
 358        .debugfs_reg_access = &st_sensors_debugfs_reg_access,
 359};
 360
 361#ifdef CONFIG_IIO_TRIGGER
 362static const struct iio_trigger_ops st_gyro_trigger_ops = {
 363        .set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
 364        .validate_device = st_sensors_validate_device,
 365};
 366#define ST_GYRO_TRIGGER_OPS (&st_gyro_trigger_ops)
 367#else
 368#define ST_GYRO_TRIGGER_OPS NULL
 369#endif
 370
 371int st_gyro_common_probe(struct iio_dev *indio_dev)
 372{
 373        struct st_sensor_data *gdata = iio_priv(indio_dev);
 374        int irq = gdata->get_irq_data_ready(indio_dev);
 375        int err;
 376
 377        indio_dev->modes = INDIO_DIRECT_MODE;
 378        indio_dev->info = &gyro_info;
 379        mutex_init(&gdata->tb.buf_lock);
 380
 381        err = st_sensors_power_enable(indio_dev);
 382        if (err)
 383                return err;
 384
 385        err = st_sensors_check_device_support(indio_dev,
 386                                        ARRAY_SIZE(st_gyro_sensors_settings),
 387                                        st_gyro_sensors_settings);
 388        if (err < 0)
 389                goto st_gyro_power_off;
 390
 391        gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
 392        gdata->multiread_bit = gdata->sensor_settings->multi_read_bit;
 393        indio_dev->channels = gdata->sensor_settings->ch;
 394        indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
 395
 396        gdata->current_fullscale = (struct st_sensor_fullscale_avl *)
 397                                        &gdata->sensor_settings->fs.fs_avl[0];
 398        gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz;
 399
 400        err = st_sensors_init_sensor(indio_dev,
 401                                (struct st_sensors_platform_data *)&gyro_pdata);
 402        if (err < 0)
 403                goto st_gyro_power_off;
 404
 405        err = st_gyro_allocate_ring(indio_dev);
 406        if (err < 0)
 407                goto st_gyro_power_off;
 408
 409        if (irq > 0) {
 410                err = st_sensors_allocate_trigger(indio_dev,
 411                                                  ST_GYRO_TRIGGER_OPS);
 412                if (err < 0)
 413                        goto st_gyro_probe_trigger_error;
 414        }
 415
 416        err = iio_device_register(indio_dev);
 417        if (err)
 418                goto st_gyro_device_register_error;
 419
 420        dev_info(&indio_dev->dev, "registered gyroscope %s\n",
 421                 indio_dev->name);
 422
 423        return 0;
 424
 425st_gyro_device_register_error:
 426        if (irq > 0)
 427                st_sensors_deallocate_trigger(indio_dev);
 428st_gyro_probe_trigger_error:
 429        st_gyro_deallocate_ring(indio_dev);
 430st_gyro_power_off:
 431        st_sensors_power_disable(indio_dev);
 432
 433        return err;
 434}
 435EXPORT_SYMBOL(st_gyro_common_probe);
 436
 437void st_gyro_common_remove(struct iio_dev *indio_dev)
 438{
 439        struct st_sensor_data *gdata = iio_priv(indio_dev);
 440
 441        st_sensors_power_disable(indio_dev);
 442
 443        iio_device_unregister(indio_dev);
 444        if (gdata->get_irq_data_ready(indio_dev) > 0)
 445                st_sensors_deallocate_trigger(indio_dev);
 446
 447        st_gyro_deallocate_ring(indio_dev);
 448}
 449EXPORT_SYMBOL(st_gyro_common_remove);
 450
 451MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
 452MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
 453MODULE_LICENSE("GPL v2");
 454