0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/regmap.h>
0011 #include <linux/acpi.h>
0012 #include <linux/bitops.h>
0013
0014 #include <linux/iio/iio.h>
0015 #include <linux/iio/sysfs.h>
0016
0017 #include "fxos8700.h"
0018
0019
0020 #define FXOS8700_STATUS 0x00
0021 #define FXOS8700_OUT_X_MSB 0x01
0022 #define FXOS8700_OUT_X_LSB 0x02
0023 #define FXOS8700_OUT_Y_MSB 0x03
0024 #define FXOS8700_OUT_Y_LSB 0x04
0025 #define FXOS8700_OUT_Z_MSB 0x05
0026 #define FXOS8700_OUT_Z_LSB 0x06
0027 #define FXOS8700_F_SETUP 0x09
0028 #define FXOS8700_TRIG_CFG 0x0a
0029 #define FXOS8700_SYSMOD 0x0b
0030 #define FXOS8700_INT_SOURCE 0x0c
0031 #define FXOS8700_WHO_AM_I 0x0d
0032 #define FXOS8700_XYZ_DATA_CFG 0x0e
0033 #define FXOS8700_HP_FILTER_CUTOFF 0x0f
0034 #define FXOS8700_PL_STATUS 0x10
0035 #define FXOS8700_PL_CFG 0x11
0036 #define FXOS8700_PL_COUNT 0x12
0037 #define FXOS8700_PL_BF_ZCOMP 0x13
0038 #define FXOS8700_PL_THS_REG 0x14
0039 #define FXOS8700_A_FFMT_CFG 0x15
0040 #define FXOS8700_A_FFMT_SRC 0x16
0041 #define FXOS8700_A_FFMT_THS 0x17
0042 #define FXOS8700_A_FFMT_COUNT 0x18
0043 #define FXOS8700_TRANSIENT_CFG 0x1d
0044 #define FXOS8700_TRANSIENT_SRC 0x1e
0045 #define FXOS8700_TRANSIENT_THS 0x1f
0046 #define FXOS8700_TRANSIENT_COUNT 0x20
0047 #define FXOS8700_PULSE_CFG 0x21
0048 #define FXOS8700_PULSE_SRC 0x22
0049 #define FXOS8700_PULSE_THSX 0x23
0050 #define FXOS8700_PULSE_THSY 0x24
0051 #define FXOS8700_PULSE_THSZ 0x25
0052 #define FXOS8700_PULSE_TMLT 0x26
0053 #define FXOS8700_PULSE_LTCY 0x27
0054 #define FXOS8700_PULSE_WIND 0x28
0055 #define FXOS8700_ASLP_COUNT 0x29
0056 #define FXOS8700_CTRL_REG1 0x2a
0057 #define FXOS8700_CTRL_REG2 0x2b
0058 #define FXOS8700_CTRL_REG3 0x2c
0059 #define FXOS8700_CTRL_REG4 0x2d
0060 #define FXOS8700_CTRL_REG5 0x2e
0061 #define FXOS8700_OFF_X 0x2f
0062 #define FXOS8700_OFF_Y 0x30
0063 #define FXOS8700_OFF_Z 0x31
0064 #define FXOS8700_M_DR_STATUS 0x32
0065 #define FXOS8700_M_OUT_X_MSB 0x33
0066 #define FXOS8700_M_OUT_X_LSB 0x34
0067 #define FXOS8700_M_OUT_Y_MSB 0x35
0068 #define FXOS8700_M_OUT_Y_LSB 0x36
0069 #define FXOS8700_M_OUT_Z_MSB 0x37
0070 #define FXOS8700_M_OUT_Z_LSB 0x38
0071 #define FXOS8700_CMP_X_MSB 0x39
0072 #define FXOS8700_CMP_X_LSB 0x3a
0073 #define FXOS8700_CMP_Y_MSB 0x3b
0074 #define FXOS8700_CMP_Y_LSB 0x3c
0075 #define FXOS8700_CMP_Z_MSB 0x3d
0076 #define FXOS8700_CMP_Z_LSB 0x3e
0077 #define FXOS8700_M_OFF_X_MSB 0x3f
0078 #define FXOS8700_M_OFF_X_LSB 0x40
0079 #define FXOS8700_M_OFF_Y_MSB 0x41
0080 #define FXOS8700_M_OFF_Y_LSB 0x42
0081 #define FXOS8700_M_OFF_Z_MSB 0x43
0082 #define FXOS8700_M_OFF_Z_LSB 0x44
0083 #define FXOS8700_MAX_X_MSB 0x45
0084 #define FXOS8700_MAX_X_LSB 0x46
0085 #define FXOS8700_MAX_Y_MSB 0x47
0086 #define FXOS8700_MAX_Y_LSB 0x48
0087 #define FXOS8700_MAX_Z_MSB 0x49
0088 #define FXOS8700_MAX_Z_LSB 0x4a
0089 #define FXOS8700_MIN_X_MSB 0x4b
0090 #define FXOS8700_MIN_X_LSB 0x4c
0091 #define FXOS8700_MIN_Y_MSB 0x4d
0092 #define FXOS8700_MIN_Y_LSB 0x4e
0093 #define FXOS8700_MIN_Z_MSB 0x4f
0094 #define FXOS8700_MIN_Z_LSB 0x50
0095 #define FXOS8700_TEMP 0x51
0096 #define FXOS8700_M_THS_CFG 0x52
0097 #define FXOS8700_M_THS_SRC 0x53
0098 #define FXOS8700_M_THS_X_MSB 0x54
0099 #define FXOS8700_M_THS_X_LSB 0x55
0100 #define FXOS8700_M_THS_Y_MSB 0x56
0101 #define FXOS8700_M_THS_Y_LSB 0x57
0102 #define FXOS8700_M_THS_Z_MSB 0x58
0103 #define FXOS8700_M_THS_Z_LSB 0x59
0104 #define FXOS8700_M_THS_COUNT 0x5a
0105 #define FXOS8700_M_CTRL_REG1 0x5b
0106 #define FXOS8700_M_CTRL_REG2 0x5c
0107 #define FXOS8700_M_CTRL_REG3 0x5d
0108 #define FXOS8700_M_INT_SRC 0x5e
0109 #define FXOS8700_A_VECM_CFG 0x5f
0110 #define FXOS8700_A_VECM_THS_MSB 0x60
0111 #define FXOS8700_A_VECM_THS_LSB 0x61
0112 #define FXOS8700_A_VECM_CNT 0x62
0113 #define FXOS8700_A_VECM_INITX_MSB 0x63
0114 #define FXOS8700_A_VECM_INITX_LSB 0x64
0115 #define FXOS8700_A_VECM_INITY_MSB 0x65
0116 #define FXOS8700_A_VECM_INITY_LSB 0x66
0117 #define FXOS8700_A_VECM_INITZ_MSB 0x67
0118 #define FXOS8700_A_VECM_INITZ_LSB 0x68
0119 #define FXOS8700_M_VECM_CFG 0x69
0120 #define FXOS8700_M_VECM_THS_MSB 0x6a
0121 #define FXOS8700_M_VECM_THS_LSB 0x6b
0122 #define FXOS8700_M_VECM_CNT 0x6c
0123 #define FXOS8700_M_VECM_INITX_MSB 0x6d
0124 #define FXOS8700_M_VECM_INITX_LSB 0x6e
0125 #define FXOS8700_M_VECM_INITY_MSB 0x6f
0126 #define FXOS8700_M_VECM_INITY_LSB 0x70
0127 #define FXOS8700_M_VECM_INITZ_MSB 0x71
0128 #define FXOS8700_M_VECM_INITZ_LSB 0x72
0129 #define FXOS8700_A_FFMT_THS_X_MSB 0x73
0130 #define FXOS8700_A_FFMT_THS_X_LSB 0x74
0131 #define FXOS8700_A_FFMT_THS_Y_MSB 0x75
0132 #define FXOS8700_A_FFMT_THS_Y_LSB 0x76
0133 #define FXOS8700_A_FFMT_THS_Z_MSB 0x77
0134 #define FXOS8700_A_FFMT_THS_Z_LSB 0x78
0135 #define FXOS8700_A_TRAN_INIT_MSB 0x79
0136 #define FXOS8700_A_TRAN_INIT_LSB_X 0x7a
0137 #define FXOS8700_A_TRAN_INIT_LSB_Y 0x7b
0138 #define FXOS8700_A_TRAN_INIT_LSB_Z 0x7d
0139 #define FXOS8700_TM_NVM_LOCK 0x7e
0140 #define FXOS8700_NVM_DATA0_35 0x80
0141 #define FXOS8700_NVM_DATA_BNK3 0xa4
0142 #define FXOS8700_NVM_DATA_BNK2 0xa5
0143 #define FXOS8700_NVM_DATA_BNK1 0xa6
0144 #define FXOS8700_NVM_DATA_BNK0 0xa7
0145
0146
0147 #define FXOS8700_CTRL_ODR_MSK 0x38
0148 #define FXOS8700_CTRL_ODR_MAX 0x00
0149 #define FXOS8700_CTRL_ODR_MIN GENMASK(4, 3)
0150
0151
0152 #define FXOS8700_HMS_MASK GENMASK(1, 0)
0153 #define FXOS8700_OS_MASK GENMASK(4, 2)
0154
0155
0156 #define FXOS8700_MAXMIN_RST BIT(2)
0157 #define FXOS8700_MAXMIN_DIS_THS BIT(3)
0158 #define FXOS8700_MAXMIN_DIS BIT(4)
0159
0160 #define FXOS8700_ACTIVE 0x01
0161 #define FXOS8700_ACTIVE_MIN_USLEEP 4000
0162
0163 #define FXOS8700_DEVICE_ID 0xC7
0164 #define FXOS8700_PRE_DEVICE_ID 0xC4
0165 #define FXOS8700_DATA_BUF_SIZE 3
0166
0167 struct fxos8700_data {
0168 struct regmap *regmap;
0169 struct iio_trigger *trig;
0170 __be16 buf[FXOS8700_DATA_BUF_SIZE] __aligned(IIO_DMA_MINALIGN);
0171 };
0172
0173
0174 static const struct regmap_range read_range[] = {
0175 {
0176 .range_min = FXOS8700_STATUS,
0177 .range_max = FXOS8700_A_FFMT_COUNT,
0178 }, {
0179 .range_min = FXOS8700_TRANSIENT_CFG,
0180 .range_max = FXOS8700_A_FFMT_THS_Z_LSB,
0181 },
0182 };
0183
0184 static const struct regmap_range write_range[] = {
0185 {
0186 .range_min = FXOS8700_F_SETUP,
0187 .range_max = FXOS8700_TRIG_CFG,
0188 }, {
0189 .range_min = FXOS8700_XYZ_DATA_CFG,
0190 .range_max = FXOS8700_HP_FILTER_CUTOFF,
0191 }, {
0192 .range_min = FXOS8700_PL_CFG,
0193 .range_max = FXOS8700_A_FFMT_CFG,
0194 }, {
0195 .range_min = FXOS8700_A_FFMT_THS,
0196 .range_max = FXOS8700_TRANSIENT_CFG,
0197 }, {
0198 .range_min = FXOS8700_TRANSIENT_THS,
0199 .range_max = FXOS8700_PULSE_CFG,
0200 }, {
0201 .range_min = FXOS8700_PULSE_THSX,
0202 .range_max = FXOS8700_OFF_Z,
0203 }, {
0204 .range_min = FXOS8700_M_OFF_X_MSB,
0205 .range_max = FXOS8700_M_OFF_Z_LSB,
0206 }, {
0207 .range_min = FXOS8700_M_THS_CFG,
0208 .range_max = FXOS8700_M_THS_CFG,
0209 }, {
0210 .range_min = FXOS8700_M_THS_X_MSB,
0211 .range_max = FXOS8700_M_CTRL_REG3,
0212 }, {
0213 .range_min = FXOS8700_A_VECM_CFG,
0214 .range_max = FXOS8700_A_FFMT_THS_Z_LSB,
0215 },
0216 };
0217
0218 static const struct regmap_access_table driver_read_table = {
0219 .yes_ranges = read_range,
0220 .n_yes_ranges = ARRAY_SIZE(read_range),
0221 };
0222
0223 static const struct regmap_access_table driver_write_table = {
0224 .yes_ranges = write_range,
0225 .n_yes_ranges = ARRAY_SIZE(write_range),
0226 };
0227
0228 const struct regmap_config fxos8700_regmap_config = {
0229 .reg_bits = 8,
0230 .val_bits = 8,
0231 .max_register = FXOS8700_NVM_DATA_BNK0,
0232 .rd_table = &driver_read_table,
0233 .wr_table = &driver_write_table,
0234 };
0235 EXPORT_SYMBOL(fxos8700_regmap_config);
0236
0237 #define FXOS8700_CHANNEL(_type, _axis) { \
0238 .type = _type, \
0239 .modified = 1, \
0240 .channel2 = IIO_MOD_##_axis, \
0241 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
0242 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
0243 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
0244 }
0245
0246 enum fxos8700_accel_scale_bits {
0247 MODE_2G = 0,
0248 MODE_4G,
0249 MODE_8G,
0250 };
0251
0252
0253 enum fxos8700_scan_axis {
0254 FXOS8700_SCAN_ACCEL_X = 0,
0255 FXOS8700_SCAN_ACCEL_Y,
0256 FXOS8700_SCAN_ACCEL_Z,
0257 FXOS8700_SCAN_MAGN_X,
0258 FXOS8700_SCAN_MAGN_Y,
0259 FXOS8700_SCAN_MAGN_Z,
0260 FXOS8700_SCAN_RHALL,
0261 FXOS8700_SCAN_TIMESTAMP,
0262 };
0263
0264 enum fxos8700_sensor {
0265 FXOS8700_ACCEL = 0,
0266 FXOS8700_MAGN,
0267 FXOS8700_NUM_SENSORS
0268 };
0269
0270 enum fxos8700_int_pin {
0271 FXOS8700_PIN_INT1,
0272 FXOS8700_PIN_INT2
0273 };
0274
0275 struct fxos8700_scale {
0276 u8 bits;
0277 int uscale;
0278 };
0279
0280 struct fxos8700_odr {
0281 u8 bits;
0282 int odr;
0283 int uodr;
0284 };
0285
0286 static const struct fxos8700_scale fxos8700_accel_scale[] = {
0287 { MODE_2G, 244},
0288 { MODE_4G, 488},
0289 { MODE_8G, 976},
0290 };
0291
0292
0293
0294
0295
0296
0297 static const struct fxos8700_odr fxos8700_odr[] = {
0298 {0x00, 800, 0},
0299 {0x01, 400, 0},
0300 {0x02, 200, 0},
0301 {0x03, 100, 0},
0302 {0x04, 50, 0},
0303 {0x05, 12, 500000},
0304 {0x06, 6, 250000},
0305 {0x07, 1, 562500},
0306 };
0307
0308 static const struct iio_chan_spec fxos8700_channels[] = {
0309 FXOS8700_CHANNEL(IIO_ACCEL, X),
0310 FXOS8700_CHANNEL(IIO_ACCEL, Y),
0311 FXOS8700_CHANNEL(IIO_ACCEL, Z),
0312 FXOS8700_CHANNEL(IIO_MAGN, X),
0313 FXOS8700_CHANNEL(IIO_MAGN, Y),
0314 FXOS8700_CHANNEL(IIO_MAGN, Z),
0315 IIO_CHAN_SOFT_TIMESTAMP(FXOS8700_SCAN_TIMESTAMP),
0316 };
0317
0318 static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type)
0319 {
0320 switch (iio_type) {
0321 case IIO_ACCEL:
0322 return FXOS8700_ACCEL;
0323 case IIO_ANGL_VEL:
0324 return FXOS8700_MAGN;
0325 default:
0326 return -EINVAL;
0327 }
0328 }
0329
0330 static int fxos8700_set_active_mode(struct fxos8700_data *data,
0331 enum fxos8700_sensor t, bool mode)
0332 {
0333 int ret;
0334
0335 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, mode);
0336 if (ret)
0337 return ret;
0338
0339 usleep_range(FXOS8700_ACTIVE_MIN_USLEEP,
0340 FXOS8700_ACTIVE_MIN_USLEEP + 1000);
0341
0342 return 0;
0343 }
0344
0345 static int fxos8700_set_scale(struct fxos8700_data *data,
0346 enum fxos8700_sensor t, int uscale)
0347 {
0348 int i;
0349 static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
0350 struct device *dev = regmap_get_device(data->regmap);
0351
0352 if (t == FXOS8700_MAGN) {
0353 dev_err(dev, "Magnetometer scale is locked at 1200uT\n");
0354 return -EINVAL;
0355 }
0356
0357 for (i = 0; i < scale_num; i++)
0358 if (fxos8700_accel_scale[i].uscale == uscale)
0359 break;
0360
0361 if (i == scale_num)
0362 return -EINVAL;
0363
0364 return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
0365 fxos8700_accel_scale[i].bits);
0366 }
0367
0368 static int fxos8700_get_scale(struct fxos8700_data *data,
0369 enum fxos8700_sensor t, int *uscale)
0370 {
0371 int i, ret, val;
0372 static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
0373
0374 if (t == FXOS8700_MAGN) {
0375 *uscale = 1200;
0376 return 0;
0377 }
0378
0379 ret = regmap_read(data->regmap, FXOS8700_XYZ_DATA_CFG, &val);
0380 if (ret)
0381 return ret;
0382
0383 for (i = 0; i < scale_num; i++) {
0384 if (fxos8700_accel_scale[i].bits == (val & 0x3)) {
0385 *uscale = fxos8700_accel_scale[i].uscale;
0386 return 0;
0387 }
0388 }
0389
0390 return -EINVAL;
0391 }
0392
0393 static int fxos8700_get_data(struct fxos8700_data *data, int chan_type,
0394 int axis, int *val)
0395 {
0396 u8 base, reg;
0397 int ret;
0398 enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
0399
0400 base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB;
0401
0402
0403 ret = regmap_bulk_read(data->regmap, base, data->buf,
0404 FXOS8700_DATA_BUF_SIZE);
0405 if (ret)
0406 return ret;
0407
0408
0409 reg = axis - IIO_MOD_X;
0410
0411
0412 *val = sign_extend32(be16_to_cpu(data->buf[reg]), 15);
0413
0414 return 0;
0415 }
0416
0417 static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
0418 int odr, int uodr)
0419 {
0420 int i, ret, val;
0421 bool active_mode;
0422 static const int odr_num = ARRAY_SIZE(fxos8700_odr);
0423
0424 ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
0425 if (ret)
0426 return ret;
0427
0428 active_mode = val & FXOS8700_ACTIVE;
0429
0430 if (active_mode) {
0431
0432
0433
0434
0435 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
0436 val & ~FXOS8700_ACTIVE);
0437 if (ret)
0438 return ret;
0439 }
0440
0441 for (i = 0; i < odr_num; i++)
0442 if (fxos8700_odr[i].odr == odr && fxos8700_odr[i].uodr == uodr)
0443 break;
0444
0445 if (i >= odr_num)
0446 return -EINVAL;
0447
0448 return regmap_update_bits(data->regmap,
0449 FXOS8700_CTRL_REG1,
0450 FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE,
0451 fxos8700_odr[i].bits << 3 | active_mode);
0452 }
0453
0454 static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
0455 int *odr, int *uodr)
0456 {
0457 int i, val, ret;
0458 static const int odr_num = ARRAY_SIZE(fxos8700_odr);
0459
0460 ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
0461 if (ret)
0462 return ret;
0463
0464 val &= FXOS8700_CTRL_ODR_MSK;
0465
0466 for (i = 0; i < odr_num; i++)
0467 if (val == fxos8700_odr[i].bits)
0468 break;
0469
0470 if (i >= odr_num)
0471 return -EINVAL;
0472
0473 *odr = fxos8700_odr[i].odr;
0474 *uodr = fxos8700_odr[i].uodr;
0475
0476 return 0;
0477 }
0478
0479 static int fxos8700_read_raw(struct iio_dev *indio_dev,
0480 struct iio_chan_spec const *chan,
0481 int *val, int *val2, long mask)
0482 {
0483 int ret;
0484 struct fxos8700_data *data = iio_priv(indio_dev);
0485
0486 switch (mask) {
0487 case IIO_CHAN_INFO_RAW:
0488 ret = fxos8700_get_data(data, chan->type, chan->channel2, val);
0489 if (ret)
0490 return ret;
0491 return IIO_VAL_INT;
0492 case IIO_CHAN_INFO_SCALE:
0493 *val = 0;
0494 ret = fxos8700_get_scale(data, fxos8700_to_sensor(chan->type),
0495 val2);
0496 return ret ? ret : IIO_VAL_INT_PLUS_MICRO;
0497 case IIO_CHAN_INFO_SAMP_FREQ:
0498 ret = fxos8700_get_odr(data, fxos8700_to_sensor(chan->type),
0499 val, val2);
0500 return ret ? ret : IIO_VAL_INT_PLUS_MICRO;
0501 default:
0502 return -EINVAL;
0503 }
0504 }
0505
0506 static int fxos8700_write_raw(struct iio_dev *indio_dev,
0507 struct iio_chan_spec const *chan,
0508 int val, int val2, long mask)
0509 {
0510 struct fxos8700_data *data = iio_priv(indio_dev);
0511
0512 switch (mask) {
0513 case IIO_CHAN_INFO_SCALE:
0514 return fxos8700_set_scale(data, fxos8700_to_sensor(chan->type),
0515 val2);
0516 case IIO_CHAN_INFO_SAMP_FREQ:
0517 return fxos8700_set_odr(data, fxos8700_to_sensor(chan->type),
0518 val, val2);
0519 default:
0520 return -EINVAL;
0521 }
0522 }
0523
0524 static IIO_CONST_ATTR(in_accel_sampling_frequency_available,
0525 "1.5625 6.25 12.5 50 100 200 400 800");
0526 static IIO_CONST_ATTR(in_magn_sampling_frequency_available,
0527 "1.5625 6.25 12.5 50 100 200 400 800");
0528 static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976");
0529 static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200");
0530
0531 static struct attribute *fxos8700_attrs[] = {
0532 &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
0533 &iio_const_attr_in_magn_sampling_frequency_available.dev_attr.attr,
0534 &iio_const_attr_in_accel_scale_available.dev_attr.attr,
0535 &iio_const_attr_in_magn_scale_available.dev_attr.attr,
0536 NULL,
0537 };
0538
0539 static const struct attribute_group fxos8700_attrs_group = {
0540 .attrs = fxos8700_attrs,
0541 };
0542
0543 static const struct iio_info fxos8700_info = {
0544 .read_raw = fxos8700_read_raw,
0545 .write_raw = fxos8700_write_raw,
0546 .attrs = &fxos8700_attrs_group,
0547 };
0548
0549 static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi)
0550 {
0551 int ret;
0552 unsigned int val;
0553 struct device *dev = regmap_get_device(data->regmap);
0554
0555 ret = regmap_read(data->regmap, FXOS8700_WHO_AM_I, &val);
0556 if (ret) {
0557 dev_err(dev, "Error reading chip id\n");
0558 return ret;
0559 }
0560 if (val != FXOS8700_DEVICE_ID && val != FXOS8700_PRE_DEVICE_ID) {
0561 dev_err(dev, "Wrong chip id, got %x expected %x or %x\n",
0562 val, FXOS8700_DEVICE_ID, FXOS8700_PRE_DEVICE_ID);
0563 return -ENODEV;
0564 }
0565
0566 ret = fxos8700_set_active_mode(data, FXOS8700_ACCEL, true);
0567 if (ret)
0568 return ret;
0569
0570 ret = fxos8700_set_active_mode(data, FXOS8700_MAGN, true);
0571 if (ret)
0572 return ret;
0573
0574
0575
0576
0577
0578 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 0x00);
0579 if (ret)
0580 return ret;
0581
0582
0583 ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG1,
0584 FXOS8700_HMS_MASK | FXOS8700_OS_MASK);
0585 if (ret)
0586 return ret;
0587
0588
0589 ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG2,
0590 FXOS8700_MAXMIN_RST | FXOS8700_MAXMIN_DIS_THS |
0591 FXOS8700_MAXMIN_DIS);
0592 if (ret)
0593 return ret;
0594
0595
0596 ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
0597 FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE);
0598 if (ret)
0599 return ret;
0600
0601
0602 return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
0603 }
0604
0605 static void fxos8700_chip_uninit(void *data)
0606 {
0607 struct fxos8700_data *fxos8700_data = data;
0608
0609 fxos8700_set_active_mode(fxos8700_data, FXOS8700_ACCEL, false);
0610 fxos8700_set_active_mode(fxos8700_data, FXOS8700_MAGN, false);
0611 }
0612
0613 int fxos8700_core_probe(struct device *dev, struct regmap *regmap,
0614 const char *name, bool use_spi)
0615 {
0616 struct iio_dev *indio_dev;
0617 struct fxos8700_data *data;
0618 int ret;
0619
0620 indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
0621 if (!indio_dev)
0622 return -ENOMEM;
0623
0624 data = iio_priv(indio_dev);
0625 dev_set_drvdata(dev, indio_dev);
0626 data->regmap = regmap;
0627
0628 ret = fxos8700_chip_init(data, use_spi);
0629 if (ret)
0630 return ret;
0631
0632 ret = devm_add_action_or_reset(dev, fxos8700_chip_uninit, data);
0633 if (ret)
0634 return ret;
0635
0636 indio_dev->channels = fxos8700_channels;
0637 indio_dev->num_channels = ARRAY_SIZE(fxos8700_channels);
0638 indio_dev->name = name ? name : "fxos8700";
0639 indio_dev->modes = INDIO_DIRECT_MODE;
0640 indio_dev->info = &fxos8700_info;
0641
0642 return devm_iio_device_register(dev, indio_dev);
0643 }
0644 EXPORT_SYMBOL_GPL(fxos8700_core_probe);
0645
0646 MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>");
0647 MODULE_DESCRIPTION("FXOS8700 6-Axis Acc and Mag Combo Sensor driver");
0648 MODULE_LICENSE("GPL v2");