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