1 // SPDX-License-Identifier: GPL-2.0
3 * FXOS8700 - NXP IMU (accelerometer plus magnetometer)
5 * IIO core driver for FXOS8700, with support for I2C/SPI busses
7 * TODO: Buffer, trigger, and IRQ support
9 #include <linux/module.h>
10 #include <linux/regmap.h>
11 #include <linux/acpi.h>
12 #include <linux/bitops.h>
13 #include <linux/bitfield.h>
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
20 /* Register Definitions */
21 #define FXOS8700_STATUS 0x00
22 #define FXOS8700_OUT_X_MSB 0x01
23 #define FXOS8700_OUT_X_LSB 0x02
24 #define FXOS8700_OUT_Y_MSB 0x03
25 #define FXOS8700_OUT_Y_LSB 0x04
26 #define FXOS8700_OUT_Z_MSB 0x05
27 #define FXOS8700_OUT_Z_LSB 0x06
28 #define FXOS8700_F_SETUP 0x09
29 #define FXOS8700_TRIG_CFG 0x0a
30 #define FXOS8700_SYSMOD 0x0b
31 #define FXOS8700_INT_SOURCE 0x0c
32 #define FXOS8700_WHO_AM_I 0x0d
33 #define FXOS8700_XYZ_DATA_CFG 0x0e
34 #define FXOS8700_HP_FILTER_CUTOFF 0x0f
35 #define FXOS8700_PL_STATUS 0x10
36 #define FXOS8700_PL_CFG 0x11
37 #define FXOS8700_PL_COUNT 0x12
38 #define FXOS8700_PL_BF_ZCOMP 0x13
39 #define FXOS8700_PL_THS_REG 0x14
40 #define FXOS8700_A_FFMT_CFG 0x15
41 #define FXOS8700_A_FFMT_SRC 0x16
42 #define FXOS8700_A_FFMT_THS 0x17
43 #define FXOS8700_A_FFMT_COUNT 0x18
44 #define FXOS8700_TRANSIENT_CFG 0x1d
45 #define FXOS8700_TRANSIENT_SRC 0x1e
46 #define FXOS8700_TRANSIENT_THS 0x1f
47 #define FXOS8700_TRANSIENT_COUNT 0x20
48 #define FXOS8700_PULSE_CFG 0x21
49 #define FXOS8700_PULSE_SRC 0x22
50 #define FXOS8700_PULSE_THSX 0x23
51 #define FXOS8700_PULSE_THSY 0x24
52 #define FXOS8700_PULSE_THSZ 0x25
53 #define FXOS8700_PULSE_TMLT 0x26
54 #define FXOS8700_PULSE_LTCY 0x27
55 #define FXOS8700_PULSE_WIND 0x28
56 #define FXOS8700_ASLP_COUNT 0x29
57 #define FXOS8700_CTRL_REG1 0x2a
58 #define FXOS8700_CTRL_REG2 0x2b
59 #define FXOS8700_CTRL_REG3 0x2c
60 #define FXOS8700_CTRL_REG4 0x2d
61 #define FXOS8700_CTRL_REG5 0x2e
62 #define FXOS8700_OFF_X 0x2f
63 #define FXOS8700_OFF_Y 0x30
64 #define FXOS8700_OFF_Z 0x31
65 #define FXOS8700_M_DR_STATUS 0x32
66 #define FXOS8700_M_OUT_X_MSB 0x33
67 #define FXOS8700_M_OUT_X_LSB 0x34
68 #define FXOS8700_M_OUT_Y_MSB 0x35
69 #define FXOS8700_M_OUT_Y_LSB 0x36
70 #define FXOS8700_M_OUT_Z_MSB 0x37
71 #define FXOS8700_M_OUT_Z_LSB 0x38
72 #define FXOS8700_CMP_X_MSB 0x39
73 #define FXOS8700_CMP_X_LSB 0x3a
74 #define FXOS8700_CMP_Y_MSB 0x3b
75 #define FXOS8700_CMP_Y_LSB 0x3c
76 #define FXOS8700_CMP_Z_MSB 0x3d
77 #define FXOS8700_CMP_Z_LSB 0x3e
78 #define FXOS8700_M_OFF_X_MSB 0x3f
79 #define FXOS8700_M_OFF_X_LSB 0x40
80 #define FXOS8700_M_OFF_Y_MSB 0x41
81 #define FXOS8700_M_OFF_Y_LSB 0x42
82 #define FXOS8700_M_OFF_Z_MSB 0x43
83 #define FXOS8700_M_OFF_Z_LSB 0x44
84 #define FXOS8700_MAX_X_MSB 0x45
85 #define FXOS8700_MAX_X_LSB 0x46
86 #define FXOS8700_MAX_Y_MSB 0x47
87 #define FXOS8700_MAX_Y_LSB 0x48
88 #define FXOS8700_MAX_Z_MSB 0x49
89 #define FXOS8700_MAX_Z_LSB 0x4a
90 #define FXOS8700_MIN_X_MSB 0x4b
91 #define FXOS8700_MIN_X_LSB 0x4c
92 #define FXOS8700_MIN_Y_MSB 0x4d
93 #define FXOS8700_MIN_Y_LSB 0x4e
94 #define FXOS8700_MIN_Z_MSB 0x4f
95 #define FXOS8700_MIN_Z_LSB 0x50
96 #define FXOS8700_TEMP 0x51
97 #define FXOS8700_M_THS_CFG 0x52
98 #define FXOS8700_M_THS_SRC 0x53
99 #define FXOS8700_M_THS_X_MSB 0x54
100 #define FXOS8700_M_THS_X_LSB 0x55
101 #define FXOS8700_M_THS_Y_MSB 0x56
102 #define FXOS8700_M_THS_Y_LSB 0x57
103 #define FXOS8700_M_THS_Z_MSB 0x58
104 #define FXOS8700_M_THS_Z_LSB 0x59
105 #define FXOS8700_M_THS_COUNT 0x5a
106 #define FXOS8700_M_CTRL_REG1 0x5b
107 #define FXOS8700_M_CTRL_REG2 0x5c
108 #define FXOS8700_M_CTRL_REG3 0x5d
109 #define FXOS8700_M_INT_SRC 0x5e
110 #define FXOS8700_A_VECM_CFG 0x5f
111 #define FXOS8700_A_VECM_THS_MSB 0x60
112 #define FXOS8700_A_VECM_THS_LSB 0x61
113 #define FXOS8700_A_VECM_CNT 0x62
114 #define FXOS8700_A_VECM_INITX_MSB 0x63
115 #define FXOS8700_A_VECM_INITX_LSB 0x64
116 #define FXOS8700_A_VECM_INITY_MSB 0x65
117 #define FXOS8700_A_VECM_INITY_LSB 0x66
118 #define FXOS8700_A_VECM_INITZ_MSB 0x67
119 #define FXOS8700_A_VECM_INITZ_LSB 0x68
120 #define FXOS8700_M_VECM_CFG 0x69
121 #define FXOS8700_M_VECM_THS_MSB 0x6a
122 #define FXOS8700_M_VECM_THS_LSB 0x6b
123 #define FXOS8700_M_VECM_CNT 0x6c
124 #define FXOS8700_M_VECM_INITX_MSB 0x6d
125 #define FXOS8700_M_VECM_INITX_LSB 0x6e
126 #define FXOS8700_M_VECM_INITY_MSB 0x6f
127 #define FXOS8700_M_VECM_INITY_LSB 0x70
128 #define FXOS8700_M_VECM_INITZ_MSB 0x71
129 #define FXOS8700_M_VECM_INITZ_LSB 0x72
130 #define FXOS8700_A_FFMT_THS_X_MSB 0x73
131 #define FXOS8700_A_FFMT_THS_X_LSB 0x74
132 #define FXOS8700_A_FFMT_THS_Y_MSB 0x75
133 #define FXOS8700_A_FFMT_THS_Y_LSB 0x76
134 #define FXOS8700_A_FFMT_THS_Z_MSB 0x77
135 #define FXOS8700_A_FFMT_THS_Z_LSB 0x78
136 #define FXOS8700_A_TRAN_INIT_MSB 0x79
137 #define FXOS8700_A_TRAN_INIT_LSB_X 0x7a
138 #define FXOS8700_A_TRAN_INIT_LSB_Y 0x7b
139 #define FXOS8700_A_TRAN_INIT_LSB_Z 0x7d
140 #define FXOS8700_TM_NVM_LOCK 0x7e
141 #define FXOS8700_NVM_DATA0_35 0x80
142 #define FXOS8700_NVM_DATA_BNK3 0xa4
143 #define FXOS8700_NVM_DATA_BNK2 0xa5
144 #define FXOS8700_NVM_DATA_BNK1 0xa6
145 #define FXOS8700_NVM_DATA_BNK0 0xa7
147 /* Bit definitions for FXOS8700_CTRL_REG1 */
148 #define FXOS8700_CTRL_ODR_MAX 0x00
149 #define FXOS8700_CTRL_ODR_MSK GENMASK(5, 3)
151 /* Bit definitions for FXOS8700_M_CTRL_REG1 */
152 #define FXOS8700_HMS_MASK GENMASK(1, 0)
153 #define FXOS8700_OS_MASK GENMASK(4, 2)
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)
160 #define FXOS8700_ACTIVE 0x01
161 #define FXOS8700_ACTIVE_MIN_USLEEP 4000 /* from table 6 in datasheet */
163 #define FXOS8700_DEVICE_ID 0xC7
164 #define FXOS8700_PRE_DEVICE_ID 0xC4
165 #define FXOS8700_DATA_BUF_SIZE 3
167 struct fxos8700_data
{
168 struct regmap
*regmap
;
169 struct iio_trigger
*trig
;
170 __be16 buf
[FXOS8700_DATA_BUF_SIZE
] __aligned(IIO_DMA_MINALIGN
);
174 static const struct regmap_range read_range
[] = {
176 .range_min
= FXOS8700_STATUS
,
177 .range_max
= FXOS8700_A_FFMT_COUNT
,
179 .range_min
= FXOS8700_TRANSIENT_CFG
,
180 .range_max
= FXOS8700_A_FFMT_THS_Z_LSB
,
184 static const struct regmap_range write_range
[] = {
186 .range_min
= FXOS8700_F_SETUP
,
187 .range_max
= FXOS8700_TRIG_CFG
,
189 .range_min
= FXOS8700_XYZ_DATA_CFG
,
190 .range_max
= FXOS8700_HP_FILTER_CUTOFF
,
192 .range_min
= FXOS8700_PL_CFG
,
193 .range_max
= FXOS8700_A_FFMT_CFG
,
195 .range_min
= FXOS8700_A_FFMT_THS
,
196 .range_max
= FXOS8700_TRANSIENT_CFG
,
198 .range_min
= FXOS8700_TRANSIENT_THS
,
199 .range_max
= FXOS8700_PULSE_CFG
,
201 .range_min
= FXOS8700_PULSE_THSX
,
202 .range_max
= FXOS8700_OFF_Z
,
204 .range_min
= FXOS8700_M_OFF_X_MSB
,
205 .range_max
= FXOS8700_M_OFF_Z_LSB
,
207 .range_min
= FXOS8700_M_THS_CFG
,
208 .range_max
= FXOS8700_M_THS_CFG
,
210 .range_min
= FXOS8700_M_THS_X_MSB
,
211 .range_max
= FXOS8700_M_CTRL_REG3
,
213 .range_min
= FXOS8700_A_VECM_CFG
,
214 .range_max
= FXOS8700_A_FFMT_THS_Z_LSB
,
218 static const struct regmap_access_table driver_read_table
= {
219 .yes_ranges
= read_range
,
220 .n_yes_ranges
= ARRAY_SIZE(read_range
),
223 static const struct regmap_access_table driver_write_table
= {
224 .yes_ranges
= write_range
,
225 .n_yes_ranges
= ARRAY_SIZE(write_range
),
228 const struct regmap_config fxos8700_regmap_config
= {
231 .max_register
= FXOS8700_NVM_DATA_BNK0
,
232 .rd_table
= &driver_read_table
,
233 .wr_table
= &driver_write_table
,
235 EXPORT_SYMBOL(fxos8700_regmap_config
);
237 #define FXOS8700_CHANNEL(_type, _axis) { \
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), \
246 enum fxos8700_accel_scale_bits
{
252 /* scan indexes follow DATA register order */
253 enum 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
,
261 FXOS8700_SCAN_TIMESTAMP
,
264 enum fxos8700_sensor
{
267 FXOS8700_NUM_SENSORS
/* must be last */
270 enum fxos8700_int_pin
{
275 struct fxos8700_scale
{
280 struct fxos8700_odr
{
286 static const struct fxos8700_scale fxos8700_accel_scale
[] = {
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
297 static const struct fxos8700_odr fxos8700_odr
[] = {
308 static 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
),
318 static enum fxos8700_sensor
fxos8700_to_sensor(enum iio_chan_type iio_type
)
322 return FXOS8700_ACCEL
;
324 return FXOS8700_MAGN
;
330 static int fxos8700_set_active_mode(struct fxos8700_data
*data
,
331 enum fxos8700_sensor t
, bool mode
)
335 ret
= regmap_write(data
->regmap
, FXOS8700_CTRL_REG1
, mode
);
339 usleep_range(FXOS8700_ACTIVE_MIN_USLEEP
,
340 FXOS8700_ACTIVE_MIN_USLEEP
+ 1000);
345 static int fxos8700_set_scale(struct fxos8700_data
*data
,
346 enum fxos8700_sensor t
, int uscale
)
350 static const int scale_num
= ARRAY_SIZE(fxos8700_accel_scale
);
351 struct device
*dev
= regmap_get_device(data
->regmap
);
353 if (t
== FXOS8700_MAGN
) {
354 dev_err(dev
, "Magnetometer scale is locked at 0.001Gs\n");
359 * When device is in active mode, it failed to set an ACCEL
360 * full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG.
361 * This is not align with the datasheet, but it is a fxos8700
362 * chip behavier. Set the device in standby mode before setting
363 * an ACCEL full-scale range.
365 ret
= regmap_read(data
->regmap
, FXOS8700_CTRL_REG1
, &val
);
369 active_mode
= val
& FXOS8700_ACTIVE
;
371 ret
= regmap_write(data
->regmap
, FXOS8700_CTRL_REG1
,
372 val
& ~FXOS8700_ACTIVE
);
377 for (i
= 0; i
< scale_num
; i
++)
378 if (fxos8700_accel_scale
[i
].uscale
== uscale
)
384 ret
= regmap_write(data
->regmap
, FXOS8700_XYZ_DATA_CFG
,
385 fxos8700_accel_scale
[i
].bits
);
388 return regmap_write(data
->regmap
, FXOS8700_CTRL_REG1
,
392 static int fxos8700_get_scale(struct fxos8700_data
*data
,
393 enum fxos8700_sensor t
, int *uscale
)
396 static const int scale_num
= ARRAY_SIZE(fxos8700_accel_scale
);
398 if (t
== FXOS8700_MAGN
) {
399 *uscale
= 1000; /* Magnetometer is locked at 0.001Gs */
403 ret
= regmap_read(data
->regmap
, FXOS8700_XYZ_DATA_CFG
, &val
);
407 for (i
= 0; i
< scale_num
; i
++) {
408 if (fxos8700_accel_scale
[i
].bits
== (val
& 0x3)) {
409 *uscale
= fxos8700_accel_scale
[i
].uscale
;
417 static int fxos8700_get_data(struct fxos8700_data
*data
, int chan_type
,
425 * Different register base addresses varies with channel types.
426 * This bug hasn't been noticed before because using an enum is
427 * really hard to read. Use an a switch statement to take over that.
431 base
= FXOS8700_OUT_X_MSB
;
434 base
= FXOS8700_M_OUT_X_MSB
;
440 /* Block read 6 bytes of device output registers to avoid data loss */
441 ret
= regmap_bulk_read(data
->regmap
, base
, data
->buf
,
446 /* Convert axis to buffer index */
447 reg
= axis
- IIO_MOD_X
;
450 * Convert to native endianness. The accel data and magn data
451 * are signed, so a forced type conversion is needed.
453 tmp
= be16_to_cpu(data
->buf
[reg
]);
456 * ACCEL output data registers contain the X-axis, Y-axis, and Z-axis
457 * 14-bit left-justified sample data and MAGN output data registers
458 * contain the X-axis, Y-axis, and Z-axis 16-bit sample data. Apply
459 * a signed 2 bits right shift to the readback raw data from ACCEL
460 * output data register and keep that from MAGN sensor as the origin.
461 * Value should be extended to 32 bit.
474 /* Convert to native endianness */
475 *val
= sign_extend32(tmp
, 15);
480 static int fxos8700_set_odr(struct fxos8700_data
*data
, enum fxos8700_sensor t
,
485 static const int odr_num
= ARRAY_SIZE(fxos8700_odr
);
487 ret
= regmap_read(data
->regmap
, FXOS8700_CTRL_REG1
, &val
);
491 active_mode
= val
& FXOS8700_ACTIVE
;
495 * The device must be in standby mode to change any of the
496 * other fields within CTRL_REG1
498 ret
= regmap_write(data
->regmap
, FXOS8700_CTRL_REG1
,
499 val
& ~FXOS8700_ACTIVE
);
504 for (i
= 0; i
< odr_num
; i
++)
505 if (fxos8700_odr
[i
].odr
== odr
&& fxos8700_odr
[i
].uodr
== uodr
)
511 val
&= ~FXOS8700_CTRL_ODR_MSK
;
512 val
|= FIELD_PREP(FXOS8700_CTRL_ODR_MSK
, fxos8700_odr
[i
].bits
) | FXOS8700_ACTIVE
;
513 return regmap_write(data
->regmap
, FXOS8700_CTRL_REG1
, val
);
516 static int fxos8700_get_odr(struct fxos8700_data
*data
, enum fxos8700_sensor t
,
520 static const int odr_num
= ARRAY_SIZE(fxos8700_odr
);
522 ret
= regmap_read(data
->regmap
, FXOS8700_CTRL_REG1
, &val
);
526 val
= FIELD_GET(FXOS8700_CTRL_ODR_MSK
, val
);
528 for (i
= 0; i
< odr_num
; i
++)
529 if (val
== fxos8700_odr
[i
].bits
)
535 *odr
= fxos8700_odr
[i
].odr
;
536 *uodr
= fxos8700_odr
[i
].uodr
;
541 static int fxos8700_read_raw(struct iio_dev
*indio_dev
,
542 struct iio_chan_spec
const *chan
,
543 int *val
, int *val2
, long mask
)
546 struct fxos8700_data
*data
= iio_priv(indio_dev
);
549 case IIO_CHAN_INFO_RAW
:
550 ret
= fxos8700_get_data(data
, chan
->type
, chan
->channel2
, val
);
554 case IIO_CHAN_INFO_SCALE
:
556 ret
= fxos8700_get_scale(data
, fxos8700_to_sensor(chan
->type
),
558 return ret
? ret
: IIO_VAL_INT_PLUS_MICRO
;
559 case IIO_CHAN_INFO_SAMP_FREQ
:
560 ret
= fxos8700_get_odr(data
, fxos8700_to_sensor(chan
->type
),
562 return ret
? ret
: IIO_VAL_INT_PLUS_MICRO
;
568 static int fxos8700_write_raw(struct iio_dev
*indio_dev
,
569 struct iio_chan_spec
const *chan
,
570 int val
, int val2
, long mask
)
572 struct fxos8700_data
*data
= iio_priv(indio_dev
);
575 case IIO_CHAN_INFO_SCALE
:
576 return fxos8700_set_scale(data
, fxos8700_to_sensor(chan
->type
),
578 case IIO_CHAN_INFO_SAMP_FREQ
:
579 return fxos8700_set_odr(data
, fxos8700_to_sensor(chan
->type
),
586 static IIO_CONST_ATTR(in_accel_sampling_frequency_available
,
587 "1.5625 6.25 12.5 50 100 200 400 800");
588 static IIO_CONST_ATTR(in_magn_sampling_frequency_available
,
589 "1.5625 6.25 12.5 50 100 200 400 800");
590 static IIO_CONST_ATTR(in_accel_scale_available
, "0.000244 0.000488 0.000976");
591 static IIO_CONST_ATTR(in_magn_scale_available
, "0.001000");
593 static struct attribute
*fxos8700_attrs
[] = {
594 &iio_const_attr_in_accel_sampling_frequency_available
.dev_attr
.attr
,
595 &iio_const_attr_in_magn_sampling_frequency_available
.dev_attr
.attr
,
596 &iio_const_attr_in_accel_scale_available
.dev_attr
.attr
,
597 &iio_const_attr_in_magn_scale_available
.dev_attr
.attr
,
601 static const struct attribute_group fxos8700_attrs_group
= {
602 .attrs
= fxos8700_attrs
,
605 static const struct iio_info fxos8700_info
= {
606 .read_raw
= fxos8700_read_raw
,
607 .write_raw
= fxos8700_write_raw
,
608 .attrs
= &fxos8700_attrs_group
,
611 static int fxos8700_chip_init(struct fxos8700_data
*data
, bool use_spi
)
615 struct device
*dev
= regmap_get_device(data
->regmap
);
617 ret
= regmap_read(data
->regmap
, FXOS8700_WHO_AM_I
, &val
);
619 dev_err(dev
, "Error reading chip id\n");
622 if (val
!= FXOS8700_DEVICE_ID
&& val
!= FXOS8700_PRE_DEVICE_ID
) {
623 dev_err(dev
, "Wrong chip id, got %x expected %x or %x\n",
624 val
, FXOS8700_DEVICE_ID
, FXOS8700_PRE_DEVICE_ID
);
628 ret
= fxos8700_set_active_mode(data
, FXOS8700_ACCEL
, true);
632 ret
= fxos8700_set_active_mode(data
, FXOS8700_MAGN
, true);
637 * The device must be in standby mode to change any of the other fields
640 ret
= regmap_write(data
->regmap
, FXOS8700_CTRL_REG1
, 0x00);
644 /* Set max oversample ratio (OSR) and both devices active */
645 ret
= regmap_write(data
->regmap
, FXOS8700_M_CTRL_REG1
,
646 FXOS8700_HMS_MASK
| FXOS8700_OS_MASK
);
650 /* Disable and rst min/max measurements & threshold */
651 ret
= regmap_write(data
->regmap
, FXOS8700_M_CTRL_REG2
,
652 FXOS8700_MAXMIN_RST
| FXOS8700_MAXMIN_DIS_THS
|
653 FXOS8700_MAXMIN_DIS
);
658 * Set max full-scale range (+/-8G) for ACCEL sensor in chip
659 * initialization then activate the device.
661 ret
= regmap_write(data
->regmap
, FXOS8700_XYZ_DATA_CFG
, MODE_8G
);
665 /* Max ODR (800Hz individual or 400Hz hybrid), active mode */
666 return regmap_update_bits(data
->regmap
, FXOS8700_CTRL_REG1
,
667 FXOS8700_CTRL_ODR_MSK
| FXOS8700_ACTIVE
,
668 FIELD_PREP(FXOS8700_CTRL_ODR_MSK
, FXOS8700_CTRL_ODR_MAX
) |
672 static void fxos8700_chip_uninit(void *data
)
674 struct fxos8700_data
*fxos8700_data
= data
;
676 fxos8700_set_active_mode(fxos8700_data
, FXOS8700_ACCEL
, false);
677 fxos8700_set_active_mode(fxos8700_data
, FXOS8700_MAGN
, false);
680 int fxos8700_core_probe(struct device
*dev
, struct regmap
*regmap
,
681 const char *name
, bool use_spi
)
683 struct iio_dev
*indio_dev
;
684 struct fxos8700_data
*data
;
687 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*data
));
691 data
= iio_priv(indio_dev
);
692 dev_set_drvdata(dev
, indio_dev
);
693 data
->regmap
= regmap
;
695 ret
= fxos8700_chip_init(data
, use_spi
);
699 ret
= devm_add_action_or_reset(dev
, fxos8700_chip_uninit
, data
);
703 indio_dev
->channels
= fxos8700_channels
;
704 indio_dev
->num_channels
= ARRAY_SIZE(fxos8700_channels
);
705 indio_dev
->name
= name
? name
: "fxos8700";
706 indio_dev
->modes
= INDIO_DIRECT_MODE
;
707 indio_dev
->info
= &fxos8700_info
;
709 return devm_iio_device_register(dev
, indio_dev
);
711 EXPORT_SYMBOL_GPL(fxos8700_core_probe
);
713 MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>");
714 MODULE_DESCRIPTION("FXOS8700 6-Axis Acc and Mag Combo Sensor driver");
715 MODULE_LICENSE("GPL v2");