root/drivers/iio/gyro/st_gyro_core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. st_gyro_read_raw
  2. st_gyro_write_raw
  3. st_gyro_get_settings
  4. st_gyro_common_probe
  5. st_gyro_common_remove

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

/* [<][>][^][v][top][bottom][index][help] */