fxos8700_core.c (18179B)
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/acpi.h> 12#include <linux/bitops.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_MSK 0x38 148#define FXOS8700_CTRL_ODR_MAX 0x00 149#define FXOS8700_CTRL_ODR_MIN GENMASK(4, 3) 150 151/* Bit definitions for FXOS8700_M_CTRL_REG1 */ 152#define FXOS8700_HMS_MASK GENMASK(1, 0) 153#define FXOS8700_OS_MASK GENMASK(4, 2) 154 155/* Bit definitions for FXOS8700_M_CTRL_REG2 */ 156#define FXOS8700_MAXMIN_RST BIT(2) 157#define FXOS8700_MAXMIN_DIS_THS BIT(3) 158#define FXOS8700_MAXMIN_DIS BIT(4) 159 160#define FXOS8700_ACTIVE 0x01 161#define FXOS8700_ACTIVE_MIN_USLEEP 4000 /* from table 6 in datasheet */ 162 163#define FXOS8700_DEVICE_ID 0xC7 164#define FXOS8700_PRE_DEVICE_ID 0xC4 165#define FXOS8700_DATA_BUF_SIZE 3 166 167struct fxos8700_data { 168 struct regmap *regmap; 169 struct iio_trigger *trig; 170 __be16 buf[FXOS8700_DATA_BUF_SIZE] ____cacheline_aligned; 171}; 172 173/* Regmap info */ 174static const struct regmap_range read_range[] = { 175 { 176 .range_min = FXOS8700_STATUS, 177 .range_max = FXOS8700_A_FFMT_COUNT, 178 }, { 179 .range_min = FXOS8700_TRANSIENT_CFG, 180 .range_max = FXOS8700_A_FFMT_THS_Z_LSB, 181 }, 182}; 183 184static const struct regmap_range write_range[] = { 185 { 186 .range_min = FXOS8700_F_SETUP, 187 .range_max = FXOS8700_TRIG_CFG, 188 }, { 189 .range_min = FXOS8700_XYZ_DATA_CFG, 190 .range_max = FXOS8700_HP_FILTER_CUTOFF, 191 }, { 192 .range_min = FXOS8700_PL_CFG, 193 .range_max = FXOS8700_A_FFMT_CFG, 194 }, { 195 .range_min = FXOS8700_A_FFMT_THS, 196 .range_max = FXOS8700_TRANSIENT_CFG, 197 }, { 198 .range_min = FXOS8700_TRANSIENT_THS, 199 .range_max = FXOS8700_PULSE_CFG, 200 }, { 201 .range_min = FXOS8700_PULSE_THSX, 202 .range_max = FXOS8700_OFF_Z, 203 }, { 204 .range_min = FXOS8700_M_OFF_X_MSB, 205 .range_max = FXOS8700_M_OFF_Z_LSB, 206 }, { 207 .range_min = FXOS8700_M_THS_CFG, 208 .range_max = FXOS8700_M_THS_CFG, 209 }, { 210 .range_min = FXOS8700_M_THS_X_MSB, 211 .range_max = FXOS8700_M_CTRL_REG3, 212 }, { 213 .range_min = FXOS8700_A_VECM_CFG, 214 .range_max = FXOS8700_A_FFMT_THS_Z_LSB, 215 }, 216}; 217 218static const struct regmap_access_table driver_read_table = { 219 .yes_ranges = read_range, 220 .n_yes_ranges = ARRAY_SIZE(read_range), 221}; 222 223static const struct regmap_access_table driver_write_table = { 224 .yes_ranges = write_range, 225 .n_yes_ranges = ARRAY_SIZE(write_range), 226}; 227 228const struct regmap_config fxos8700_regmap_config = { 229 .reg_bits = 8, 230 .val_bits = 8, 231 .max_register = FXOS8700_NVM_DATA_BNK0, 232 .rd_table = &driver_read_table, 233 .wr_table = &driver_write_table, 234}; 235EXPORT_SYMBOL(fxos8700_regmap_config); 236 237#define FXOS8700_CHANNEL(_type, _axis) { \ 238 .type = _type, \ 239 .modified = 1, \ 240 .channel2 = IIO_MOD_##_axis, \ 241 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 242 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 243 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 244} 245 246enum fxos8700_accel_scale_bits { 247 MODE_2G = 0, 248 MODE_4G, 249 MODE_8G, 250}; 251 252/* scan indexes follow DATA register order */ 253enum fxos8700_scan_axis { 254 FXOS8700_SCAN_ACCEL_X = 0, 255 FXOS8700_SCAN_ACCEL_Y, 256 FXOS8700_SCAN_ACCEL_Z, 257 FXOS8700_SCAN_MAGN_X, 258 FXOS8700_SCAN_MAGN_Y, 259 FXOS8700_SCAN_MAGN_Z, 260 FXOS8700_SCAN_RHALL, 261 FXOS8700_SCAN_TIMESTAMP, 262}; 263 264enum fxos8700_sensor { 265 FXOS8700_ACCEL = 0, 266 FXOS8700_MAGN, 267 FXOS8700_NUM_SENSORS /* must be last */ 268}; 269 270enum fxos8700_int_pin { 271 FXOS8700_PIN_INT1, 272 FXOS8700_PIN_INT2 273}; 274 275struct fxos8700_scale { 276 u8 bits; 277 int uscale; 278}; 279 280struct fxos8700_odr { 281 u8 bits; 282 int odr; 283 int uodr; 284}; 285 286static const struct fxos8700_scale fxos8700_accel_scale[] = { 287 { MODE_2G, 244}, 288 { MODE_4G, 488}, 289 { MODE_8G, 976}, 290}; 291 292/* 293 * Accellerometer and magnetometer have the same ODR options, set in the 294 * CTRL_REG1 register. ODR is halved when using both sensors at once in 295 * hybrid mode. 296 */ 297static const struct fxos8700_odr fxos8700_odr[] = { 298 {0x00, 800, 0}, 299 {0x01, 400, 0}, 300 {0x02, 200, 0}, 301 {0x03, 100, 0}, 302 {0x04, 50, 0}, 303 {0x05, 12, 500000}, 304 {0x06, 6, 250000}, 305 {0x07, 1, 562500}, 306}; 307 308static const struct iio_chan_spec fxos8700_channels[] = { 309 FXOS8700_CHANNEL(IIO_ACCEL, X), 310 FXOS8700_CHANNEL(IIO_ACCEL, Y), 311 FXOS8700_CHANNEL(IIO_ACCEL, Z), 312 FXOS8700_CHANNEL(IIO_MAGN, X), 313 FXOS8700_CHANNEL(IIO_MAGN, Y), 314 FXOS8700_CHANNEL(IIO_MAGN, Z), 315 IIO_CHAN_SOFT_TIMESTAMP(FXOS8700_SCAN_TIMESTAMP), 316}; 317 318static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type) 319{ 320 switch (iio_type) { 321 case IIO_ACCEL: 322 return FXOS8700_ACCEL; 323 case IIO_ANGL_VEL: 324 return FXOS8700_MAGN; 325 default: 326 return -EINVAL; 327 } 328} 329 330static int fxos8700_set_active_mode(struct fxos8700_data *data, 331 enum fxos8700_sensor t, bool mode) 332{ 333 int ret; 334 335 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, mode); 336 if (ret) 337 return ret; 338 339 usleep_range(FXOS8700_ACTIVE_MIN_USLEEP, 340 FXOS8700_ACTIVE_MIN_USLEEP + 1000); 341 342 return 0; 343} 344 345static int fxos8700_set_scale(struct fxos8700_data *data, 346 enum fxos8700_sensor t, int uscale) 347{ 348 int i; 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 1200uT\n"); 354 return -EINVAL; 355 } 356 357 for (i = 0; i < scale_num; i++) 358 if (fxos8700_accel_scale[i].uscale == uscale) 359 break; 360 361 if (i == scale_num) 362 return -EINVAL; 363 364 return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, 365 fxos8700_accel_scale[i].bits); 366} 367 368static int fxos8700_get_scale(struct fxos8700_data *data, 369 enum fxos8700_sensor t, int *uscale) 370{ 371 int i, ret, val; 372 static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale); 373 374 if (t == FXOS8700_MAGN) { 375 *uscale = 1200; /* Magnetometer is locked at 1200uT */ 376 return 0; 377 } 378 379 ret = regmap_read(data->regmap, FXOS8700_XYZ_DATA_CFG, &val); 380 if (ret) 381 return ret; 382 383 for (i = 0; i < scale_num; i++) { 384 if (fxos8700_accel_scale[i].bits == (val & 0x3)) { 385 *uscale = fxos8700_accel_scale[i].uscale; 386 return 0; 387 } 388 } 389 390 return -EINVAL; 391} 392 393static int fxos8700_get_data(struct fxos8700_data *data, int chan_type, 394 int axis, int *val) 395{ 396 u8 base, reg; 397 int ret; 398 enum fxos8700_sensor type = fxos8700_to_sensor(chan_type); 399 400 base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB; 401 402 /* Block read 6 bytes of device output registers to avoid data loss */ 403 ret = regmap_bulk_read(data->regmap, base, data->buf, 404 FXOS8700_DATA_BUF_SIZE); 405 if (ret) 406 return ret; 407 408 /* Convert axis to buffer index */ 409 reg = axis - IIO_MOD_X; 410 411 /* Convert to native endianness */ 412 *val = sign_extend32(be16_to_cpu(data->buf[reg]), 15); 413 414 return 0; 415} 416 417static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t, 418 int odr, int uodr) 419{ 420 int i, ret, val; 421 bool active_mode; 422 static const int odr_num = ARRAY_SIZE(fxos8700_odr); 423 424 ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val); 425 if (ret) 426 return ret; 427 428 active_mode = val & FXOS8700_ACTIVE; 429 430 if (active_mode) { 431 /* 432 * The device must be in standby mode to change any of the 433 * other fields within CTRL_REG1 434 */ 435 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 436 val & ~FXOS8700_ACTIVE); 437 if (ret) 438 return ret; 439 } 440 441 for (i = 0; i < odr_num; i++) 442 if (fxos8700_odr[i].odr == odr && fxos8700_odr[i].uodr == uodr) 443 break; 444 445 if (i >= odr_num) 446 return -EINVAL; 447 448 return regmap_update_bits(data->regmap, 449 FXOS8700_CTRL_REG1, 450 FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE, 451 fxos8700_odr[i].bits << 3 | active_mode); 452} 453 454static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t, 455 int *odr, int *uodr) 456{ 457 int i, val, ret; 458 static const int odr_num = ARRAY_SIZE(fxos8700_odr); 459 460 ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val); 461 if (ret) 462 return ret; 463 464 val &= FXOS8700_CTRL_ODR_MSK; 465 466 for (i = 0; i < odr_num; i++) 467 if (val == fxos8700_odr[i].bits) 468 break; 469 470 if (i >= odr_num) 471 return -EINVAL; 472 473 *odr = fxos8700_odr[i].odr; 474 *uodr = fxos8700_odr[i].uodr; 475 476 return 0; 477} 478 479static int fxos8700_read_raw(struct iio_dev *indio_dev, 480 struct iio_chan_spec const *chan, 481 int *val, int *val2, long mask) 482{ 483 int ret; 484 struct fxos8700_data *data = iio_priv(indio_dev); 485 486 switch (mask) { 487 case IIO_CHAN_INFO_RAW: 488 ret = fxos8700_get_data(data, chan->type, chan->channel2, val); 489 if (ret) 490 return ret; 491 return IIO_VAL_INT; 492 case IIO_CHAN_INFO_SCALE: 493 *val = 0; 494 ret = fxos8700_get_scale(data, fxos8700_to_sensor(chan->type), 495 val2); 496 return ret ? ret : IIO_VAL_INT_PLUS_MICRO; 497 case IIO_CHAN_INFO_SAMP_FREQ: 498 ret = fxos8700_get_odr(data, fxos8700_to_sensor(chan->type), 499 val, val2); 500 return ret ? ret : IIO_VAL_INT_PLUS_MICRO; 501 default: 502 return -EINVAL; 503 } 504} 505 506static int fxos8700_write_raw(struct iio_dev *indio_dev, 507 struct iio_chan_spec const *chan, 508 int val, int val2, long mask) 509{ 510 struct fxos8700_data *data = iio_priv(indio_dev); 511 512 switch (mask) { 513 case IIO_CHAN_INFO_SCALE: 514 return fxos8700_set_scale(data, fxos8700_to_sensor(chan->type), 515 val2); 516 case IIO_CHAN_INFO_SAMP_FREQ: 517 return fxos8700_set_odr(data, fxos8700_to_sensor(chan->type), 518 val, val2); 519 default: 520 return -EINVAL; 521 } 522} 523 524static IIO_CONST_ATTR(in_accel_sampling_frequency_available, 525 "1.5625 6.25 12.5 50 100 200 400 800"); 526static IIO_CONST_ATTR(in_magn_sampling_frequency_available, 527 "1.5625 6.25 12.5 50 100 200 400 800"); 528static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976"); 529static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200"); 530 531static struct attribute *fxos8700_attrs[] = { 532 &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr, 533 &iio_const_attr_in_magn_sampling_frequency_available.dev_attr.attr, 534 &iio_const_attr_in_accel_scale_available.dev_attr.attr, 535 &iio_const_attr_in_magn_scale_available.dev_attr.attr, 536 NULL, 537}; 538 539static const struct attribute_group fxos8700_attrs_group = { 540 .attrs = fxos8700_attrs, 541}; 542 543static const struct iio_info fxos8700_info = { 544 .read_raw = fxos8700_read_raw, 545 .write_raw = fxos8700_write_raw, 546 .attrs = &fxos8700_attrs_group, 547}; 548 549static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi) 550{ 551 int ret; 552 unsigned int val; 553 struct device *dev = regmap_get_device(data->regmap); 554 555 ret = regmap_read(data->regmap, FXOS8700_WHO_AM_I, &val); 556 if (ret) { 557 dev_err(dev, "Error reading chip id\n"); 558 return ret; 559 } 560 if (val != FXOS8700_DEVICE_ID && val != FXOS8700_PRE_DEVICE_ID) { 561 dev_err(dev, "Wrong chip id, got %x expected %x or %x\n", 562 val, FXOS8700_DEVICE_ID, FXOS8700_PRE_DEVICE_ID); 563 return -ENODEV; 564 } 565 566 ret = fxos8700_set_active_mode(data, FXOS8700_ACCEL, true); 567 if (ret) 568 return ret; 569 570 ret = fxos8700_set_active_mode(data, FXOS8700_MAGN, true); 571 if (ret) 572 return ret; 573 574 /* 575 * The device must be in standby mode to change any of the other fields 576 * within CTRL_REG1 577 */ 578 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 0x00); 579 if (ret) 580 return ret; 581 582 /* Set max oversample ratio (OSR) and both devices active */ 583 ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG1, 584 FXOS8700_HMS_MASK | FXOS8700_OS_MASK); 585 if (ret) 586 return ret; 587 588 /* Disable and rst min/max measurements & threshold */ 589 ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG2, 590 FXOS8700_MAXMIN_RST | FXOS8700_MAXMIN_DIS_THS | 591 FXOS8700_MAXMIN_DIS); 592 if (ret) 593 return ret; 594 595 /* Max ODR (800Hz individual or 400Hz hybrid), active mode */ 596 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 597 FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE); 598 if (ret) 599 return ret; 600 601 /* Set for max full-scale range (+/-8G) */ 602 return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G); 603} 604 605static void fxos8700_chip_uninit(void *data) 606{ 607 struct fxos8700_data *fxos8700_data = data; 608 609 fxos8700_set_active_mode(fxos8700_data, FXOS8700_ACCEL, false); 610 fxos8700_set_active_mode(fxos8700_data, FXOS8700_MAGN, false); 611} 612 613int fxos8700_core_probe(struct device *dev, struct regmap *regmap, 614 const char *name, bool use_spi) 615{ 616 struct iio_dev *indio_dev; 617 struct fxos8700_data *data; 618 int ret; 619 620 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 621 if (!indio_dev) 622 return -ENOMEM; 623 624 data = iio_priv(indio_dev); 625 dev_set_drvdata(dev, indio_dev); 626 data->regmap = regmap; 627 628 ret = fxos8700_chip_init(data, use_spi); 629 if (ret) 630 return ret; 631 632 ret = devm_add_action_or_reset(dev, fxos8700_chip_uninit, data); 633 if (ret) 634 return ret; 635 636 indio_dev->channels = fxos8700_channels; 637 indio_dev->num_channels = ARRAY_SIZE(fxos8700_channels); 638 indio_dev->name = name ? name : "fxos8700"; 639 indio_dev->modes = INDIO_DIRECT_MODE; 640 indio_dev->info = &fxos8700_info; 641 642 return devm_iio_device_register(dev, indio_dev); 643} 644EXPORT_SYMBOL_GPL(fxos8700_core_probe); 645 646MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>"); 647MODULE_DESCRIPTION("FXOS8700 6-Axis Acc and Mag Combo Sensor driver"); 648MODULE_LICENSE("GPL v2");