1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * FXOS8700 - NXP IMU (accelerometer plus magnetometer) 4 * 5 * IIO core driver for FXOS8700, with support for I2C/SPI busses 6 * 7 * TODO: Buffer, trigger, and IRQ support 8 */ 9 #include <linux/module.h> 10 #include <linux/regmap.h> 11 #include <linux/bitops.h> 12 #include <linux/bitfield.h> 13 14 #include <linux/iio/iio.h> 15 #include <linux/iio/sysfs.h> 16 17 #include "fxos8700.h" 18 19 /* Register Definitions */ 20 #define FXOS8700_STATUS 0x00 21 #define FXOS8700_OUT_X_MSB 0x01 22 #define FXOS8700_OUT_X_LSB 0x02 23 #define FXOS8700_OUT_Y_MSB 0x03 24 #define FXOS8700_OUT_Y_LSB 0x04 25 #define FXOS8700_OUT_Z_MSB 0x05 26 #define FXOS8700_OUT_Z_LSB 0x06 27 #define FXOS8700_F_SETUP 0x09 28 #define FXOS8700_TRIG_CFG 0x0a 29 #define FXOS8700_SYSMOD 0x0b 30 #define FXOS8700_INT_SOURCE 0x0c 31 #define FXOS8700_WHO_AM_I 0x0d 32 #define FXOS8700_XYZ_DATA_CFG 0x0e 33 #define FXOS8700_HP_FILTER_CUTOFF 0x0f 34 #define FXOS8700_PL_STATUS 0x10 35 #define FXOS8700_PL_CFG 0x11 36 #define FXOS8700_PL_COUNT 0x12 37 #define FXOS8700_PL_BF_ZCOMP 0x13 38 #define FXOS8700_PL_THS_REG 0x14 39 #define FXOS8700_A_FFMT_CFG 0x15 40 #define FXOS8700_A_FFMT_SRC 0x16 41 #define FXOS8700_A_FFMT_THS 0x17 42 #define FXOS8700_A_FFMT_COUNT 0x18 43 #define FXOS8700_TRANSIENT_CFG 0x1d 44 #define FXOS8700_TRANSIENT_SRC 0x1e 45 #define FXOS8700_TRANSIENT_THS 0x1f 46 #define FXOS8700_TRANSIENT_COUNT 0x20 47 #define FXOS8700_PULSE_CFG 0x21 48 #define FXOS8700_PULSE_SRC 0x22 49 #define FXOS8700_PULSE_THSX 0x23 50 #define FXOS8700_PULSE_THSY 0x24 51 #define FXOS8700_PULSE_THSZ 0x25 52 #define FXOS8700_PULSE_TMLT 0x26 53 #define FXOS8700_PULSE_LTCY 0x27 54 #define FXOS8700_PULSE_WIND 0x28 55 #define FXOS8700_ASLP_COUNT 0x29 56 #define FXOS8700_CTRL_REG1 0x2a 57 #define FXOS8700_CTRL_REG2 0x2b 58 #define FXOS8700_CTRL_REG3 0x2c 59 #define FXOS8700_CTRL_REG4 0x2d 60 #define FXOS8700_CTRL_REG5 0x2e 61 #define FXOS8700_OFF_X 0x2f 62 #define FXOS8700_OFF_Y 0x30 63 #define FXOS8700_OFF_Z 0x31 64 #define FXOS8700_M_DR_STATUS 0x32 65 #define FXOS8700_M_OUT_X_MSB 0x33 66 #define FXOS8700_M_OUT_X_LSB 0x34 67 #define FXOS8700_M_OUT_Y_MSB 0x35 68 #define FXOS8700_M_OUT_Y_LSB 0x36 69 #define FXOS8700_M_OUT_Z_MSB 0x37 70 #define FXOS8700_M_OUT_Z_LSB 0x38 71 #define FXOS8700_CMP_X_MSB 0x39 72 #define FXOS8700_CMP_X_LSB 0x3a 73 #define FXOS8700_CMP_Y_MSB 0x3b 74 #define FXOS8700_CMP_Y_LSB 0x3c 75 #define FXOS8700_CMP_Z_MSB 0x3d 76 #define FXOS8700_CMP_Z_LSB 0x3e 77 #define FXOS8700_M_OFF_X_MSB 0x3f 78 #define FXOS8700_M_OFF_X_LSB 0x40 79 #define FXOS8700_M_OFF_Y_MSB 0x41 80 #define FXOS8700_M_OFF_Y_LSB 0x42 81 #define FXOS8700_M_OFF_Z_MSB 0x43 82 #define FXOS8700_M_OFF_Z_LSB 0x44 83 #define FXOS8700_MAX_X_MSB 0x45 84 #define FXOS8700_MAX_X_LSB 0x46 85 #define FXOS8700_MAX_Y_MSB 0x47 86 #define FXOS8700_MAX_Y_LSB 0x48 87 #define FXOS8700_MAX_Z_MSB 0x49 88 #define FXOS8700_MAX_Z_LSB 0x4a 89 #define FXOS8700_MIN_X_MSB 0x4b 90 #define FXOS8700_MIN_X_LSB 0x4c 91 #define FXOS8700_MIN_Y_MSB 0x4d 92 #define FXOS8700_MIN_Y_LSB 0x4e 93 #define FXOS8700_MIN_Z_MSB 0x4f 94 #define FXOS8700_MIN_Z_LSB 0x50 95 #define FXOS8700_TEMP 0x51 96 #define FXOS8700_M_THS_CFG 0x52 97 #define FXOS8700_M_THS_SRC 0x53 98 #define FXOS8700_M_THS_X_MSB 0x54 99 #define FXOS8700_M_THS_X_LSB 0x55 100 #define FXOS8700_M_THS_Y_MSB 0x56 101 #define FXOS8700_M_THS_Y_LSB 0x57 102 #define FXOS8700_M_THS_Z_MSB 0x58 103 #define FXOS8700_M_THS_Z_LSB 0x59 104 #define FXOS8700_M_THS_COUNT 0x5a 105 #define FXOS8700_M_CTRL_REG1 0x5b 106 #define FXOS8700_M_CTRL_REG2 0x5c 107 #define FXOS8700_M_CTRL_REG3 0x5d 108 #define FXOS8700_M_INT_SRC 0x5e 109 #define FXOS8700_A_VECM_CFG 0x5f 110 #define FXOS8700_A_VECM_THS_MSB 0x60 111 #define FXOS8700_A_VECM_THS_LSB 0x61 112 #define FXOS8700_A_VECM_CNT 0x62 113 #define FXOS8700_A_VECM_INITX_MSB 0x63 114 #define FXOS8700_A_VECM_INITX_LSB 0x64 115 #define FXOS8700_A_VECM_INITY_MSB 0x65 116 #define FXOS8700_A_VECM_INITY_LSB 0x66 117 #define FXOS8700_A_VECM_INITZ_MSB 0x67 118 #define FXOS8700_A_VECM_INITZ_LSB 0x68 119 #define FXOS8700_M_VECM_CFG 0x69 120 #define FXOS8700_M_VECM_THS_MSB 0x6a 121 #define FXOS8700_M_VECM_THS_LSB 0x6b 122 #define FXOS8700_M_VECM_CNT 0x6c 123 #define FXOS8700_M_VECM_INITX_MSB 0x6d 124 #define FXOS8700_M_VECM_INITX_LSB 0x6e 125 #define FXOS8700_M_VECM_INITY_MSB 0x6f 126 #define FXOS8700_M_VECM_INITY_LSB 0x70 127 #define FXOS8700_M_VECM_INITZ_MSB 0x71 128 #define FXOS8700_M_VECM_INITZ_LSB 0x72 129 #define FXOS8700_A_FFMT_THS_X_MSB 0x73 130 #define FXOS8700_A_FFMT_THS_X_LSB 0x74 131 #define FXOS8700_A_FFMT_THS_Y_MSB 0x75 132 #define FXOS8700_A_FFMT_THS_Y_LSB 0x76 133 #define FXOS8700_A_FFMT_THS_Z_MSB 0x77 134 #define FXOS8700_A_FFMT_THS_Z_LSB 0x78 135 #define FXOS8700_A_TRAN_INIT_MSB 0x79 136 #define FXOS8700_A_TRAN_INIT_LSB_X 0x7a 137 #define FXOS8700_A_TRAN_INIT_LSB_Y 0x7b 138 #define FXOS8700_A_TRAN_INIT_LSB_Z 0x7d 139 #define FXOS8700_TM_NVM_LOCK 0x7e 140 #define FXOS8700_NVM_DATA0_35 0x80 141 #define FXOS8700_NVM_DATA_BNK3 0xa4 142 #define FXOS8700_NVM_DATA_BNK2 0xa5 143 #define FXOS8700_NVM_DATA_BNK1 0xa6 144 #define FXOS8700_NVM_DATA_BNK0 0xa7 145 146 /* Bit definitions for FXOS8700_CTRL_REG1 */ 147 #define FXOS8700_CTRL_ODR_MAX 0x00 148 #define FXOS8700_CTRL_ODR_MSK GENMASK(5, 3) 149 150 /* Bit definitions for FXOS8700_M_CTRL_REG1 */ 151 #define FXOS8700_HMS_MASK GENMASK(1, 0) 152 #define FXOS8700_OS_MASK GENMASK(4, 2) 153 154 /* Bit definitions for FXOS8700_M_CTRL_REG2 */ 155 #define FXOS8700_MAXMIN_RST BIT(2) 156 #define FXOS8700_MAXMIN_DIS_THS BIT(3) 157 #define FXOS8700_MAXMIN_DIS BIT(4) 158 159 #define FXOS8700_ACTIVE 0x01 160 #define FXOS8700_ACTIVE_MIN_USLEEP 4000 /* from table 6 in datasheet */ 161 162 #define FXOS8700_DEVICE_ID 0xC7 163 #define FXOS8700_PRE_DEVICE_ID 0xC4 164 #define FXOS8700_DATA_BUF_SIZE 3 165 166 struct fxos8700_data { 167 struct regmap *regmap; 168 struct iio_trigger *trig; 169 __be16 buf[FXOS8700_DATA_BUF_SIZE] __aligned(IIO_DMA_MINALIGN); 170 }; 171 172 /* Regmap info */ 173 static const struct regmap_range read_range[] = { 174 { 175 .range_min = FXOS8700_STATUS, 176 .range_max = FXOS8700_A_FFMT_COUNT, 177 }, { 178 .range_min = FXOS8700_TRANSIENT_CFG, 179 .range_max = FXOS8700_A_FFMT_THS_Z_LSB, 180 }, 181 }; 182 183 static const struct regmap_range write_range[] = { 184 { 185 .range_min = FXOS8700_F_SETUP, 186 .range_max = FXOS8700_TRIG_CFG, 187 }, { 188 .range_min = FXOS8700_XYZ_DATA_CFG, 189 .range_max = FXOS8700_HP_FILTER_CUTOFF, 190 }, { 191 .range_min = FXOS8700_PL_CFG, 192 .range_max = FXOS8700_A_FFMT_CFG, 193 }, { 194 .range_min = FXOS8700_A_FFMT_THS, 195 .range_max = FXOS8700_TRANSIENT_CFG, 196 }, { 197 .range_min = FXOS8700_TRANSIENT_THS, 198 .range_max = FXOS8700_PULSE_CFG, 199 }, { 200 .range_min = FXOS8700_PULSE_THSX, 201 .range_max = FXOS8700_OFF_Z, 202 }, { 203 .range_min = FXOS8700_M_OFF_X_MSB, 204 .range_max = FXOS8700_M_OFF_Z_LSB, 205 }, { 206 .range_min = FXOS8700_M_THS_CFG, 207 .range_max = FXOS8700_M_THS_CFG, 208 }, { 209 .range_min = FXOS8700_M_THS_X_MSB, 210 .range_max = FXOS8700_M_CTRL_REG3, 211 }, { 212 .range_min = FXOS8700_A_VECM_CFG, 213 .range_max = FXOS8700_A_FFMT_THS_Z_LSB, 214 }, 215 }; 216 217 static const struct regmap_access_table driver_read_table = { 218 .yes_ranges = read_range, 219 .n_yes_ranges = ARRAY_SIZE(read_range), 220 }; 221 222 static const struct regmap_access_table driver_write_table = { 223 .yes_ranges = write_range, 224 .n_yes_ranges = ARRAY_SIZE(write_range), 225 }; 226 227 const struct regmap_config fxos8700_regmap_config = { 228 .reg_bits = 8, 229 .val_bits = 8, 230 .max_register = FXOS8700_NVM_DATA_BNK0, 231 .rd_table = &driver_read_table, 232 .wr_table = &driver_write_table, 233 }; 234 EXPORT_SYMBOL(fxos8700_regmap_config); 235 236 #define FXOS8700_CHANNEL(_type, _axis) { \ 237 .type = _type, \ 238 .modified = 1, \ 239 .channel2 = IIO_MOD_##_axis, \ 240 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 241 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 242 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 243 } 244 245 enum fxos8700_accel_scale_bits { 246 MODE_2G = 0, 247 MODE_4G, 248 MODE_8G, 249 }; 250 251 /* scan indexes follow DATA register order */ 252 enum fxos8700_scan_axis { 253 FXOS8700_SCAN_ACCEL_X = 0, 254 FXOS8700_SCAN_ACCEL_Y, 255 FXOS8700_SCAN_ACCEL_Z, 256 FXOS8700_SCAN_MAGN_X, 257 FXOS8700_SCAN_MAGN_Y, 258 FXOS8700_SCAN_MAGN_Z, 259 FXOS8700_SCAN_RHALL, 260 FXOS8700_SCAN_TIMESTAMP, 261 }; 262 263 enum fxos8700_sensor { 264 FXOS8700_ACCEL = 0, 265 FXOS8700_MAGN, 266 FXOS8700_NUM_SENSORS /* must be last */ 267 }; 268 269 enum fxos8700_int_pin { 270 FXOS8700_PIN_INT1, 271 FXOS8700_PIN_INT2 272 }; 273 274 struct fxos8700_scale { 275 u8 bits; 276 int uscale; 277 }; 278 279 struct fxos8700_odr { 280 u8 bits; 281 int odr; 282 int uodr; 283 }; 284 285 static const struct fxos8700_scale fxos8700_accel_scale[] = { 286 { MODE_2G, 244}, 287 { MODE_4G, 488}, 288 { MODE_8G, 976}, 289 }; 290 291 /* 292 * Accellerometer and magnetometer have the same ODR options, set in the 293 * CTRL_REG1 register. ODR is halved when using both sensors at once in 294 * hybrid mode. 295 */ 296 static const struct fxos8700_odr fxos8700_odr[] = { 297 {0x00, 800, 0}, 298 {0x01, 400, 0}, 299 {0x02, 200, 0}, 300 {0x03, 100, 0}, 301 {0x04, 50, 0}, 302 {0x05, 12, 500000}, 303 {0x06, 6, 250000}, 304 {0x07, 1, 562500}, 305 }; 306 307 static const struct iio_chan_spec fxos8700_channels[] = { 308 FXOS8700_CHANNEL(IIO_ACCEL, X), 309 FXOS8700_CHANNEL(IIO_ACCEL, Y), 310 FXOS8700_CHANNEL(IIO_ACCEL, Z), 311 FXOS8700_CHANNEL(IIO_MAGN, X), 312 FXOS8700_CHANNEL(IIO_MAGN, Y), 313 FXOS8700_CHANNEL(IIO_MAGN, Z), 314 IIO_CHAN_SOFT_TIMESTAMP(FXOS8700_SCAN_TIMESTAMP), 315 }; 316 317 static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type) 318 { 319 switch (iio_type) { 320 case IIO_ACCEL: 321 return FXOS8700_ACCEL; 322 case IIO_MAGN: 323 return FXOS8700_MAGN; 324 default: 325 return -EINVAL; 326 } 327 } 328 329 static int fxos8700_set_active_mode(struct fxos8700_data *data, 330 enum fxos8700_sensor t, bool mode) 331 { 332 int ret; 333 334 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, mode); 335 if (ret) 336 return ret; 337 338 usleep_range(FXOS8700_ACTIVE_MIN_USLEEP, 339 FXOS8700_ACTIVE_MIN_USLEEP + 1000); 340 341 return 0; 342 } 343 344 static int fxos8700_set_scale(struct fxos8700_data *data, 345 enum fxos8700_sensor t, int uscale) 346 { 347 int i, ret, val; 348 bool active_mode; 349 static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale); 350 struct device *dev = regmap_get_device(data->regmap); 351 352 if (t == FXOS8700_MAGN) { 353 dev_err(dev, "Magnetometer scale is locked at 0.001Gs\n"); 354 return -EINVAL; 355 } 356 357 /* 358 * When device is in active mode, it failed to set an ACCEL 359 * full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG. 360 * This is not align with the datasheet, but it is a fxos8700 361 * chip behavier. Set the device in standby mode before setting 362 * an ACCEL full-scale range. 363 */ 364 ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val); 365 if (ret) 366 return ret; 367 368 active_mode = val & FXOS8700_ACTIVE; 369 if (active_mode) { 370 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 371 val & ~FXOS8700_ACTIVE); 372 if (ret) 373 return ret; 374 } 375 376 for (i = 0; i < scale_num; i++) 377 if (fxos8700_accel_scale[i].uscale == uscale) 378 break; 379 380 if (i == scale_num) 381 return -EINVAL; 382 383 ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, 384 fxos8700_accel_scale[i].bits); 385 if (ret) 386 return ret; 387 return regmap_write(data->regmap, FXOS8700_CTRL_REG1, 388 active_mode); 389 } 390 391 static int fxos8700_get_scale(struct fxos8700_data *data, 392 enum fxos8700_sensor t, int *uscale) 393 { 394 int i, ret, val; 395 static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale); 396 397 if (t == FXOS8700_MAGN) { 398 *uscale = 1000; /* Magnetometer is locked at 0.001Gs */ 399 return 0; 400 } 401 402 ret = regmap_read(data->regmap, FXOS8700_XYZ_DATA_CFG, &val); 403 if (ret) 404 return ret; 405 406 for (i = 0; i < scale_num; i++) { 407 if (fxos8700_accel_scale[i].bits == (val & 0x3)) { 408 *uscale = fxos8700_accel_scale[i].uscale; 409 return 0; 410 } 411 } 412 413 return -EINVAL; 414 } 415 416 static int fxos8700_get_data(struct fxos8700_data *data, int chan_type, 417 int axis, int *val) 418 { 419 u8 base, reg; 420 s16 tmp; 421 int ret; 422 423 /* 424 * Different register base addresses varies with channel types. 425 * This bug hasn't been noticed before because using an enum is 426 * really hard to read. Use an a switch statement to take over that. 427 */ 428 switch (chan_type) { 429 case IIO_ACCEL: 430 base = FXOS8700_OUT_X_MSB; 431 break; 432 case IIO_MAGN: 433 base = FXOS8700_M_OUT_X_MSB; 434 break; 435 default: 436 return -EINVAL; 437 } 438 439 /* Block read 6 bytes of device output registers to avoid data loss */ 440 ret = regmap_bulk_read(data->regmap, base, data->buf, 441 sizeof(data->buf)); 442 if (ret) 443 return ret; 444 445 /* Convert axis to buffer index */ 446 reg = axis - IIO_MOD_X; 447 448 /* 449 * Convert to native endianness. The accel data and magn data 450 * are signed, so a forced type conversion is needed. 451 */ 452 tmp = be16_to_cpu(data->buf[reg]); 453 454 /* 455 * ACCEL output data registers contain the X-axis, Y-axis, and Z-axis 456 * 14-bit left-justified sample data and MAGN output data registers 457 * contain the X-axis, Y-axis, and Z-axis 16-bit sample data. Apply 458 * a signed 2 bits right shift to the readback raw data from ACCEL 459 * output data register and keep that from MAGN sensor as the origin. 460 * Value should be extended to 32 bit. 461 */ 462 switch (chan_type) { 463 case IIO_ACCEL: 464 tmp = tmp >> 2; 465 break; 466 case IIO_MAGN: 467 /* Nothing to do */ 468 break; 469 default: 470 return -EINVAL; 471 } 472 473 /* Convert to native endianness */ 474 *val = sign_extend32(tmp, 15); 475 476 return 0; 477 } 478 479 static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t, 480 int odr, int uodr) 481 { 482 int i, ret, val; 483 bool active_mode; 484 static const int odr_num = ARRAY_SIZE(fxos8700_odr); 485 486 ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val); 487 if (ret) 488 return ret; 489 490 active_mode = val & FXOS8700_ACTIVE; 491 492 if (active_mode) { 493 /* 494 * The device must be in standby mode to change any of the 495 * other fields within CTRL_REG1 496 */ 497 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 498 val & ~FXOS8700_ACTIVE); 499 if (ret) 500 return ret; 501 } 502 503 for (i = 0; i < odr_num; i++) 504 if (fxos8700_odr[i].odr == odr && fxos8700_odr[i].uodr == uodr) 505 break; 506 507 if (i >= odr_num) 508 return -EINVAL; 509 510 val &= ~FXOS8700_CTRL_ODR_MSK; 511 val |= FIELD_PREP(FXOS8700_CTRL_ODR_MSK, fxos8700_odr[i].bits) | FXOS8700_ACTIVE; 512 return regmap_write(data->regmap, FXOS8700_CTRL_REG1, val); 513 } 514 515 static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t, 516 int *odr, int *uodr) 517 { 518 int i, val, ret; 519 static const int odr_num = ARRAY_SIZE(fxos8700_odr); 520 521 ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val); 522 if (ret) 523 return ret; 524 525 val = FIELD_GET(FXOS8700_CTRL_ODR_MSK, val); 526 527 for (i = 0; i < odr_num; i++) 528 if (val == fxos8700_odr[i].bits) 529 break; 530 531 if (i >= odr_num) 532 return -EINVAL; 533 534 *odr = fxos8700_odr[i].odr; 535 *uodr = fxos8700_odr[i].uodr; 536 537 return 0; 538 } 539 540 static int fxos8700_read_raw(struct iio_dev *indio_dev, 541 struct iio_chan_spec const *chan, 542 int *val, int *val2, long mask) 543 { 544 int ret; 545 struct fxos8700_data *data = iio_priv(indio_dev); 546 547 switch (mask) { 548 case IIO_CHAN_INFO_RAW: 549 ret = fxos8700_get_data(data, chan->type, chan->channel2, val); 550 if (ret) 551 return ret; 552 return IIO_VAL_INT; 553 case IIO_CHAN_INFO_SCALE: 554 *val = 0; 555 ret = fxos8700_get_scale(data, fxos8700_to_sensor(chan->type), 556 val2); 557 return ret ? ret : IIO_VAL_INT_PLUS_MICRO; 558 case IIO_CHAN_INFO_SAMP_FREQ: 559 ret = fxos8700_get_odr(data, fxos8700_to_sensor(chan->type), 560 val, val2); 561 return ret ? ret : IIO_VAL_INT_PLUS_MICRO; 562 default: 563 return -EINVAL; 564 } 565 } 566 567 static int fxos8700_write_raw(struct iio_dev *indio_dev, 568 struct iio_chan_spec const *chan, 569 int val, int val2, long mask) 570 { 571 struct fxos8700_data *data = iio_priv(indio_dev); 572 573 switch (mask) { 574 case IIO_CHAN_INFO_SCALE: 575 return fxos8700_set_scale(data, fxos8700_to_sensor(chan->type), 576 val2); 577 case IIO_CHAN_INFO_SAMP_FREQ: 578 return fxos8700_set_odr(data, fxos8700_to_sensor(chan->type), 579 val, val2); 580 default: 581 return -EINVAL; 582 } 583 } 584 585 static IIO_CONST_ATTR(in_accel_sampling_frequency_available, 586 "1.5625 6.25 12.5 50 100 200 400 800"); 587 static IIO_CONST_ATTR(in_magn_sampling_frequency_available, 588 "1.5625 6.25 12.5 50 100 200 400 800"); 589 static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976"); 590 static IIO_CONST_ATTR(in_magn_scale_available, "0.001000"); 591 592 static struct attribute *fxos8700_attrs[] = { 593 &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr, 594 &iio_const_attr_in_magn_sampling_frequency_available.dev_attr.attr, 595 &iio_const_attr_in_accel_scale_available.dev_attr.attr, 596 &iio_const_attr_in_magn_scale_available.dev_attr.attr, 597 NULL, 598 }; 599 600 static const struct attribute_group fxos8700_attrs_group = { 601 .attrs = fxos8700_attrs, 602 }; 603 604 static const struct iio_info fxos8700_info = { 605 .read_raw = fxos8700_read_raw, 606 .write_raw = fxos8700_write_raw, 607 .attrs = &fxos8700_attrs_group, 608 }; 609 610 static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi) 611 { 612 int ret; 613 unsigned int val; 614 struct device *dev = regmap_get_device(data->regmap); 615 616 ret = regmap_read(data->regmap, FXOS8700_WHO_AM_I, &val); 617 if (ret) { 618 dev_err(dev, "Error reading chip id\n"); 619 return ret; 620 } 621 if (val != FXOS8700_DEVICE_ID && val != FXOS8700_PRE_DEVICE_ID) { 622 dev_err(dev, "Wrong chip id, got %x expected %x or %x\n", 623 val, FXOS8700_DEVICE_ID, FXOS8700_PRE_DEVICE_ID); 624 return -ENODEV; 625 } 626 627 ret = fxos8700_set_active_mode(data, FXOS8700_ACCEL, true); 628 if (ret) 629 return ret; 630 631 ret = fxos8700_set_active_mode(data, FXOS8700_MAGN, true); 632 if (ret) 633 return ret; 634 635 /* 636 * The device must be in standby mode to change any of the other fields 637 * within CTRL_REG1 638 */ 639 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 0x00); 640 if (ret) 641 return ret; 642 643 /* Set max oversample ratio (OSR) and both devices active */ 644 ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG1, 645 FXOS8700_HMS_MASK | FXOS8700_OS_MASK); 646 if (ret) 647 return ret; 648 649 /* Disable and rst min/max measurements & threshold */ 650 ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG2, 651 FXOS8700_MAXMIN_RST | FXOS8700_MAXMIN_DIS_THS | 652 FXOS8700_MAXMIN_DIS); 653 if (ret) 654 return ret; 655 656 /* 657 * Set max full-scale range (+/-8G) for ACCEL sensor in chip 658 * initialization then activate the device. 659 */ 660 ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G); 661 if (ret) 662 return ret; 663 664 /* Max ODR (800Hz individual or 400Hz hybrid), active mode */ 665 return regmap_update_bits(data->regmap, FXOS8700_CTRL_REG1, 666 FXOS8700_CTRL_ODR_MSK | FXOS8700_ACTIVE, 667 FIELD_PREP(FXOS8700_CTRL_ODR_MSK, FXOS8700_CTRL_ODR_MAX) | 668 FXOS8700_ACTIVE); 669 } 670 671 static void fxos8700_chip_uninit(void *data) 672 { 673 struct fxos8700_data *fxos8700_data = data; 674 675 fxos8700_set_active_mode(fxos8700_data, FXOS8700_ACCEL, false); 676 fxos8700_set_active_mode(fxos8700_data, FXOS8700_MAGN, false); 677 } 678 679 int fxos8700_core_probe(struct device *dev, struct regmap *regmap, 680 const char *name, bool use_spi) 681 { 682 struct iio_dev *indio_dev; 683 struct fxos8700_data *data; 684 int ret; 685 686 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 687 if (!indio_dev) 688 return -ENOMEM; 689 690 data = iio_priv(indio_dev); 691 dev_set_drvdata(dev, indio_dev); 692 data->regmap = regmap; 693 694 ret = fxos8700_chip_init(data, use_spi); 695 if (ret) 696 return ret; 697 698 ret = devm_add_action_or_reset(dev, fxos8700_chip_uninit, data); 699 if (ret) 700 return ret; 701 702 indio_dev->channels = fxos8700_channels; 703 indio_dev->num_channels = ARRAY_SIZE(fxos8700_channels); 704 indio_dev->name = name ? name : "fxos8700"; 705 indio_dev->modes = INDIO_DIRECT_MODE; 706 indio_dev->info = &fxos8700_info; 707 708 return devm_iio_device_register(dev, indio_dev); 709 } 710 EXPORT_SYMBOL_GPL(fxos8700_core_probe); 711 712 MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>"); 713 MODULE_DESCRIPTION("FXOS8700 6-Axis Acc and Mag Combo Sensor driver"); 714 MODULE_LICENSE("GPL v2"); 715