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 /* DEFAULT VALUE FOR SENSORS */ 30 #define ST_MAGN_DEFAULT_OUT_X_L_ADDR 0X04 31 #define ST_MAGN_DEFAULT_OUT_Y_L_ADDR 0X08 32 #define ST_MAGN_DEFAULT_OUT_Z_L_ADDR 0X06 33 34 /* FULLSCALE */ 35 #define ST_MAGN_FS_AVL_1300MG 1300 36 #define ST_MAGN_FS_AVL_1900MG 1900 37 #define ST_MAGN_FS_AVL_2500MG 2500 38 #define ST_MAGN_FS_AVL_4000MG 4000 39 #define ST_MAGN_FS_AVL_4700MG 4700 40 #define ST_MAGN_FS_AVL_5600MG 5600 41 #define ST_MAGN_FS_AVL_8000MG 8000 42 #define ST_MAGN_FS_AVL_8100MG 8100 43 #define ST_MAGN_FS_AVL_10000MG 10000 44 45 /* CUSTOM VALUES FOR SENSOR 1 */ 46 #define ST_MAGN_1_WAI_EXP 0x3c 47 #define ST_MAGN_1_ODR_ADDR 0x00 48 #define ST_MAGN_1_ODR_MASK 0x1c 49 #define ST_MAGN_1_ODR_AVL_1HZ_VAL 0x00 50 #define ST_MAGN_1_ODR_AVL_2HZ_VAL 0x01 51 #define ST_MAGN_1_ODR_AVL_3HZ_VAL 0x02 52 #define ST_MAGN_1_ODR_AVL_8HZ_VAL 0x03 53 #define ST_MAGN_1_ODR_AVL_15HZ_VAL 0x04 54 #define ST_MAGN_1_ODR_AVL_30HZ_VAL 0x05 55 #define ST_MAGN_1_ODR_AVL_75HZ_VAL 0x06 56 #define ST_MAGN_1_ODR_AVL_220HZ_VAL 0x07 57 #define ST_MAGN_1_PW_ADDR 0x02 58 #define ST_MAGN_1_PW_MASK 0x03 59 #define ST_MAGN_1_PW_ON 0x00 60 #define ST_MAGN_1_PW_OFF 0x03 61 #define ST_MAGN_1_FS_ADDR 0x01 62 #define ST_MAGN_1_FS_MASK 0xe0 63 #define ST_MAGN_1_FS_AVL_1300_VAL 0x01 64 #define ST_MAGN_1_FS_AVL_1900_VAL 0x02 65 #define ST_MAGN_1_FS_AVL_2500_VAL 0x03 66 #define ST_MAGN_1_FS_AVL_4000_VAL 0x04 67 #define ST_MAGN_1_FS_AVL_4700_VAL 0x05 68 #define ST_MAGN_1_FS_AVL_5600_VAL 0x06 69 #define ST_MAGN_1_FS_AVL_8100_VAL 0x07 70 #define ST_MAGN_1_FS_AVL_1300_GAIN_XY 1100 71 #define ST_MAGN_1_FS_AVL_1900_GAIN_XY 855 72 #define ST_MAGN_1_FS_AVL_2500_GAIN_XY 670 73 #define ST_MAGN_1_FS_AVL_4000_GAIN_XY 450 74 #define ST_MAGN_1_FS_AVL_4700_GAIN_XY 400 75 #define ST_MAGN_1_FS_AVL_5600_GAIN_XY 330 76 #define ST_MAGN_1_FS_AVL_8100_GAIN_XY 230 77 #define ST_MAGN_1_FS_AVL_1300_GAIN_Z 980 78 #define ST_MAGN_1_FS_AVL_1900_GAIN_Z 760 79 #define ST_MAGN_1_FS_AVL_2500_GAIN_Z 600 80 #define ST_MAGN_1_FS_AVL_4000_GAIN_Z 400 81 #define ST_MAGN_1_FS_AVL_4700_GAIN_Z 355 82 #define ST_MAGN_1_FS_AVL_5600_GAIN_Z 295 83 #define ST_MAGN_1_FS_AVL_8100_GAIN_Z 205 84 #define ST_MAGN_1_MULTIREAD_BIT false 85 86 /* CUSTOM VALUES FOR SENSOR 2 */ 87 #define ST_MAGN_2_WAI_EXP 0x3d 88 #define ST_MAGN_2_ODR_ADDR 0x20 89 #define ST_MAGN_2_ODR_MASK 0x1c 90 #define ST_MAGN_2_ODR_AVL_1HZ_VAL 0x00 91 #define ST_MAGN_2_ODR_AVL_2HZ_VAL 0x01 92 #define ST_MAGN_2_ODR_AVL_3HZ_VAL 0x02 93 #define ST_MAGN_2_ODR_AVL_5HZ_VAL 0x03 94 #define ST_MAGN_2_ODR_AVL_10HZ_VAL 0x04 95 #define ST_MAGN_2_ODR_AVL_20HZ_VAL 0x05 96 #define ST_MAGN_2_ODR_AVL_40HZ_VAL 0x06 97 #define ST_MAGN_2_ODR_AVL_80HZ_VAL 0x07 98 #define ST_MAGN_2_PW_ADDR 0x22 99 #define ST_MAGN_2_PW_MASK 0x03 100 #define ST_MAGN_2_PW_ON 0x00 101 #define ST_MAGN_2_PW_OFF 0x03 102 #define ST_MAGN_2_FS_ADDR 0x21 103 #define ST_MAGN_2_FS_MASK 0x60 104 #define ST_MAGN_2_FS_AVL_4000_VAL 0x00 105 #define ST_MAGN_2_FS_AVL_8000_VAL 0x01 106 #define ST_MAGN_2_FS_AVL_10000_VAL 0x02 107 #define ST_MAGN_2_FS_AVL_4000_GAIN 430 108 #define ST_MAGN_2_FS_AVL_8000_GAIN 230 109 #define ST_MAGN_2_FS_AVL_10000_GAIN 230 110 #define ST_MAGN_2_MULTIREAD_BIT false 111 #define ST_MAGN_2_OUT_X_L_ADDR 0x28 112 #define ST_MAGN_2_OUT_Y_L_ADDR 0x2a 113 #define ST_MAGN_2_OUT_Z_L_ADDR 0x2c 114 115 static const struct iio_chan_spec st_magn_16bit_channels[] = { 116 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE, 117 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_X_L_ADDR), 118 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE, 119 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Y_L_ADDR), 120 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE, 121 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Z_L_ADDR), 122 IIO_CHAN_SOFT_TIMESTAMP(3) 123 }; 124 125 static const struct iio_chan_spec st_magn_2_16bit_channels[] = { 126 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE, 127 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_X_L_ADDR), 128 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE, 129 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Y_L_ADDR), 130 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE, 131 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Z_L_ADDR), 132 IIO_CHAN_SOFT_TIMESTAMP(3) 133 }; 134 135 static const struct st_sensors st_magn_sensors[] = { 136 { 137 .wai = ST_MAGN_1_WAI_EXP, 138 .sensors_supported = { 139 [0] = LSM303DLHC_MAGN_DEV_NAME, 140 [1] = LSM303DLM_MAGN_DEV_NAME, 141 }, 142 .ch = (struct iio_chan_spec *)st_magn_16bit_channels, 143 .odr = { 144 .addr = ST_MAGN_1_ODR_ADDR, 145 .mask = ST_MAGN_1_ODR_MASK, 146 .odr_avl = { 147 { 1, ST_MAGN_1_ODR_AVL_1HZ_VAL, }, 148 { 2, ST_MAGN_1_ODR_AVL_2HZ_VAL, }, 149 { 3, ST_MAGN_1_ODR_AVL_3HZ_VAL, }, 150 { 8, ST_MAGN_1_ODR_AVL_8HZ_VAL, }, 151 { 15, ST_MAGN_1_ODR_AVL_15HZ_VAL, }, 152 { 30, ST_MAGN_1_ODR_AVL_30HZ_VAL, }, 153 { 75, ST_MAGN_1_ODR_AVL_75HZ_VAL, }, 154 { 220, ST_MAGN_1_ODR_AVL_220HZ_VAL, }, 155 }, 156 }, 157 .pw = { 158 .addr = ST_MAGN_1_PW_ADDR, 159 .mask = ST_MAGN_1_PW_MASK, 160 .value_on = ST_MAGN_1_PW_ON, 161 .value_off = ST_MAGN_1_PW_OFF, 162 }, 163 .fs = { 164 .addr = ST_MAGN_1_FS_ADDR, 165 .mask = ST_MAGN_1_FS_MASK, 166 .fs_avl = { 167 [0] = { 168 .num = ST_MAGN_FS_AVL_1300MG, 169 .value = ST_MAGN_1_FS_AVL_1300_VAL, 170 .gain = ST_MAGN_1_FS_AVL_1300_GAIN_XY, 171 .gain2 = ST_MAGN_1_FS_AVL_1300_GAIN_Z, 172 }, 173 [1] = { 174 .num = ST_MAGN_FS_AVL_1900MG, 175 .value = ST_MAGN_1_FS_AVL_1900_VAL, 176 .gain = ST_MAGN_1_FS_AVL_1900_GAIN_XY, 177 .gain2 = ST_MAGN_1_FS_AVL_1900_GAIN_Z, 178 }, 179 [2] = { 180 .num = ST_MAGN_FS_AVL_2500MG, 181 .value = ST_MAGN_1_FS_AVL_2500_VAL, 182 .gain = ST_MAGN_1_FS_AVL_2500_GAIN_XY, 183 .gain2 = ST_MAGN_1_FS_AVL_2500_GAIN_Z, 184 }, 185 [3] = { 186 .num = ST_MAGN_FS_AVL_4000MG, 187 .value = ST_MAGN_1_FS_AVL_4000_VAL, 188 .gain = ST_MAGN_1_FS_AVL_4000_GAIN_XY, 189 .gain2 = ST_MAGN_1_FS_AVL_4000_GAIN_Z, 190 }, 191 [4] = { 192 .num = ST_MAGN_FS_AVL_4700MG, 193 .value = ST_MAGN_1_FS_AVL_4700_VAL, 194 .gain = ST_MAGN_1_FS_AVL_4700_GAIN_XY, 195 .gain2 = ST_MAGN_1_FS_AVL_4700_GAIN_Z, 196 }, 197 [5] = { 198 .num = ST_MAGN_FS_AVL_5600MG, 199 .value = ST_MAGN_1_FS_AVL_5600_VAL, 200 .gain = ST_MAGN_1_FS_AVL_5600_GAIN_XY, 201 .gain2 = ST_MAGN_1_FS_AVL_5600_GAIN_Z, 202 }, 203 [6] = { 204 .num = ST_MAGN_FS_AVL_8100MG, 205 .value = ST_MAGN_1_FS_AVL_8100_VAL, 206 .gain = ST_MAGN_1_FS_AVL_8100_GAIN_XY, 207 .gain2 = ST_MAGN_1_FS_AVL_8100_GAIN_Z, 208 }, 209 }, 210 }, 211 .multi_read_bit = ST_MAGN_1_MULTIREAD_BIT, 212 .bootime = 2, 213 }, 214 { 215 .wai = ST_MAGN_2_WAI_EXP, 216 .sensors_supported = { 217 [0] = LIS3MDL_MAGN_DEV_NAME, 218 }, 219 .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels, 220 .odr = { 221 .addr = ST_MAGN_2_ODR_ADDR, 222 .mask = ST_MAGN_2_ODR_MASK, 223 .odr_avl = { 224 { 1, ST_MAGN_2_ODR_AVL_1HZ_VAL, }, 225 { 2, ST_MAGN_2_ODR_AVL_2HZ_VAL, }, 226 { 3, ST_MAGN_2_ODR_AVL_3HZ_VAL, }, 227 { 5, ST_MAGN_2_ODR_AVL_5HZ_VAL, }, 228 { 10, ST_MAGN_2_ODR_AVL_10HZ_VAL, }, 229 { 20, ST_MAGN_2_ODR_AVL_20HZ_VAL, }, 230 { 40, ST_MAGN_2_ODR_AVL_40HZ_VAL, }, 231 { 80, ST_MAGN_2_ODR_AVL_80HZ_VAL, }, 232 }, 233 }, 234 .pw = { 235 .addr = ST_MAGN_2_PW_ADDR, 236 .mask = ST_MAGN_2_PW_MASK, 237 .value_on = ST_MAGN_2_PW_ON, 238 .value_off = ST_MAGN_2_PW_OFF, 239 }, 240 .fs = { 241 .addr = ST_MAGN_2_FS_ADDR, 242 .mask = ST_MAGN_2_FS_MASK, 243 .fs_avl = { 244 [0] = { 245 .num = ST_MAGN_FS_AVL_4000MG, 246 .value = ST_MAGN_2_FS_AVL_4000_VAL, 247 .gain = ST_MAGN_2_FS_AVL_4000_GAIN, 248 }, 249 [1] = { 250 .num = ST_MAGN_FS_AVL_8000MG, 251 .value = ST_MAGN_2_FS_AVL_8000_VAL, 252 .gain = ST_MAGN_2_FS_AVL_8000_GAIN, 253 }, 254 [2] = { 255 .num = ST_MAGN_FS_AVL_10000MG, 256 .value = ST_MAGN_2_FS_AVL_10000_VAL, 257 .gain = ST_MAGN_2_FS_AVL_10000_GAIN, 258 }, 259 }, 260 }, 261 .multi_read_bit = ST_MAGN_2_MULTIREAD_BIT, 262 .bootime = 2, 263 }, 264 }; 265 266 static int st_magn_read_raw(struct iio_dev *indio_dev, 267 struct iio_chan_spec const *ch, int *val, 268 int *val2, long mask) 269 { 270 int err; 271 struct st_sensor_data *mdata = iio_priv(indio_dev); 272 273 switch (mask) { 274 case IIO_CHAN_INFO_RAW: 275 err = st_sensors_read_info_raw(indio_dev, ch, val); 276 if (err < 0) 277 goto read_error; 278 279 return IIO_VAL_INT; 280 case IIO_CHAN_INFO_SCALE: 281 *val = 0; 282 if ((ch->scan_index == ST_SENSORS_SCAN_Z) && 283 (mdata->current_fullscale->gain2 != 0)) 284 *val2 = mdata->current_fullscale->gain2; 285 else 286 *val2 = mdata->current_fullscale->gain; 287 return IIO_VAL_INT_PLUS_MICRO; 288 default: 289 return -EINVAL; 290 } 291 292 read_error: 293 return err; 294 } 295 296 static int st_magn_write_raw(struct iio_dev *indio_dev, 297 struct iio_chan_spec const *chan, int val, int val2, long mask) 298 { 299 int err; 300 301 switch (mask) { 302 case IIO_CHAN_INFO_SCALE: 303 err = st_sensors_set_fullscale_by_gain(indio_dev, val2); 304 break; 305 default: 306 err = -EINVAL; 307 } 308 309 return err; 310 } 311 312 static ST_SENSOR_DEV_ATTR_SAMP_FREQ(); 313 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); 314 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available); 315 316 static struct attribute *st_magn_attributes[] = { 317 &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 318 &iio_dev_attr_in_magn_scale_available.dev_attr.attr, 319 &iio_dev_attr_sampling_frequency.dev_attr.attr, 320 NULL, 321 }; 322 323 static const struct attribute_group st_magn_attribute_group = { 324 .attrs = st_magn_attributes, 325 }; 326 327 static const struct iio_info magn_info = { 328 .driver_module = THIS_MODULE, 329 .attrs = &st_magn_attribute_group, 330 .read_raw = &st_magn_read_raw, 331 .write_raw = &st_magn_write_raw, 332 }; 333 334 int st_magn_common_probe(struct iio_dev *indio_dev) 335 { 336 int err; 337 struct st_sensor_data *mdata = iio_priv(indio_dev); 338 339 indio_dev->modes = INDIO_DIRECT_MODE; 340 indio_dev->info = &magn_info; 341 342 err = st_sensors_check_device_support(indio_dev, 343 ARRAY_SIZE(st_magn_sensors), st_magn_sensors); 344 if (err < 0) 345 goto st_magn_common_probe_error; 346 347 mdata->multiread_bit = mdata->sensor->multi_read_bit; 348 indio_dev->channels = mdata->sensor->ch; 349 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; 350 351 mdata->current_fullscale = (struct st_sensor_fullscale_avl *) 352 &mdata->sensor->fs.fs_avl[0]; 353 mdata->odr = mdata->sensor->odr.odr_avl[0].hz; 354 355 err = st_sensors_init_sensor(indio_dev); 356 if (err < 0) 357 goto st_magn_common_probe_error; 358 359 if (mdata->get_irq_data_ready(indio_dev) > 0) { 360 err = st_magn_allocate_ring(indio_dev); 361 if (err < 0) 362 goto st_magn_common_probe_error; 363 err = st_sensors_allocate_trigger(indio_dev, NULL); 364 if (err < 0) 365 goto st_magn_probe_trigger_error; 366 } 367 368 err = iio_device_register(indio_dev); 369 if (err) 370 goto st_magn_device_register_error; 371 372 return err; 373 374 st_magn_device_register_error: 375 if (mdata->get_irq_data_ready(indio_dev) > 0) 376 st_sensors_deallocate_trigger(indio_dev); 377 st_magn_probe_trigger_error: 378 if (mdata->get_irq_data_ready(indio_dev) > 0) 379 st_magn_deallocate_ring(indio_dev); 380 st_magn_common_probe_error: 381 return err; 382 } 383 EXPORT_SYMBOL(st_magn_common_probe); 384 385 void st_magn_common_remove(struct iio_dev *indio_dev) 386 { 387 struct st_sensor_data *mdata = iio_priv(indio_dev); 388 389 iio_device_unregister(indio_dev); 390 if (mdata->get_irq_data_ready(indio_dev) > 0) { 391 st_sensors_deallocate_trigger(indio_dev); 392 st_magn_deallocate_ring(indio_dev); 393 } 394 iio_device_free(indio_dev); 395 } 396 EXPORT_SYMBOL(st_magn_common_remove); 397 398 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 399 MODULE_DESCRIPTION("STMicroelectronics magnetometers driver"); 400 MODULE_LICENSE("GPL v2"); 401