0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/mutex.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/sysfs.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/iio/sysfs.h>
0017 #include <linux/iio/trigger.h>
0018
0019 #include <linux/iio/common/st_sensors.h>
0020 #include "st_gyro.h"
0021
0022 #define ST_GYRO_NUMBER_DATA_CHANNELS 3
0023
0024
0025 #define ST_GYRO_DEFAULT_OUT_X_L_ADDR 0x28
0026 #define ST_GYRO_DEFAULT_OUT_Y_L_ADDR 0x2a
0027 #define ST_GYRO_DEFAULT_OUT_Z_L_ADDR 0x2c
0028
0029
0030 #define ST_GYRO_FS_AVL_245DPS 245
0031 #define ST_GYRO_FS_AVL_250DPS 250
0032 #define ST_GYRO_FS_AVL_500DPS 500
0033 #define ST_GYRO_FS_AVL_2000DPS 2000
0034
0035 static const struct iio_mount_matrix *
0036 st_gyro_get_mount_matrix(const struct iio_dev *indio_dev,
0037 const struct iio_chan_spec *chan)
0038 {
0039 struct st_sensor_data *gdata = iio_priv(indio_dev);
0040
0041 return &gdata->mount_matrix;
0042 }
0043
0044 static const struct iio_chan_spec_ext_info st_gyro_mount_matrix_ext_info[] = {
0045 IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_gyro_get_mount_matrix),
0046 { }
0047 };
0048
0049 static const struct iio_chan_spec st_gyro_16bit_channels[] = {
0050 ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
0051 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
0052 ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
0053 ST_GYRO_DEFAULT_OUT_X_L_ADDR,
0054 st_gyro_mount_matrix_ext_info),
0055 ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
0056 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
0057 ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
0058 ST_GYRO_DEFAULT_OUT_Y_L_ADDR,
0059 st_gyro_mount_matrix_ext_info),
0060 ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
0061 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
0062 ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
0063 ST_GYRO_DEFAULT_OUT_Z_L_ADDR,
0064 st_gyro_mount_matrix_ext_info),
0065 IIO_CHAN_SOFT_TIMESTAMP(3)
0066 };
0067
0068 static const struct st_sensor_settings st_gyro_sensors_settings[] = {
0069 {
0070 .wai = 0xd3,
0071 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0072 .sensors_supported = {
0073 [0] = L3G4200D_GYRO_DEV_NAME,
0074 [1] = LSM330DL_GYRO_DEV_NAME,
0075 },
0076 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
0077 .odr = {
0078 .addr = 0x20,
0079 .mask = 0xc0,
0080 .odr_avl = {
0081 { .hz = 100, .value = 0x00, },
0082 { .hz = 200, .value = 0x01, },
0083 { .hz = 400, .value = 0x02, },
0084 { .hz = 800, .value = 0x03, },
0085 },
0086 },
0087 .pw = {
0088 .addr = 0x20,
0089 .mask = 0x08,
0090 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
0091 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0092 },
0093 .enable_axis = {
0094 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
0095 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
0096 },
0097 .fs = {
0098 .addr = 0x23,
0099 .mask = 0x30,
0100 .fs_avl = {
0101 [0] = {
0102 .num = ST_GYRO_FS_AVL_250DPS,
0103 .value = 0x00,
0104 .gain = IIO_DEGREE_TO_RAD(8750),
0105 },
0106 [1] = {
0107 .num = ST_GYRO_FS_AVL_500DPS,
0108 .value = 0x01,
0109 .gain = IIO_DEGREE_TO_RAD(17500),
0110 },
0111 [2] = {
0112 .num = ST_GYRO_FS_AVL_2000DPS,
0113 .value = 0x02,
0114 .gain = IIO_DEGREE_TO_RAD(70000),
0115 },
0116 },
0117 },
0118 .bdu = {
0119 .addr = 0x23,
0120 .mask = 0x80,
0121 },
0122 .drdy_irq = {
0123 .int2 = {
0124 .addr = 0x22,
0125 .mask = 0x08,
0126 },
0127
0128
0129
0130
0131
0132 .stat_drdy = {
0133 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0134 .mask = 0x07,
0135 },
0136 },
0137 .sim = {
0138 .addr = 0x23,
0139 .value = BIT(0),
0140 },
0141 .multi_read_bit = true,
0142 .bootime = 2,
0143 },
0144 {
0145 .wai = 0xd4,
0146 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0147 .sensors_supported = {
0148 [0] = L3GD20_GYRO_DEV_NAME,
0149 [1] = LSM330D_GYRO_DEV_NAME,
0150 [2] = LSM330DLC_GYRO_DEV_NAME,
0151 [3] = L3G4IS_GYRO_DEV_NAME,
0152 [4] = LSM330_GYRO_DEV_NAME,
0153 },
0154 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
0155 .odr = {
0156 .addr = 0x20,
0157 .mask = 0xc0,
0158 .odr_avl = {
0159 { .hz = 95, .value = 0x00, },
0160 { .hz = 190, .value = 0x01, },
0161 { .hz = 380, .value = 0x02, },
0162 { .hz = 760, .value = 0x03, },
0163 },
0164 },
0165 .pw = {
0166 .addr = 0x20,
0167 .mask = 0x08,
0168 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
0169 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0170 },
0171 .enable_axis = {
0172 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
0173 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
0174 },
0175 .fs = {
0176 .addr = 0x23,
0177 .mask = 0x30,
0178 .fs_avl = {
0179 [0] = {
0180 .num = ST_GYRO_FS_AVL_250DPS,
0181 .value = 0x00,
0182 .gain = IIO_DEGREE_TO_RAD(8750),
0183 },
0184 [1] = {
0185 .num = ST_GYRO_FS_AVL_500DPS,
0186 .value = 0x01,
0187 .gain = IIO_DEGREE_TO_RAD(17500),
0188 },
0189 [2] = {
0190 .num = ST_GYRO_FS_AVL_2000DPS,
0191 .value = 0x02,
0192 .gain = IIO_DEGREE_TO_RAD(70000),
0193 },
0194 },
0195 },
0196 .bdu = {
0197 .addr = 0x23,
0198 .mask = 0x80,
0199 },
0200 .drdy_irq = {
0201 .int2 = {
0202 .addr = 0x22,
0203 .mask = 0x08,
0204 },
0205
0206
0207
0208
0209
0210 .stat_drdy = {
0211 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0212 .mask = 0x07,
0213 },
0214 },
0215 .sim = {
0216 .addr = 0x23,
0217 .value = BIT(0),
0218 },
0219 .multi_read_bit = true,
0220 .bootime = 2,
0221 },
0222 {
0223 .wai = 0xd4,
0224 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0225 .sensors_supported = {
0226 [0] = LSM9DS0_GYRO_DEV_NAME,
0227 },
0228 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
0229 .odr = {
0230 .addr = 0x20,
0231 .mask = GENMASK(7, 6),
0232 .odr_avl = {
0233 { .hz = 95, .value = 0x00, },
0234 { .hz = 190, .value = 0x01, },
0235 { .hz = 380, .value = 0x02, },
0236 { .hz = 760, .value = 0x03, },
0237 },
0238 },
0239 .pw = {
0240 .addr = 0x20,
0241 .mask = BIT(3),
0242 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
0243 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0244 },
0245 .enable_axis = {
0246 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
0247 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
0248 },
0249 .fs = {
0250 .addr = 0x23,
0251 .mask = GENMASK(5, 4),
0252 .fs_avl = {
0253 [0] = {
0254 .num = ST_GYRO_FS_AVL_245DPS,
0255 .value = 0x00,
0256 .gain = IIO_DEGREE_TO_RAD(8750),
0257 },
0258 [1] = {
0259 .num = ST_GYRO_FS_AVL_500DPS,
0260 .value = 0x01,
0261 .gain = IIO_DEGREE_TO_RAD(17500),
0262 },
0263 [2] = {
0264 .num = ST_GYRO_FS_AVL_2000DPS,
0265 .value = 0x02,
0266 .gain = IIO_DEGREE_TO_RAD(70000),
0267 },
0268 },
0269 },
0270 .bdu = {
0271 .addr = 0x23,
0272 .mask = BIT(7),
0273 },
0274 .drdy_irq = {
0275 .int2 = {
0276 .addr = 0x22,
0277 .mask = BIT(3),
0278 },
0279
0280
0281
0282
0283
0284 .stat_drdy = {
0285 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0286 .mask = GENMASK(2, 0),
0287 },
0288 },
0289 .sim = {
0290 .addr = 0x23,
0291 .value = BIT(0),
0292 },
0293 .multi_read_bit = true,
0294 .bootime = 2,
0295 },
0296 {
0297 .wai = 0xd7,
0298 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0299 .sensors_supported = {
0300 [0] = L3GD20H_GYRO_DEV_NAME,
0301 },
0302 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
0303 .odr = {
0304 .addr = 0x20,
0305 .mask = 0xc0,
0306 .odr_avl = {
0307 { .hz = 100, .value = 0x00, },
0308 { .hz = 200, .value = 0x01, },
0309 { .hz = 400, .value = 0x02, },
0310 { .hz = 800, .value = 0x03, },
0311 },
0312 },
0313 .pw = {
0314 .addr = 0x20,
0315 .mask = 0x08,
0316 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
0317 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0318 },
0319 .enable_axis = {
0320 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
0321 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
0322 },
0323 .fs = {
0324 .addr = 0x23,
0325 .mask = 0x30,
0326 .fs_avl = {
0327 [0] = {
0328 .num = ST_GYRO_FS_AVL_245DPS,
0329 .value = 0x00,
0330 .gain = IIO_DEGREE_TO_RAD(8750),
0331 },
0332 [1] = {
0333 .num = ST_GYRO_FS_AVL_500DPS,
0334 .value = 0x01,
0335 .gain = IIO_DEGREE_TO_RAD(17500),
0336 },
0337 [2] = {
0338 .num = ST_GYRO_FS_AVL_2000DPS,
0339 .value = 0x02,
0340 .gain = IIO_DEGREE_TO_RAD(70000),
0341 },
0342 },
0343 },
0344 .bdu = {
0345 .addr = 0x23,
0346 .mask = 0x80,
0347 },
0348 .drdy_irq = {
0349 .int2 = {
0350 .addr = 0x22,
0351 .mask = 0x08,
0352 },
0353
0354
0355
0356
0357
0358 .stat_drdy = {
0359 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0360 .mask = 0x07,
0361 },
0362 },
0363 .sim = {
0364 .addr = 0x23,
0365 .value = BIT(0),
0366 },
0367 .multi_read_bit = true,
0368 .bootime = 2,
0369 },
0370 };
0371
0372
0373 static const struct st_sensors_platform_data gyro_pdata = {
0374 .drdy_int_pin = 2,
0375 };
0376
0377 static int st_gyro_read_raw(struct iio_dev *indio_dev,
0378 struct iio_chan_spec const *ch, int *val,
0379 int *val2, long mask)
0380 {
0381 int err;
0382 struct st_sensor_data *gdata = iio_priv(indio_dev);
0383
0384 switch (mask) {
0385 case IIO_CHAN_INFO_RAW:
0386 err = st_sensors_read_info_raw(indio_dev, ch, val);
0387 if (err < 0)
0388 goto read_error;
0389
0390 return IIO_VAL_INT;
0391 case IIO_CHAN_INFO_SCALE:
0392 *val = 0;
0393 *val2 = gdata->current_fullscale->gain;
0394 return IIO_VAL_INT_PLUS_MICRO;
0395 case IIO_CHAN_INFO_SAMP_FREQ:
0396 *val = gdata->odr;
0397 return IIO_VAL_INT;
0398 default:
0399 return -EINVAL;
0400 }
0401
0402 read_error:
0403 return err;
0404 }
0405
0406 static int st_gyro_write_raw(struct iio_dev *indio_dev,
0407 struct iio_chan_spec const *chan, int val, int val2, long mask)
0408 {
0409 switch (mask) {
0410 case IIO_CHAN_INFO_SCALE:
0411 return st_sensors_set_fullscale_by_gain(indio_dev, val2);
0412 case IIO_CHAN_INFO_SAMP_FREQ:
0413 if (val2)
0414 return -EINVAL;
0415
0416 return st_sensors_set_odr(indio_dev, val);
0417 default:
0418 return -EINVAL;
0419 }
0420 }
0421
0422 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
0423 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
0424
0425 static struct attribute *st_gyro_attributes[] = {
0426 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
0427 &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
0428 NULL,
0429 };
0430
0431 static const struct attribute_group st_gyro_attribute_group = {
0432 .attrs = st_gyro_attributes,
0433 };
0434
0435 static const struct iio_info gyro_info = {
0436 .attrs = &st_gyro_attribute_group,
0437 .read_raw = &st_gyro_read_raw,
0438 .write_raw = &st_gyro_write_raw,
0439 .debugfs_reg_access = &st_sensors_debugfs_reg_access,
0440 };
0441
0442 #ifdef CONFIG_IIO_TRIGGER
0443 static const struct iio_trigger_ops st_gyro_trigger_ops = {
0444 .set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
0445 .validate_device = st_sensors_validate_device,
0446 };
0447 #define ST_GYRO_TRIGGER_OPS (&st_gyro_trigger_ops)
0448 #else
0449 #define ST_GYRO_TRIGGER_OPS NULL
0450 #endif
0451
0452
0453
0454
0455
0456
0457
0458 const struct st_sensor_settings *st_gyro_get_settings(const char *name)
0459 {
0460 int index = st_sensors_get_settings_index(name,
0461 st_gyro_sensors_settings,
0462 ARRAY_SIZE(st_gyro_sensors_settings));
0463 if (index < 0)
0464 return NULL;
0465
0466 return &st_gyro_sensors_settings[index];
0467 }
0468 EXPORT_SYMBOL_NS(st_gyro_get_settings, IIO_ST_SENSORS);
0469
0470 int st_gyro_common_probe(struct iio_dev *indio_dev)
0471 {
0472 struct st_sensor_data *gdata = iio_priv(indio_dev);
0473 struct st_sensors_platform_data *pdata;
0474 struct device *parent = indio_dev->dev.parent;
0475 int err;
0476
0477 indio_dev->modes = INDIO_DIRECT_MODE;
0478 indio_dev->info = &gyro_info;
0479
0480 err = st_sensors_verify_id(indio_dev);
0481 if (err < 0)
0482 return err;
0483
0484 gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
0485 indio_dev->channels = gdata->sensor_settings->ch;
0486 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
0487
0488 err = iio_read_mount_matrix(parent, &gdata->mount_matrix);
0489 if (err)
0490 return err;
0491
0492 gdata->current_fullscale = &gdata->sensor_settings->fs.fs_avl[0];
0493 gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz;
0494
0495 pdata = (struct st_sensors_platform_data *)&gyro_pdata;
0496
0497 err = st_sensors_init_sensor(indio_dev, pdata);
0498 if (err < 0)
0499 return err;
0500
0501 err = st_gyro_allocate_ring(indio_dev);
0502 if (err < 0)
0503 return err;
0504
0505 if (gdata->irq > 0) {
0506 err = st_sensors_allocate_trigger(indio_dev,
0507 ST_GYRO_TRIGGER_OPS);
0508 if (err < 0)
0509 return err;
0510 }
0511
0512 return devm_iio_device_register(parent, indio_dev);
0513 }
0514 EXPORT_SYMBOL_NS(st_gyro_common_probe, IIO_ST_SENSORS);
0515
0516 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
0517 MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
0518 MODULE_LICENSE("GPL v2");
0519 MODULE_IMPORT_NS(IIO_ST_SENSORS);