1/* 2 * STMicroelectronics accelerometers 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/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_accel.h" 28 29#define ST_ACCEL_NUMBER_DATA_CHANNELS 3 30 31/* DEFAULT VALUE FOR SENSORS */ 32#define ST_ACCEL_DEFAULT_OUT_X_L_ADDR 0x28 33#define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR 0x2a 34#define ST_ACCEL_DEFAULT_OUT_Z_L_ADDR 0x2c 35 36/* FULLSCALE */ 37#define ST_ACCEL_FS_AVL_2G 2 38#define ST_ACCEL_FS_AVL_4G 4 39#define ST_ACCEL_FS_AVL_6G 6 40#define ST_ACCEL_FS_AVL_8G 8 41#define ST_ACCEL_FS_AVL_16G 16 42 43/* CUSTOM VALUES FOR SENSOR 1 */ 44#define ST_ACCEL_1_WAI_EXP 0x33 45#define ST_ACCEL_1_ODR_ADDR 0x20 46#define ST_ACCEL_1_ODR_MASK 0xf0 47#define ST_ACCEL_1_ODR_AVL_1HZ_VAL 0x01 48#define ST_ACCEL_1_ODR_AVL_10HZ_VAL 0x02 49#define ST_ACCEL_1_ODR_AVL_25HZ_VAL 0x03 50#define ST_ACCEL_1_ODR_AVL_50HZ_VAL 0x04 51#define ST_ACCEL_1_ODR_AVL_100HZ_VAL 0x05 52#define ST_ACCEL_1_ODR_AVL_200HZ_VAL 0x06 53#define ST_ACCEL_1_ODR_AVL_400HZ_VAL 0x07 54#define ST_ACCEL_1_ODR_AVL_1600HZ_VAL 0x08 55#define ST_ACCEL_1_FS_ADDR 0x23 56#define ST_ACCEL_1_FS_MASK 0x30 57#define ST_ACCEL_1_FS_AVL_2_VAL 0x00 58#define ST_ACCEL_1_FS_AVL_4_VAL 0x01 59#define ST_ACCEL_1_FS_AVL_8_VAL 0x02 60#define ST_ACCEL_1_FS_AVL_16_VAL 0x03 61#define ST_ACCEL_1_FS_AVL_2_GAIN IIO_G_TO_M_S_2(1000) 62#define ST_ACCEL_1_FS_AVL_4_GAIN IIO_G_TO_M_S_2(2000) 63#define ST_ACCEL_1_FS_AVL_8_GAIN IIO_G_TO_M_S_2(4000) 64#define ST_ACCEL_1_FS_AVL_16_GAIN IIO_G_TO_M_S_2(12000) 65#define ST_ACCEL_1_BDU_ADDR 0x23 66#define ST_ACCEL_1_BDU_MASK 0x80 67#define ST_ACCEL_1_DRDY_IRQ_ADDR 0x22 68#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK 0x10 69#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK 0x08 70#define ST_ACCEL_1_MULTIREAD_BIT true 71 72/* CUSTOM VALUES FOR SENSOR 2 */ 73#define ST_ACCEL_2_WAI_EXP 0x32 74#define ST_ACCEL_2_ODR_ADDR 0x20 75#define ST_ACCEL_2_ODR_MASK 0x18 76#define ST_ACCEL_2_ODR_AVL_50HZ_VAL 0x00 77#define ST_ACCEL_2_ODR_AVL_100HZ_VAL 0x01 78#define ST_ACCEL_2_ODR_AVL_400HZ_VAL 0x02 79#define ST_ACCEL_2_ODR_AVL_1000HZ_VAL 0x03 80#define ST_ACCEL_2_PW_ADDR 0x20 81#define ST_ACCEL_2_PW_MASK 0xe0 82#define ST_ACCEL_2_FS_ADDR 0x23 83#define ST_ACCEL_2_FS_MASK 0x30 84#define ST_ACCEL_2_FS_AVL_2_VAL 0X00 85#define ST_ACCEL_2_FS_AVL_4_VAL 0X01 86#define ST_ACCEL_2_FS_AVL_8_VAL 0x03 87#define ST_ACCEL_2_FS_AVL_2_GAIN IIO_G_TO_M_S_2(1000) 88#define ST_ACCEL_2_FS_AVL_4_GAIN IIO_G_TO_M_S_2(2000) 89#define ST_ACCEL_2_FS_AVL_8_GAIN IIO_G_TO_M_S_2(3900) 90#define ST_ACCEL_2_BDU_ADDR 0x23 91#define ST_ACCEL_2_BDU_MASK 0x80 92#define ST_ACCEL_2_DRDY_IRQ_ADDR 0x22 93#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK 0x02 94#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK 0x10 95#define ST_ACCEL_2_MULTIREAD_BIT true 96 97/* CUSTOM VALUES FOR SENSOR 3 */ 98#define ST_ACCEL_3_WAI_EXP 0x40 99#define ST_ACCEL_3_ODR_ADDR 0x20 100#define ST_ACCEL_3_ODR_MASK 0xf0 101#define ST_ACCEL_3_ODR_AVL_3HZ_VAL 0x01 102#define ST_ACCEL_3_ODR_AVL_6HZ_VAL 0x02 103#define ST_ACCEL_3_ODR_AVL_12HZ_VAL 0x03 104#define ST_ACCEL_3_ODR_AVL_25HZ_VAL 0x04 105#define ST_ACCEL_3_ODR_AVL_50HZ_VAL 0x05 106#define ST_ACCEL_3_ODR_AVL_100HZ_VAL 0x06 107#define ST_ACCEL_3_ODR_AVL_200HZ_VAL 0x07 108#define ST_ACCEL_3_ODR_AVL_400HZ_VAL 0x08 109#define ST_ACCEL_3_ODR_AVL_800HZ_VAL 0x09 110#define ST_ACCEL_3_ODR_AVL_1600HZ_VAL 0x0a 111#define ST_ACCEL_3_FS_ADDR 0x24 112#define ST_ACCEL_3_FS_MASK 0x38 113#define ST_ACCEL_3_FS_AVL_2_VAL 0X00 114#define ST_ACCEL_3_FS_AVL_4_VAL 0X01 115#define ST_ACCEL_3_FS_AVL_6_VAL 0x02 116#define ST_ACCEL_3_FS_AVL_8_VAL 0x03 117#define ST_ACCEL_3_FS_AVL_16_VAL 0x04 118#define ST_ACCEL_3_FS_AVL_2_GAIN IIO_G_TO_M_S_2(61) 119#define ST_ACCEL_3_FS_AVL_4_GAIN IIO_G_TO_M_S_2(122) 120#define ST_ACCEL_3_FS_AVL_6_GAIN IIO_G_TO_M_S_2(183) 121#define ST_ACCEL_3_FS_AVL_8_GAIN IIO_G_TO_M_S_2(244) 122#define ST_ACCEL_3_FS_AVL_16_GAIN IIO_G_TO_M_S_2(732) 123#define ST_ACCEL_3_BDU_ADDR 0x20 124#define ST_ACCEL_3_BDU_MASK 0x08 125#define ST_ACCEL_3_DRDY_IRQ_ADDR 0x23 126#define ST_ACCEL_3_DRDY_IRQ_INT1_MASK 0x80 127#define ST_ACCEL_3_DRDY_IRQ_INT2_MASK 0x00 128#define ST_ACCEL_3_IG1_EN_ADDR 0x23 129#define ST_ACCEL_3_IG1_EN_MASK 0x08 130#define ST_ACCEL_3_MULTIREAD_BIT false 131 132/* CUSTOM VALUES FOR SENSOR 4 */ 133#define ST_ACCEL_4_WAI_EXP 0x3a 134#define ST_ACCEL_4_ODR_ADDR 0x20 135#define ST_ACCEL_4_ODR_MASK 0x30 /* DF1 and DF0 */ 136#define ST_ACCEL_4_ODR_AVL_40HZ_VAL 0x00 137#define ST_ACCEL_4_ODR_AVL_160HZ_VAL 0x01 138#define ST_ACCEL_4_ODR_AVL_640HZ_VAL 0x02 139#define ST_ACCEL_4_ODR_AVL_2560HZ_VAL 0x03 140#define ST_ACCEL_4_PW_ADDR 0x20 141#define ST_ACCEL_4_PW_MASK 0xc0 142#define ST_ACCEL_4_FS_ADDR 0x21 143#define ST_ACCEL_4_FS_MASK 0x80 144#define ST_ACCEL_4_FS_AVL_2_VAL 0X00 145#define ST_ACCEL_4_FS_AVL_6_VAL 0X01 146#define ST_ACCEL_4_FS_AVL_2_GAIN IIO_G_TO_M_S_2(1024) 147#define ST_ACCEL_4_FS_AVL_6_GAIN IIO_G_TO_M_S_2(340) 148#define ST_ACCEL_4_BDU_ADDR 0x21 149#define ST_ACCEL_4_BDU_MASK 0x40 150#define ST_ACCEL_4_DRDY_IRQ_ADDR 0x21 151#define ST_ACCEL_4_DRDY_IRQ_INT1_MASK 0x04 152#define ST_ACCEL_4_MULTIREAD_BIT true 153 154static const struct iio_chan_spec st_accel_12bit_channels[] = { 155 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, 156 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 157 ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16, 158 ST_ACCEL_DEFAULT_OUT_X_L_ADDR), 159 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, 160 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 161 ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16, 162 ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), 163 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, 164 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 165 ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16, 166 ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), 167 IIO_CHAN_SOFT_TIMESTAMP(3) 168}; 169 170static const struct iio_chan_spec st_accel_16bit_channels[] = { 171 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, 172 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 173 ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, 174 ST_ACCEL_DEFAULT_OUT_X_L_ADDR), 175 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, 176 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 177 ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, 178 ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), 179 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, 180 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 181 ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, 182 ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), 183 IIO_CHAN_SOFT_TIMESTAMP(3) 184}; 185 186static const struct st_sensor_settings st_accel_sensors_settings[] = { 187 { 188 .wai = ST_ACCEL_1_WAI_EXP, 189 .sensors_supported = { 190 [0] = LIS3DH_ACCEL_DEV_NAME, 191 [1] = LSM303DLHC_ACCEL_DEV_NAME, 192 [2] = LSM330D_ACCEL_DEV_NAME, 193 [3] = LSM330DL_ACCEL_DEV_NAME, 194 [4] = LSM330DLC_ACCEL_DEV_NAME, 195 }, 196 .ch = (struct iio_chan_spec *)st_accel_12bit_channels, 197 .odr = { 198 .addr = ST_ACCEL_1_ODR_ADDR, 199 .mask = ST_ACCEL_1_ODR_MASK, 200 .odr_avl = { 201 { 1, ST_ACCEL_1_ODR_AVL_1HZ_VAL, }, 202 { 10, ST_ACCEL_1_ODR_AVL_10HZ_VAL, }, 203 { 25, ST_ACCEL_1_ODR_AVL_25HZ_VAL, }, 204 { 50, ST_ACCEL_1_ODR_AVL_50HZ_VAL, }, 205 { 100, ST_ACCEL_1_ODR_AVL_100HZ_VAL, }, 206 { 200, ST_ACCEL_1_ODR_AVL_200HZ_VAL, }, 207 { 400, ST_ACCEL_1_ODR_AVL_400HZ_VAL, }, 208 { 1600, ST_ACCEL_1_ODR_AVL_1600HZ_VAL, }, 209 }, 210 }, 211 .pw = { 212 .addr = ST_ACCEL_1_ODR_ADDR, 213 .mask = ST_ACCEL_1_ODR_MASK, 214 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, 215 }, 216 .enable_axis = { 217 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, 218 .mask = ST_SENSORS_DEFAULT_AXIS_MASK, 219 }, 220 .fs = { 221 .addr = ST_ACCEL_1_FS_ADDR, 222 .mask = ST_ACCEL_1_FS_MASK, 223 .fs_avl = { 224 [0] = { 225 .num = ST_ACCEL_FS_AVL_2G, 226 .value = ST_ACCEL_1_FS_AVL_2_VAL, 227 .gain = ST_ACCEL_1_FS_AVL_2_GAIN, 228 }, 229 [1] = { 230 .num = ST_ACCEL_FS_AVL_4G, 231 .value = ST_ACCEL_1_FS_AVL_4_VAL, 232 .gain = ST_ACCEL_1_FS_AVL_4_GAIN, 233 }, 234 [2] = { 235 .num = ST_ACCEL_FS_AVL_8G, 236 .value = ST_ACCEL_1_FS_AVL_8_VAL, 237 .gain = ST_ACCEL_1_FS_AVL_8_GAIN, 238 }, 239 [3] = { 240 .num = ST_ACCEL_FS_AVL_16G, 241 .value = ST_ACCEL_1_FS_AVL_16_VAL, 242 .gain = ST_ACCEL_1_FS_AVL_16_GAIN, 243 }, 244 }, 245 }, 246 .bdu = { 247 .addr = ST_ACCEL_1_BDU_ADDR, 248 .mask = ST_ACCEL_1_BDU_MASK, 249 }, 250 .drdy_irq = { 251 .addr = ST_ACCEL_1_DRDY_IRQ_ADDR, 252 .mask_int1 = ST_ACCEL_1_DRDY_IRQ_INT1_MASK, 253 .mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK, 254 }, 255 .multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT, 256 .bootime = 2, 257 }, 258 { 259 .wai = ST_ACCEL_2_WAI_EXP, 260 .sensors_supported = { 261 [0] = LIS331DLH_ACCEL_DEV_NAME, 262 [1] = LSM303DL_ACCEL_DEV_NAME, 263 [2] = LSM303DLH_ACCEL_DEV_NAME, 264 [3] = LSM303DLM_ACCEL_DEV_NAME, 265 }, 266 .ch = (struct iio_chan_spec *)st_accel_12bit_channels, 267 .odr = { 268 .addr = ST_ACCEL_2_ODR_ADDR, 269 .mask = ST_ACCEL_2_ODR_MASK, 270 .odr_avl = { 271 { 50, ST_ACCEL_2_ODR_AVL_50HZ_VAL, }, 272 { 100, ST_ACCEL_2_ODR_AVL_100HZ_VAL, }, 273 { 400, ST_ACCEL_2_ODR_AVL_400HZ_VAL, }, 274 { 1000, ST_ACCEL_2_ODR_AVL_1000HZ_VAL, }, 275 }, 276 }, 277 .pw = { 278 .addr = ST_ACCEL_2_PW_ADDR, 279 .mask = ST_ACCEL_2_PW_MASK, 280 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, 281 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, 282 }, 283 .enable_axis = { 284 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, 285 .mask = ST_SENSORS_DEFAULT_AXIS_MASK, 286 }, 287 .fs = { 288 .addr = ST_ACCEL_2_FS_ADDR, 289 .mask = ST_ACCEL_2_FS_MASK, 290 .fs_avl = { 291 [0] = { 292 .num = ST_ACCEL_FS_AVL_2G, 293 .value = ST_ACCEL_2_FS_AVL_2_VAL, 294 .gain = ST_ACCEL_2_FS_AVL_2_GAIN, 295 }, 296 [1] = { 297 .num = ST_ACCEL_FS_AVL_4G, 298 .value = ST_ACCEL_2_FS_AVL_4_VAL, 299 .gain = ST_ACCEL_2_FS_AVL_4_GAIN, 300 }, 301 [2] = { 302 .num = ST_ACCEL_FS_AVL_8G, 303 .value = ST_ACCEL_2_FS_AVL_8_VAL, 304 .gain = ST_ACCEL_2_FS_AVL_8_GAIN, 305 }, 306 }, 307 }, 308 .bdu = { 309 .addr = ST_ACCEL_2_BDU_ADDR, 310 .mask = ST_ACCEL_2_BDU_MASK, 311 }, 312 .drdy_irq = { 313 .addr = ST_ACCEL_2_DRDY_IRQ_ADDR, 314 .mask_int1 = ST_ACCEL_2_DRDY_IRQ_INT1_MASK, 315 .mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK, 316 }, 317 .multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT, 318 .bootime = 2, 319 }, 320 { 321 .wai = ST_ACCEL_3_WAI_EXP, 322 .sensors_supported = { 323 [0] = LSM330_ACCEL_DEV_NAME, 324 }, 325 .ch = (struct iio_chan_spec *)st_accel_16bit_channels, 326 .odr = { 327 .addr = ST_ACCEL_3_ODR_ADDR, 328 .mask = ST_ACCEL_3_ODR_MASK, 329 .odr_avl = { 330 { 3, ST_ACCEL_3_ODR_AVL_3HZ_VAL }, 331 { 6, ST_ACCEL_3_ODR_AVL_6HZ_VAL, }, 332 { 12, ST_ACCEL_3_ODR_AVL_12HZ_VAL, }, 333 { 25, ST_ACCEL_3_ODR_AVL_25HZ_VAL, }, 334 { 50, ST_ACCEL_3_ODR_AVL_50HZ_VAL, }, 335 { 100, ST_ACCEL_3_ODR_AVL_100HZ_VAL, }, 336 { 200, ST_ACCEL_3_ODR_AVL_200HZ_VAL, }, 337 { 400, ST_ACCEL_3_ODR_AVL_400HZ_VAL, }, 338 { 800, ST_ACCEL_3_ODR_AVL_800HZ_VAL, }, 339 { 1600, ST_ACCEL_3_ODR_AVL_1600HZ_VAL, }, 340 }, 341 }, 342 .pw = { 343 .addr = ST_ACCEL_3_ODR_ADDR, 344 .mask = ST_ACCEL_3_ODR_MASK, 345 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, 346 }, 347 .enable_axis = { 348 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, 349 .mask = ST_SENSORS_DEFAULT_AXIS_MASK, 350 }, 351 .fs = { 352 .addr = ST_ACCEL_3_FS_ADDR, 353 .mask = ST_ACCEL_3_FS_MASK, 354 .fs_avl = { 355 [0] = { 356 .num = ST_ACCEL_FS_AVL_2G, 357 .value = ST_ACCEL_3_FS_AVL_2_VAL, 358 .gain = ST_ACCEL_3_FS_AVL_2_GAIN, 359 }, 360 [1] = { 361 .num = ST_ACCEL_FS_AVL_4G, 362 .value = ST_ACCEL_3_FS_AVL_4_VAL, 363 .gain = ST_ACCEL_3_FS_AVL_4_GAIN, 364 }, 365 [2] = { 366 .num = ST_ACCEL_FS_AVL_6G, 367 .value = ST_ACCEL_3_FS_AVL_6_VAL, 368 .gain = ST_ACCEL_3_FS_AVL_6_GAIN, 369 }, 370 [3] = { 371 .num = ST_ACCEL_FS_AVL_8G, 372 .value = ST_ACCEL_3_FS_AVL_8_VAL, 373 .gain = ST_ACCEL_3_FS_AVL_8_GAIN, 374 }, 375 [4] = { 376 .num = ST_ACCEL_FS_AVL_16G, 377 .value = ST_ACCEL_3_FS_AVL_16_VAL, 378 .gain = ST_ACCEL_3_FS_AVL_16_GAIN, 379 }, 380 }, 381 }, 382 .bdu = { 383 .addr = ST_ACCEL_3_BDU_ADDR, 384 .mask = ST_ACCEL_3_BDU_MASK, 385 }, 386 .drdy_irq = { 387 .addr = ST_ACCEL_3_DRDY_IRQ_ADDR, 388 .mask_int1 = ST_ACCEL_3_DRDY_IRQ_INT1_MASK, 389 .mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK, 390 .ig1 = { 391 .en_addr = ST_ACCEL_3_IG1_EN_ADDR, 392 .en_mask = ST_ACCEL_3_IG1_EN_MASK, 393 }, 394 }, 395 .multi_read_bit = ST_ACCEL_3_MULTIREAD_BIT, 396 .bootime = 2, 397 }, 398 { 399 .wai = ST_ACCEL_4_WAI_EXP, 400 .sensors_supported = { 401 [0] = LIS3LV02DL_ACCEL_DEV_NAME, 402 }, 403 .ch = (struct iio_chan_spec *)st_accel_12bit_channels, 404 .odr = { 405 .addr = ST_ACCEL_4_ODR_ADDR, 406 .mask = ST_ACCEL_4_ODR_MASK, 407 .odr_avl = { 408 { 40, ST_ACCEL_4_ODR_AVL_40HZ_VAL }, 409 { 160, ST_ACCEL_4_ODR_AVL_160HZ_VAL, }, 410 { 640, ST_ACCEL_4_ODR_AVL_640HZ_VAL, }, 411 { 2560, ST_ACCEL_4_ODR_AVL_2560HZ_VAL, }, 412 }, 413 }, 414 .pw = { 415 .addr = ST_ACCEL_4_PW_ADDR, 416 .mask = ST_ACCEL_4_PW_MASK, 417 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, 418 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, 419 }, 420 .enable_axis = { 421 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, 422 .mask = ST_SENSORS_DEFAULT_AXIS_MASK, 423 }, 424 .fs = { 425 .addr = ST_ACCEL_4_FS_ADDR, 426 .mask = ST_ACCEL_4_FS_MASK, 427 .fs_avl = { 428 [0] = { 429 .num = ST_ACCEL_FS_AVL_2G, 430 .value = ST_ACCEL_4_FS_AVL_2_VAL, 431 .gain = ST_ACCEL_4_FS_AVL_2_GAIN, 432 }, 433 [1] = { 434 .num = ST_ACCEL_FS_AVL_6G, 435 .value = ST_ACCEL_4_FS_AVL_6_VAL, 436 .gain = ST_ACCEL_4_FS_AVL_6_GAIN, 437 }, 438 }, 439 }, 440 .bdu = { 441 .addr = ST_ACCEL_4_BDU_ADDR, 442 .mask = ST_ACCEL_4_BDU_MASK, 443 }, 444 .drdy_irq = { 445 .addr = ST_ACCEL_4_DRDY_IRQ_ADDR, 446 .mask_int1 = ST_ACCEL_4_DRDY_IRQ_INT1_MASK, 447 }, 448 .multi_read_bit = ST_ACCEL_4_MULTIREAD_BIT, 449 .bootime = 2, /* guess */ 450 }, 451}; 452 453static int st_accel_read_raw(struct iio_dev *indio_dev, 454 struct iio_chan_spec const *ch, int *val, 455 int *val2, long mask) 456{ 457 int err; 458 struct st_sensor_data *adata = iio_priv(indio_dev); 459 460 switch (mask) { 461 case IIO_CHAN_INFO_RAW: 462 err = st_sensors_read_info_raw(indio_dev, ch, val); 463 if (err < 0) 464 goto read_error; 465 466 return IIO_VAL_INT; 467 case IIO_CHAN_INFO_SCALE: 468 *val = 0; 469 *val2 = adata->current_fullscale->gain; 470 return IIO_VAL_INT_PLUS_MICRO; 471 case IIO_CHAN_INFO_SAMP_FREQ: 472 *val = adata->odr; 473 return IIO_VAL_INT; 474 default: 475 return -EINVAL; 476 } 477 478read_error: 479 return err; 480} 481 482static int st_accel_write_raw(struct iio_dev *indio_dev, 483 struct iio_chan_spec const *chan, int val, int val2, long mask) 484{ 485 int err; 486 487 switch (mask) { 488 case IIO_CHAN_INFO_SCALE: 489 err = st_sensors_set_fullscale_by_gain(indio_dev, val2); 490 break; 491 case IIO_CHAN_INFO_SAMP_FREQ: 492 if (val2) 493 return -EINVAL; 494 mutex_lock(&indio_dev->mlock); 495 err = st_sensors_set_odr(indio_dev, val); 496 mutex_unlock(&indio_dev->mlock); 497 return err; 498 default: 499 return -EINVAL; 500 } 501 502 return err; 503} 504 505static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); 506static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available); 507 508static struct attribute *st_accel_attributes[] = { 509 &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 510 &iio_dev_attr_in_accel_scale_available.dev_attr.attr, 511 NULL, 512}; 513 514static const struct attribute_group st_accel_attribute_group = { 515 .attrs = st_accel_attributes, 516}; 517 518static const struct iio_info accel_info = { 519 .driver_module = THIS_MODULE, 520 .attrs = &st_accel_attribute_group, 521 .read_raw = &st_accel_read_raw, 522 .write_raw = &st_accel_write_raw, 523}; 524 525#ifdef CONFIG_IIO_TRIGGER 526static const struct iio_trigger_ops st_accel_trigger_ops = { 527 .owner = THIS_MODULE, 528 .set_trigger_state = ST_ACCEL_TRIGGER_SET_STATE, 529}; 530#define ST_ACCEL_TRIGGER_OPS (&st_accel_trigger_ops) 531#else 532#define ST_ACCEL_TRIGGER_OPS NULL 533#endif 534 535int st_accel_common_probe(struct iio_dev *indio_dev) 536{ 537 struct st_sensor_data *adata = iio_priv(indio_dev); 538 int irq = adata->get_irq_data_ready(indio_dev); 539 int err; 540 541 indio_dev->modes = INDIO_DIRECT_MODE; 542 indio_dev->info = &accel_info; 543 mutex_init(&adata->tb.buf_lock); 544 545 st_sensors_power_enable(indio_dev); 546 547 err = st_sensors_check_device_support(indio_dev, 548 ARRAY_SIZE(st_accel_sensors_settings), 549 st_accel_sensors_settings); 550 if (err < 0) 551 return err; 552 553 adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS; 554 adata->multiread_bit = adata->sensor_settings->multi_read_bit; 555 indio_dev->channels = adata->sensor_settings->ch; 556 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; 557 558 adata->current_fullscale = (struct st_sensor_fullscale_avl *) 559 &adata->sensor_settings->fs.fs_avl[0]; 560 adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; 561 562 if (!adata->dev->platform_data) 563 adata->dev->platform_data = 564 (struct st_sensors_platform_data *)&default_accel_pdata; 565 566 err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data); 567 if (err < 0) 568 return err; 569 570 err = st_accel_allocate_ring(indio_dev); 571 if (err < 0) 572 return err; 573 574 if (irq > 0) { 575 err = st_sensors_allocate_trigger(indio_dev, 576 ST_ACCEL_TRIGGER_OPS); 577 if (err < 0) 578 goto st_accel_probe_trigger_error; 579 } 580 581 err = iio_device_register(indio_dev); 582 if (err) 583 goto st_accel_device_register_error; 584 585 dev_info(&indio_dev->dev, "registered accelerometer %s\n", 586 indio_dev->name); 587 588 return 0; 589 590st_accel_device_register_error: 591 if (irq > 0) 592 st_sensors_deallocate_trigger(indio_dev); 593st_accel_probe_trigger_error: 594 st_accel_deallocate_ring(indio_dev); 595 596 return err; 597} 598EXPORT_SYMBOL(st_accel_common_probe); 599 600void st_accel_common_remove(struct iio_dev *indio_dev) 601{ 602 struct st_sensor_data *adata = iio_priv(indio_dev); 603 604 st_sensors_power_disable(indio_dev); 605 606 iio_device_unregister(indio_dev); 607 if (adata->get_irq_data_ready(indio_dev) > 0) 608 st_sensors_deallocate_trigger(indio_dev); 609 610 st_accel_deallocate_ring(indio_dev); 611} 612EXPORT_SYMBOL(st_accel_common_remove); 613 614MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 615MODULE_DESCRIPTION("STMicroelectronics accelerometers driver"); 616MODULE_LICENSE("GPL v2"); 617