1 /* 2 * STMicroelectronics magnetometers 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/delay.h> 22 #include <linux/iio/iio.h> 23 #include <linux/iio/sysfs.h> 24 #include <linux/iio/buffer.h> 25 26 #include <linux/iio/common/st_sensors.h> 27 #include "st_magn.h" 28 29 #define ST_MAGN_NUMBER_DATA_CHANNELS 3 30 31 /* DEFAULT VALUE FOR SENSORS */ 32 #define ST_MAGN_DEFAULT_OUT_X_H_ADDR 0X03 33 #define ST_MAGN_DEFAULT_OUT_Y_H_ADDR 0X07 34 #define ST_MAGN_DEFAULT_OUT_Z_H_ADDR 0X05 35 36 /* FULLSCALE */ 37 #define ST_MAGN_FS_AVL_1300MG 1300 38 #define ST_MAGN_FS_AVL_1900MG 1900 39 #define ST_MAGN_FS_AVL_2500MG 2500 40 #define ST_MAGN_FS_AVL_4000MG 4000 41 #define ST_MAGN_FS_AVL_4700MG 4700 42 #define ST_MAGN_FS_AVL_5600MG 5600 43 #define ST_MAGN_FS_AVL_8000MG 8000 44 #define ST_MAGN_FS_AVL_8100MG 8100 45 #define ST_MAGN_FS_AVL_12000MG 12000 46 #define ST_MAGN_FS_AVL_16000MG 16000 47 48 /* CUSTOM VALUES FOR SENSOR 0 */ 49 #define ST_MAGN_0_ODR_ADDR 0x00 50 #define ST_MAGN_0_ODR_MASK 0x1c 51 #define ST_MAGN_0_ODR_AVL_1HZ_VAL 0x00 52 #define ST_MAGN_0_ODR_AVL_2HZ_VAL 0x01 53 #define ST_MAGN_0_ODR_AVL_3HZ_VAL 0x02 54 #define ST_MAGN_0_ODR_AVL_8HZ_VAL 0x03 55 #define ST_MAGN_0_ODR_AVL_15HZ_VAL 0x04 56 #define ST_MAGN_0_ODR_AVL_30HZ_VAL 0x05 57 #define ST_MAGN_0_ODR_AVL_75HZ_VAL 0x06 58 #define ST_MAGN_0_ODR_AVL_220HZ_VAL 0x07 59 #define ST_MAGN_0_PW_ADDR 0x02 60 #define ST_MAGN_0_PW_MASK 0x03 61 #define ST_MAGN_0_PW_ON 0x00 62 #define ST_MAGN_0_PW_OFF 0x03 63 #define ST_MAGN_0_FS_ADDR 0x01 64 #define ST_MAGN_0_FS_MASK 0xe0 65 #define ST_MAGN_0_FS_AVL_1300_VAL 0x01 66 #define ST_MAGN_0_FS_AVL_1900_VAL 0x02 67 #define ST_MAGN_0_FS_AVL_2500_VAL 0x03 68 #define ST_MAGN_0_FS_AVL_4000_VAL 0x04 69 #define ST_MAGN_0_FS_AVL_4700_VAL 0x05 70 #define ST_MAGN_0_FS_AVL_5600_VAL 0x06 71 #define ST_MAGN_0_FS_AVL_8100_VAL 0x07 72 #define ST_MAGN_0_FS_AVL_1300_GAIN_XY 1100 73 #define ST_MAGN_0_FS_AVL_1900_GAIN_XY 855 74 #define ST_MAGN_0_FS_AVL_2500_GAIN_XY 670 75 #define ST_MAGN_0_FS_AVL_4000_GAIN_XY 450 76 #define ST_MAGN_0_FS_AVL_4700_GAIN_XY 400 77 #define ST_MAGN_0_FS_AVL_5600_GAIN_XY 330 78 #define ST_MAGN_0_FS_AVL_8100_GAIN_XY 230 79 #define ST_MAGN_0_FS_AVL_1300_GAIN_Z 980 80 #define ST_MAGN_0_FS_AVL_1900_GAIN_Z 760 81 #define ST_MAGN_0_FS_AVL_2500_GAIN_Z 600 82 #define ST_MAGN_0_FS_AVL_4000_GAIN_Z 400 83 #define ST_MAGN_0_FS_AVL_4700_GAIN_Z 355 84 #define ST_MAGN_0_FS_AVL_5600_GAIN_Z 295 85 #define ST_MAGN_0_FS_AVL_8100_GAIN_Z 205 86 #define ST_MAGN_0_MULTIREAD_BIT false 87 88 /* CUSTOM VALUES FOR SENSOR 1 */ 89 #define ST_MAGN_1_WAI_EXP 0x3c 90 #define ST_MAGN_1_ODR_ADDR 0x00 91 #define ST_MAGN_1_ODR_MASK 0x1c 92 #define ST_MAGN_1_ODR_AVL_1HZ_VAL 0x00 93 #define ST_MAGN_1_ODR_AVL_2HZ_VAL 0x01 94 #define ST_MAGN_1_ODR_AVL_3HZ_VAL 0x02 95 #define ST_MAGN_1_ODR_AVL_8HZ_VAL 0x03 96 #define ST_MAGN_1_ODR_AVL_15HZ_VAL 0x04 97 #define ST_MAGN_1_ODR_AVL_30HZ_VAL 0x05 98 #define ST_MAGN_1_ODR_AVL_75HZ_VAL 0x06 99 #define ST_MAGN_1_ODR_AVL_220HZ_VAL 0x07 100 #define ST_MAGN_1_PW_ADDR 0x02 101 #define ST_MAGN_1_PW_MASK 0x03 102 #define ST_MAGN_1_PW_ON 0x00 103 #define ST_MAGN_1_PW_OFF 0x03 104 #define ST_MAGN_1_FS_ADDR 0x01 105 #define ST_MAGN_1_FS_MASK 0xe0 106 #define ST_MAGN_1_FS_AVL_1300_VAL 0x01 107 #define ST_MAGN_1_FS_AVL_1900_VAL 0x02 108 #define ST_MAGN_1_FS_AVL_2500_VAL 0x03 109 #define ST_MAGN_1_FS_AVL_4000_VAL 0x04 110 #define ST_MAGN_1_FS_AVL_4700_VAL 0x05 111 #define ST_MAGN_1_FS_AVL_5600_VAL 0x06 112 #define ST_MAGN_1_FS_AVL_8100_VAL 0x07 113 #define ST_MAGN_1_FS_AVL_1300_GAIN_XY 909 114 #define ST_MAGN_1_FS_AVL_1900_GAIN_XY 1169 115 #define ST_MAGN_1_FS_AVL_2500_GAIN_XY 1492 116 #define ST_MAGN_1_FS_AVL_4000_GAIN_XY 2222 117 #define ST_MAGN_1_FS_AVL_4700_GAIN_XY 2500 118 #define ST_MAGN_1_FS_AVL_5600_GAIN_XY 3030 119 #define ST_MAGN_1_FS_AVL_8100_GAIN_XY 4347 120 #define ST_MAGN_1_FS_AVL_1300_GAIN_Z 1020 121 #define ST_MAGN_1_FS_AVL_1900_GAIN_Z 1315 122 #define ST_MAGN_1_FS_AVL_2500_GAIN_Z 1666 123 #define ST_MAGN_1_FS_AVL_4000_GAIN_Z 2500 124 #define ST_MAGN_1_FS_AVL_4700_GAIN_Z 2816 125 #define ST_MAGN_1_FS_AVL_5600_GAIN_Z 3389 126 #define ST_MAGN_1_FS_AVL_8100_GAIN_Z 4878 127 #define ST_MAGN_1_MULTIREAD_BIT false 128 129 /* CUSTOM VALUES FOR SENSOR 2 */ 130 #define ST_MAGN_2_WAI_EXP 0x3d 131 #define ST_MAGN_2_ODR_ADDR 0x20 132 #define ST_MAGN_2_ODR_MASK 0x1c 133 #define ST_MAGN_2_ODR_AVL_1HZ_VAL 0x00 134 #define ST_MAGN_2_ODR_AVL_2HZ_VAL 0x01 135 #define ST_MAGN_2_ODR_AVL_3HZ_VAL 0x02 136 #define ST_MAGN_2_ODR_AVL_5HZ_VAL 0x03 137 #define ST_MAGN_2_ODR_AVL_10HZ_VAL 0x04 138 #define ST_MAGN_2_ODR_AVL_20HZ_VAL 0x05 139 #define ST_MAGN_2_ODR_AVL_40HZ_VAL 0x06 140 #define ST_MAGN_2_ODR_AVL_80HZ_VAL 0x07 141 #define ST_MAGN_2_PW_ADDR 0x22 142 #define ST_MAGN_2_PW_MASK 0x03 143 #define ST_MAGN_2_PW_ON 0x00 144 #define ST_MAGN_2_PW_OFF 0x03 145 #define ST_MAGN_2_FS_ADDR 0x21 146 #define ST_MAGN_2_FS_MASK 0x60 147 #define ST_MAGN_2_FS_AVL_4000_VAL 0x00 148 #define ST_MAGN_2_FS_AVL_8000_VAL 0x01 149 #define ST_MAGN_2_FS_AVL_12000_VAL 0x02 150 #define ST_MAGN_2_FS_AVL_16000_VAL 0x03 151 #define ST_MAGN_2_FS_AVL_4000_GAIN 146 152 #define ST_MAGN_2_FS_AVL_8000_GAIN 292 153 #define ST_MAGN_2_FS_AVL_12000_GAIN 438 154 #define ST_MAGN_2_FS_AVL_16000_GAIN 584 155 #define ST_MAGN_2_MULTIREAD_BIT false 156 #define ST_MAGN_2_OUT_X_L_ADDR 0x28 157 #define ST_MAGN_2_OUT_Y_L_ADDR 0x2a 158 #define ST_MAGN_2_OUT_Z_L_ADDR 0x2c 159 160 static const struct iio_chan_spec st_magn_16bit_channels[] = { 161 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, 162 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 163 ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_BE, 16, 16, 164 ST_MAGN_DEFAULT_OUT_X_H_ADDR), 165 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, 166 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 167 ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_BE, 16, 16, 168 ST_MAGN_DEFAULT_OUT_Y_H_ADDR), 169 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, 170 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 171 ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_BE, 16, 16, 172 ST_MAGN_DEFAULT_OUT_Z_H_ADDR), 173 IIO_CHAN_SOFT_TIMESTAMP(3) 174 }; 175 176 static const struct iio_chan_spec st_magn_2_16bit_channels[] = { 177 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, 178 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 179 ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, 180 ST_MAGN_2_OUT_X_L_ADDR), 181 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, 182 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 183 ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, 184 ST_MAGN_2_OUT_Y_L_ADDR), 185 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, 186 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 187 ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, 188 ST_MAGN_2_OUT_Z_L_ADDR), 189 IIO_CHAN_SOFT_TIMESTAMP(3) 190 }; 191 192 static const struct st_sensor_settings st_magn_sensors_settings[] = { 193 { 194 .wai = 0, /* This sensor has no valid WhoAmI report 0 */ 195 .sensors_supported = { 196 [0] = LSM303DLH_MAGN_DEV_NAME, 197 }, 198 .ch = (struct iio_chan_spec *)st_magn_16bit_channels, 199 .odr = { 200 .addr = ST_MAGN_0_ODR_ADDR, 201 .mask = ST_MAGN_0_ODR_MASK, 202 .odr_avl = { 203 { 1, ST_MAGN_0_ODR_AVL_1HZ_VAL, }, 204 { 2, ST_MAGN_0_ODR_AVL_2HZ_VAL, }, 205 { 3, ST_MAGN_0_ODR_AVL_3HZ_VAL, }, 206 { 8, ST_MAGN_0_ODR_AVL_8HZ_VAL, }, 207 { 15, ST_MAGN_0_ODR_AVL_15HZ_VAL, }, 208 { 30, ST_MAGN_0_ODR_AVL_30HZ_VAL, }, 209 { 75, ST_MAGN_0_ODR_AVL_75HZ_VAL, }, 210 }, 211 }, 212 .pw = { 213 .addr = ST_MAGN_0_PW_ADDR, 214 .mask = ST_MAGN_0_PW_MASK, 215 .value_on = ST_MAGN_0_PW_ON, 216 .value_off = ST_MAGN_0_PW_OFF, 217 }, 218 .fs = { 219 .addr = ST_MAGN_0_FS_ADDR, 220 .mask = ST_MAGN_0_FS_MASK, 221 .fs_avl = { 222 [0] = { 223 .num = ST_MAGN_FS_AVL_1300MG, 224 .value = ST_MAGN_0_FS_AVL_1300_VAL, 225 .gain = ST_MAGN_0_FS_AVL_1300_GAIN_XY, 226 .gain2 = ST_MAGN_0_FS_AVL_1300_GAIN_Z, 227 }, 228 [1] = { 229 .num = ST_MAGN_FS_AVL_1900MG, 230 .value = ST_MAGN_0_FS_AVL_1900_VAL, 231 .gain = ST_MAGN_0_FS_AVL_1900_GAIN_XY, 232 .gain2 = ST_MAGN_0_FS_AVL_1900_GAIN_Z, 233 }, 234 [2] = { 235 .num = ST_MAGN_FS_AVL_2500MG, 236 .value = ST_MAGN_0_FS_AVL_2500_VAL, 237 .gain = ST_MAGN_0_FS_AVL_2500_GAIN_XY, 238 .gain2 = ST_MAGN_0_FS_AVL_2500_GAIN_Z, 239 }, 240 [3] = { 241 .num = ST_MAGN_FS_AVL_4000MG, 242 .value = ST_MAGN_0_FS_AVL_4000_VAL, 243 .gain = ST_MAGN_0_FS_AVL_4000_GAIN_XY, 244 .gain2 = ST_MAGN_0_FS_AVL_4000_GAIN_Z, 245 }, 246 [4] = { 247 .num = ST_MAGN_FS_AVL_4700MG, 248 .value = ST_MAGN_0_FS_AVL_4700_VAL, 249 .gain = ST_MAGN_0_FS_AVL_4700_GAIN_XY, 250 .gain2 = ST_MAGN_0_FS_AVL_4700_GAIN_Z, 251 }, 252 [5] = { 253 .num = ST_MAGN_FS_AVL_5600MG, 254 .value = ST_MAGN_0_FS_AVL_5600_VAL, 255 .gain = ST_MAGN_0_FS_AVL_5600_GAIN_XY, 256 .gain2 = ST_MAGN_0_FS_AVL_5600_GAIN_Z, 257 }, 258 [6] = { 259 .num = ST_MAGN_FS_AVL_8100MG, 260 .value = ST_MAGN_0_FS_AVL_8100_VAL, 261 .gain = ST_MAGN_0_FS_AVL_8100_GAIN_XY, 262 .gain2 = ST_MAGN_0_FS_AVL_8100_GAIN_Z, 263 }, 264 }, 265 }, 266 .multi_read_bit = ST_MAGN_0_MULTIREAD_BIT, 267 .bootime = 2, 268 }, 269 { 270 .wai = ST_MAGN_1_WAI_EXP, 271 .sensors_supported = { 272 [0] = LSM303DLHC_MAGN_DEV_NAME, 273 [1] = LSM303DLM_MAGN_DEV_NAME, 274 }, 275 .ch = (struct iio_chan_spec *)st_magn_16bit_channels, 276 .odr = { 277 .addr = ST_MAGN_1_ODR_ADDR, 278 .mask = ST_MAGN_1_ODR_MASK, 279 .odr_avl = { 280 { 1, ST_MAGN_1_ODR_AVL_1HZ_VAL, }, 281 { 2, ST_MAGN_1_ODR_AVL_2HZ_VAL, }, 282 { 3, ST_MAGN_1_ODR_AVL_3HZ_VAL, }, 283 { 8, ST_MAGN_1_ODR_AVL_8HZ_VAL, }, 284 { 15, ST_MAGN_1_ODR_AVL_15HZ_VAL, }, 285 { 30, ST_MAGN_1_ODR_AVL_30HZ_VAL, }, 286 { 75, ST_MAGN_1_ODR_AVL_75HZ_VAL, }, 287 { 220, ST_MAGN_1_ODR_AVL_220HZ_VAL, }, 288 }, 289 }, 290 .pw = { 291 .addr = ST_MAGN_1_PW_ADDR, 292 .mask = ST_MAGN_1_PW_MASK, 293 .value_on = ST_MAGN_1_PW_ON, 294 .value_off = ST_MAGN_1_PW_OFF, 295 }, 296 .fs = { 297 .addr = ST_MAGN_1_FS_ADDR, 298 .mask = ST_MAGN_1_FS_MASK, 299 .fs_avl = { 300 [0] = { 301 .num = ST_MAGN_FS_AVL_1300MG, 302 .value = ST_MAGN_1_FS_AVL_1300_VAL, 303 .gain = ST_MAGN_1_FS_AVL_1300_GAIN_XY, 304 .gain2 = ST_MAGN_1_FS_AVL_1300_GAIN_Z, 305 }, 306 [1] = { 307 .num = ST_MAGN_FS_AVL_1900MG, 308 .value = ST_MAGN_1_FS_AVL_1900_VAL, 309 .gain = ST_MAGN_1_FS_AVL_1900_GAIN_XY, 310 .gain2 = ST_MAGN_1_FS_AVL_1900_GAIN_Z, 311 }, 312 [2] = { 313 .num = ST_MAGN_FS_AVL_2500MG, 314 .value = ST_MAGN_1_FS_AVL_2500_VAL, 315 .gain = ST_MAGN_1_FS_AVL_2500_GAIN_XY, 316 .gain2 = ST_MAGN_1_FS_AVL_2500_GAIN_Z, 317 }, 318 [3] = { 319 .num = ST_MAGN_FS_AVL_4000MG, 320 .value = ST_MAGN_1_FS_AVL_4000_VAL, 321 .gain = ST_MAGN_1_FS_AVL_4000_GAIN_XY, 322 .gain2 = ST_MAGN_1_FS_AVL_4000_GAIN_Z, 323 }, 324 [4] = { 325 .num = ST_MAGN_FS_AVL_4700MG, 326 .value = ST_MAGN_1_FS_AVL_4700_VAL, 327 .gain = ST_MAGN_1_FS_AVL_4700_GAIN_XY, 328 .gain2 = ST_MAGN_1_FS_AVL_4700_GAIN_Z, 329 }, 330 [5] = { 331 .num = ST_MAGN_FS_AVL_5600MG, 332 .value = ST_MAGN_1_FS_AVL_5600_VAL, 333 .gain = ST_MAGN_1_FS_AVL_5600_GAIN_XY, 334 .gain2 = ST_MAGN_1_FS_AVL_5600_GAIN_Z, 335 }, 336 [6] = { 337 .num = ST_MAGN_FS_AVL_8100MG, 338 .value = ST_MAGN_1_FS_AVL_8100_VAL, 339 .gain = ST_MAGN_1_FS_AVL_8100_GAIN_XY, 340 .gain2 = ST_MAGN_1_FS_AVL_8100_GAIN_Z, 341 }, 342 }, 343 }, 344 .multi_read_bit = ST_MAGN_1_MULTIREAD_BIT, 345 .bootime = 2, 346 }, 347 { 348 .wai = ST_MAGN_2_WAI_EXP, 349 .sensors_supported = { 350 [0] = LIS3MDL_MAGN_DEV_NAME, 351 }, 352 .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels, 353 .odr = { 354 .addr = ST_MAGN_2_ODR_ADDR, 355 .mask = ST_MAGN_2_ODR_MASK, 356 .odr_avl = { 357 { 1, ST_MAGN_2_ODR_AVL_1HZ_VAL, }, 358 { 2, ST_MAGN_2_ODR_AVL_2HZ_VAL, }, 359 { 3, ST_MAGN_2_ODR_AVL_3HZ_VAL, }, 360 { 5, ST_MAGN_2_ODR_AVL_5HZ_VAL, }, 361 { 10, ST_MAGN_2_ODR_AVL_10HZ_VAL, }, 362 { 20, ST_MAGN_2_ODR_AVL_20HZ_VAL, }, 363 { 40, ST_MAGN_2_ODR_AVL_40HZ_VAL, }, 364 { 80, ST_MAGN_2_ODR_AVL_80HZ_VAL, }, 365 }, 366 }, 367 .pw = { 368 .addr = ST_MAGN_2_PW_ADDR, 369 .mask = ST_MAGN_2_PW_MASK, 370 .value_on = ST_MAGN_2_PW_ON, 371 .value_off = ST_MAGN_2_PW_OFF, 372 }, 373 .fs = { 374 .addr = ST_MAGN_2_FS_ADDR, 375 .mask = ST_MAGN_2_FS_MASK, 376 .fs_avl = { 377 [0] = { 378 .num = ST_MAGN_FS_AVL_4000MG, 379 .value = ST_MAGN_2_FS_AVL_4000_VAL, 380 .gain = ST_MAGN_2_FS_AVL_4000_GAIN, 381 }, 382 [1] = { 383 .num = ST_MAGN_FS_AVL_8000MG, 384 .value = ST_MAGN_2_FS_AVL_8000_VAL, 385 .gain = ST_MAGN_2_FS_AVL_8000_GAIN, 386 }, 387 [2] = { 388 .num = ST_MAGN_FS_AVL_12000MG, 389 .value = ST_MAGN_2_FS_AVL_12000_VAL, 390 .gain = ST_MAGN_2_FS_AVL_12000_GAIN, 391 }, 392 [3] = { 393 .num = ST_MAGN_FS_AVL_16000MG, 394 .value = ST_MAGN_2_FS_AVL_16000_VAL, 395 .gain = ST_MAGN_2_FS_AVL_16000_GAIN, 396 }, 397 }, 398 }, 399 .multi_read_bit = ST_MAGN_2_MULTIREAD_BIT, 400 .bootime = 2, 401 }, 402 }; 403 404 static int st_magn_read_raw(struct iio_dev *indio_dev, 405 struct iio_chan_spec const *ch, int *val, 406 int *val2, long mask) 407 { 408 int err; 409 struct st_sensor_data *mdata = iio_priv(indio_dev); 410 411 switch (mask) { 412 case IIO_CHAN_INFO_RAW: 413 err = st_sensors_read_info_raw(indio_dev, ch, val); 414 if (err < 0) 415 goto read_error; 416 417 return IIO_VAL_INT; 418 case IIO_CHAN_INFO_SCALE: 419 *val = 0; 420 if ((ch->scan_index == ST_SENSORS_SCAN_Z) && 421 (mdata->current_fullscale->gain2 != 0)) 422 *val2 = mdata->current_fullscale->gain2; 423 else 424 *val2 = mdata->current_fullscale->gain; 425 return IIO_VAL_INT_PLUS_MICRO; 426 case IIO_CHAN_INFO_SAMP_FREQ: 427 *val = mdata->odr; 428 return IIO_VAL_INT; 429 default: 430 return -EINVAL; 431 } 432 433 read_error: 434 return err; 435 } 436 437 static int st_magn_write_raw(struct iio_dev *indio_dev, 438 struct iio_chan_spec const *chan, int val, int val2, long mask) 439 { 440 int err; 441 442 switch (mask) { 443 case IIO_CHAN_INFO_SCALE: 444 err = st_sensors_set_fullscale_by_gain(indio_dev, val2); 445 break; 446 case IIO_CHAN_INFO_SAMP_FREQ: 447 if (val2) 448 return -EINVAL; 449 mutex_lock(&indio_dev->mlock); 450 err = st_sensors_set_odr(indio_dev, val); 451 mutex_unlock(&indio_dev->mlock); 452 return err; 453 default: 454 err = -EINVAL; 455 } 456 457 return err; 458 } 459 460 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); 461 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available); 462 463 static struct attribute *st_magn_attributes[] = { 464 &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 465 &iio_dev_attr_in_magn_scale_available.dev_attr.attr, 466 NULL, 467 }; 468 469 static const struct attribute_group st_magn_attribute_group = { 470 .attrs = st_magn_attributes, 471 }; 472 473 static const struct iio_info magn_info = { 474 .driver_module = THIS_MODULE, 475 .attrs = &st_magn_attribute_group, 476 .read_raw = &st_magn_read_raw, 477 .write_raw = &st_magn_write_raw, 478 }; 479 480 int st_magn_common_probe(struct iio_dev *indio_dev) 481 { 482 struct st_sensor_data *mdata = iio_priv(indio_dev); 483 int irq = mdata->get_irq_data_ready(indio_dev); 484 int err; 485 486 indio_dev->modes = INDIO_DIRECT_MODE; 487 indio_dev->info = &magn_info; 488 mutex_init(&mdata->tb.buf_lock); 489 490 st_sensors_power_enable(indio_dev); 491 492 err = st_sensors_check_device_support(indio_dev, 493 ARRAY_SIZE(st_magn_sensors_settings), 494 st_magn_sensors_settings); 495 if (err < 0) 496 return err; 497 498 mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS; 499 mdata->multiread_bit = mdata->sensor_settings->multi_read_bit; 500 indio_dev->channels = mdata->sensor_settings->ch; 501 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; 502 503 mdata->current_fullscale = (struct st_sensor_fullscale_avl *) 504 &mdata->sensor_settings->fs.fs_avl[0]; 505 mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz; 506 507 err = st_sensors_init_sensor(indio_dev, NULL); 508 if (err < 0) 509 return err; 510 511 err = st_magn_allocate_ring(indio_dev); 512 if (err < 0) 513 return err; 514 515 if (irq > 0) { 516 err = st_sensors_allocate_trigger(indio_dev, NULL); 517 if (err < 0) 518 goto st_magn_probe_trigger_error; 519 } 520 521 err = iio_device_register(indio_dev); 522 if (err) 523 goto st_magn_device_register_error; 524 525 dev_info(&indio_dev->dev, "registered magnetometer %s\n", 526 indio_dev->name); 527 528 return 0; 529 530 st_magn_device_register_error: 531 if (irq > 0) 532 st_sensors_deallocate_trigger(indio_dev); 533 st_magn_probe_trigger_error: 534 st_magn_deallocate_ring(indio_dev); 535 536 return err; 537 } 538 EXPORT_SYMBOL(st_magn_common_probe); 539 540 void st_magn_common_remove(struct iio_dev *indio_dev) 541 { 542 struct st_sensor_data *mdata = iio_priv(indio_dev); 543 544 st_sensors_power_disable(indio_dev); 545 546 iio_device_unregister(indio_dev); 547 if (mdata->get_irq_data_ready(indio_dev) > 0) 548 st_sensors_deallocate_trigger(indio_dev); 549 550 st_magn_deallocate_ring(indio_dev); 551 } 552 EXPORT_SYMBOL(st_magn_common_remove); 553 554 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 555 MODULE_DESCRIPTION("STMicroelectronics magnetometers driver"); 556 MODULE_LICENSE("GPL v2"); 557