1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * mma8452.c - Support for following Freescale / NXP 3-axis accelerometers: |
4 | * |
5 | * device name digital output 7-bit I2C slave address (pin selectable) |
6 | * --------------------------------------------------------------------- |
7 | * MMA8451Q 14 bit 0x1c / 0x1d |
8 | * MMA8452Q 12 bit 0x1c / 0x1d |
9 | * MMA8453Q 10 bit 0x1c / 0x1d |
10 | * MMA8652FC 12 bit 0x1d |
11 | * MMA8653FC 10 bit 0x1d |
12 | * FXLS8471Q 14 bit 0x1e / 0x1d / 0x1c / 0x1f |
13 | * |
14 | * Copyright 2015 Martin Kepplinger <martink@posteo.de> |
15 | * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net> |
16 | * |
17 | * |
18 | * TODO: orientation events |
19 | */ |
20 | |
21 | #include <linux/module.h> |
22 | #include <linux/i2c.h> |
23 | #include <linux/iio/iio.h> |
24 | #include <linux/iio/sysfs.h> |
25 | #include <linux/iio/buffer.h> |
26 | #include <linux/iio/trigger.h> |
27 | #include <linux/iio/trigger_consumer.h> |
28 | #include <linux/iio/triggered_buffer.h> |
29 | #include <linux/iio/events.h> |
30 | #include <linux/delay.h> |
31 | #include <linux/of.h> |
32 | #include <linux/of_irq.h> |
33 | #include <linux/pm_runtime.h> |
34 | #include <linux/regulator/consumer.h> |
35 | |
36 | #define MMA8452_STATUS 0x00 |
37 | #define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0)) |
38 | #define MMA8452_OUT_X 0x01 /* MSB first */ |
39 | #define MMA8452_OUT_Y 0x03 |
40 | #define MMA8452_OUT_Z 0x05 |
41 | #define MMA8452_INT_SRC 0x0c |
42 | #define MMA8452_WHO_AM_I 0x0d |
43 | #define MMA8452_DATA_CFG 0x0e |
44 | #define MMA8452_DATA_CFG_FS_MASK GENMASK(1, 0) |
45 | #define MMA8452_DATA_CFG_FS_2G 0 |
46 | #define MMA8452_DATA_CFG_FS_4G 1 |
47 | #define MMA8452_DATA_CFG_FS_8G 2 |
48 | #define MMA8452_DATA_CFG_HPF_MASK BIT(4) |
49 | #define MMA8452_HP_FILTER_CUTOFF 0x0f |
50 | #define MMA8452_HP_FILTER_CUTOFF_SEL_MASK GENMASK(1, 0) |
51 | #define MMA8452_FF_MT_CFG 0x15 |
52 | #define MMA8452_FF_MT_CFG_OAE BIT(6) |
53 | #define MMA8452_FF_MT_CFG_ELE BIT(7) |
54 | #define MMA8452_FF_MT_SRC 0x16 |
55 | #define MMA8452_FF_MT_SRC_XHE BIT(1) |
56 | #define MMA8452_FF_MT_SRC_YHE BIT(3) |
57 | #define MMA8452_FF_MT_SRC_ZHE BIT(5) |
58 | #define MMA8452_FF_MT_THS 0x17 |
59 | #define MMA8452_FF_MT_THS_MASK 0x7f |
60 | #define MMA8452_FF_MT_COUNT 0x18 |
61 | #define MMA8452_FF_MT_CHAN_SHIFT 3 |
62 | #define MMA8452_TRANSIENT_CFG 0x1d |
63 | #define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1) |
64 | #define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0) |
65 | #define MMA8452_TRANSIENT_CFG_ELE BIT(4) |
66 | #define MMA8452_TRANSIENT_SRC 0x1e |
67 | #define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1) |
68 | #define MMA8452_TRANSIENT_SRC_YTRANSE BIT(3) |
69 | #define MMA8452_TRANSIENT_SRC_ZTRANSE BIT(5) |
70 | #define MMA8452_TRANSIENT_THS 0x1f |
71 | #define MMA8452_TRANSIENT_THS_MASK GENMASK(6, 0) |
72 | #define MMA8452_TRANSIENT_COUNT 0x20 |
73 | #define MMA8452_TRANSIENT_CHAN_SHIFT 1 |
74 | #define MMA8452_CTRL_REG1 0x2a |
75 | #define MMA8452_CTRL_ACTIVE BIT(0) |
76 | #define MMA8452_CTRL_DR_MASK GENMASK(5, 3) |
77 | #define MMA8452_CTRL_DR_SHIFT 3 |
78 | #define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */ |
79 | #define MMA8452_CTRL_REG2 0x2b |
80 | #define MMA8452_CTRL_REG2_RST BIT(6) |
81 | #define MMA8452_CTRL_REG2_MODS_SHIFT 3 |
82 | #define MMA8452_CTRL_REG2_MODS_MASK 0x1b |
83 | #define MMA8452_CTRL_REG4 0x2d |
84 | #define MMA8452_CTRL_REG5 0x2e |
85 | #define MMA8452_OFF_X 0x2f |
86 | #define MMA8452_OFF_Y 0x30 |
87 | #define MMA8452_OFF_Z 0x31 |
88 | |
89 | #define MMA8452_MAX_REG 0x31 |
90 | |
91 | #define MMA8452_INT_DRDY BIT(0) |
92 | #define MMA8452_INT_FF_MT BIT(2) |
93 | #define MMA8452_INT_TRANS BIT(5) |
94 | |
95 | #define MMA8451_DEVICE_ID 0x1a |
96 | #define MMA8452_DEVICE_ID 0x2a |
97 | #define MMA8453_DEVICE_ID 0x3a |
98 | #define MMA8652_DEVICE_ID 0x4a |
99 | #define MMA8653_DEVICE_ID 0x5a |
100 | #define FXLS8471_DEVICE_ID 0x6a |
101 | |
102 | #define MMA8452_AUTO_SUSPEND_DELAY_MS 2000 |
103 | |
104 | struct mma8452_data { |
105 | struct i2c_client *client; |
106 | struct mutex lock; |
107 | struct iio_mount_matrix orientation; |
108 | u8 ctrl_reg1; |
109 | u8 data_cfg; |
110 | const struct mma_chip_info *chip_info; |
111 | int sleep_val; |
112 | struct regulator *vdd_reg; |
113 | struct regulator *vddio_reg; |
114 | |
115 | /* Ensure correct alignment of time stamp when present */ |
116 | struct { |
117 | __be16 channels[3]; |
118 | s64 ts __aligned(8); |
119 | } buffer; |
120 | }; |
121 | |
122 | /** |
123 | * struct mma8452_event_regs - chip specific data related to events |
124 | * @ev_cfg: event config register address |
125 | * @ev_cfg_ele: latch bit in event config register |
126 | * @ev_cfg_chan_shift: number of the bit to enable events in X |
127 | * direction; in event config register |
128 | * @ev_src: event source register address |
129 | * @ev_ths: event threshold register address |
130 | * @ev_ths_mask: mask for the threshold value |
131 | * @ev_count: event count (period) register address |
132 | * |
133 | * Since not all chips supported by the driver support comparing high pass |
134 | * filtered data for events (interrupts), different interrupt sources are |
135 | * used for different chips and the relevant registers are included here. |
136 | */ |
137 | struct mma8452_event_regs { |
138 | u8 ev_cfg; |
139 | u8 ev_cfg_ele; |
140 | u8 ev_cfg_chan_shift; |
141 | u8 ev_src; |
142 | u8 ev_ths; |
143 | u8 ev_ths_mask; |
144 | u8 ev_count; |
145 | }; |
146 | |
147 | static const struct mma8452_event_regs ff_mt_ev_regs = { |
148 | .ev_cfg = MMA8452_FF_MT_CFG, |
149 | .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE, |
150 | .ev_cfg_chan_shift = MMA8452_FF_MT_CHAN_SHIFT, |
151 | .ev_src = MMA8452_FF_MT_SRC, |
152 | .ev_ths = MMA8452_FF_MT_THS, |
153 | .ev_ths_mask = MMA8452_FF_MT_THS_MASK, |
154 | .ev_count = MMA8452_FF_MT_COUNT |
155 | }; |
156 | |
157 | static const struct mma8452_event_regs trans_ev_regs = { |
158 | .ev_cfg = MMA8452_TRANSIENT_CFG, |
159 | .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE, |
160 | .ev_cfg_chan_shift = MMA8452_TRANSIENT_CHAN_SHIFT, |
161 | .ev_src = MMA8452_TRANSIENT_SRC, |
162 | .ev_ths = MMA8452_TRANSIENT_THS, |
163 | .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK, |
164 | .ev_count = MMA8452_TRANSIENT_COUNT, |
165 | }; |
166 | |
167 | /** |
168 | * struct mma_chip_info - chip specific data |
169 | * @name: part number of device reported via 'name' attr |
170 | * @chip_id: WHO_AM_I register's value |
171 | * @channels: struct iio_chan_spec matching the device's |
172 | * capabilities |
173 | * @num_channels: number of channels |
174 | * @mma_scales: scale factors for converting register values |
175 | * to m/s^2; 3 modes: 2g, 4g, 8g; 2 integers |
176 | * per mode: m/s^2 and micro m/s^2 |
177 | * @all_events: all events supported by this chip |
178 | * @enabled_events: event flags enabled and handled by this driver |
179 | */ |
180 | struct mma_chip_info { |
181 | const char *name; |
182 | u8 chip_id; |
183 | const struct iio_chan_spec *channels; |
184 | int num_channels; |
185 | const int mma_scales[3][2]; |
186 | int all_events; |
187 | int enabled_events; |
188 | }; |
189 | |
190 | enum { |
191 | idx_x, |
192 | idx_y, |
193 | idx_z, |
194 | idx_ts, |
195 | }; |
196 | |
197 | static int mma8452_drdy(struct mma8452_data *data) |
198 | { |
199 | int tries = 150; |
200 | |
201 | while (tries-- > 0) { |
202 | int ret = i2c_smbus_read_byte_data(client: data->client, |
203 | MMA8452_STATUS); |
204 | if (ret < 0) |
205 | return ret; |
206 | if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY) |
207 | return 0; |
208 | |
209 | if (data->sleep_val <= 20) |
210 | usleep_range(min: data->sleep_val * 250, |
211 | max: data->sleep_val * 500); |
212 | else |
213 | msleep(msecs: 20); |
214 | } |
215 | |
216 | dev_err(&data->client->dev, "data not ready\n" ); |
217 | |
218 | return -EIO; |
219 | } |
220 | |
221 | static int mma8452_set_runtime_pm_state(struct i2c_client *client, bool on) |
222 | { |
223 | #ifdef CONFIG_PM |
224 | int ret; |
225 | |
226 | if (on) { |
227 | ret = pm_runtime_resume_and_get(dev: &client->dev); |
228 | } else { |
229 | pm_runtime_mark_last_busy(dev: &client->dev); |
230 | ret = pm_runtime_put_autosuspend(dev: &client->dev); |
231 | } |
232 | |
233 | if (ret < 0) { |
234 | dev_err(&client->dev, |
235 | "failed to change power state to %d\n" , on); |
236 | |
237 | return ret; |
238 | } |
239 | #endif |
240 | |
241 | return 0; |
242 | } |
243 | |
244 | static int mma8452_read(struct mma8452_data *data, __be16 buf[3]) |
245 | { |
246 | int ret = mma8452_drdy(data); |
247 | |
248 | if (ret < 0) |
249 | return ret; |
250 | |
251 | ret = mma8452_set_runtime_pm_state(client: data->client, on: true); |
252 | if (ret) |
253 | return ret; |
254 | |
255 | ret = i2c_smbus_read_i2c_block_data(client: data->client, MMA8452_OUT_X, |
256 | length: 3 * sizeof(__be16), values: (u8 *)buf); |
257 | |
258 | ret = mma8452_set_runtime_pm_state(client: data->client, on: false); |
259 | |
260 | return ret; |
261 | } |
262 | |
263 | static ssize_t mma8452_show_int_plus_micros(char *buf, const int (*vals)[2], |
264 | int n) |
265 | { |
266 | size_t len = 0; |
267 | |
268 | while (n-- > 0) |
269 | len += scnprintf(buf: buf + len, PAGE_SIZE - len, fmt: "%d.%06d " , |
270 | vals[n][0], vals[n][1]); |
271 | |
272 | /* replace trailing space by newline */ |
273 | buf[len - 1] = '\n'; |
274 | |
275 | return len; |
276 | } |
277 | |
278 | static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n, |
279 | int val, int val2) |
280 | { |
281 | while (n-- > 0) |
282 | if (val == vals[n][0] && val2 == vals[n][1]) |
283 | return n; |
284 | |
285 | return -EINVAL; |
286 | } |
287 | |
288 | static unsigned int mma8452_get_odr_index(struct mma8452_data *data) |
289 | { |
290 | return (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >> |
291 | MMA8452_CTRL_DR_SHIFT; |
292 | } |
293 | |
294 | static const int mma8452_samp_freq[8][2] = { |
295 | {800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000}, |
296 | {6, 250000}, {1, 560000} |
297 | }; |
298 | |
299 | /* Datasheet table: step time "Relationship with the ODR" (sample frequency) */ |
300 | static const unsigned int mma8452_time_step_us[4][8] = { |
301 | { 1250, 2500, 5000, 10000, 20000, 20000, 20000, 20000 }, /* normal */ |
302 | { 1250, 2500, 5000, 10000, 20000, 80000, 80000, 80000 }, /* l p l n */ |
303 | { 1250, 2500, 2500, 2500, 2500, 2500, 2500, 2500 }, /* high res*/ |
304 | { 1250, 2500, 5000, 10000, 20000, 80000, 160000, 160000 } /* l p */ |
305 | }; |
306 | |
307 | /* Datasheet table "High-Pass Filter Cutoff Options" */ |
308 | static const int mma8452_hp_filter_cutoff[4][8][4][2] = { |
309 | { /* normal */ |
310 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, /* 800 Hz sample */ |
311 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, /* 400 Hz sample */ |
312 | { {8, 0}, {4, 0}, {2, 0}, {1, 0} }, /* 200 Hz sample */ |
313 | { {4, 0}, {2, 0}, {1, 0}, {0, 500000} }, /* 100 Hz sample */ |
314 | { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, /* 50 Hz sample */ |
315 | { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, /* 12.5 Hz sample */ |
316 | { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, /* 6.25 Hz sample */ |
317 | { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} } /* 1.56 Hz sample */ |
318 | }, |
319 | { /* low noise low power */ |
320 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
321 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
322 | { {8, 0}, {4, 0}, {2, 0}, {1, 0} }, |
323 | { {4, 0}, {2, 0}, {1, 0}, {0, 500000} }, |
324 | { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, |
325 | { {0, 500000}, {0, 250000}, {0, 125000}, {0, 063000} }, |
326 | { {0, 500000}, {0, 250000}, {0, 125000}, {0, 063000} }, |
327 | { {0, 500000}, {0, 250000}, {0, 125000}, {0, 063000} } |
328 | }, |
329 | { /* high resolution */ |
330 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
331 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
332 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
333 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
334 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
335 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
336 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
337 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} } |
338 | }, |
339 | { /* low power */ |
340 | { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, |
341 | { {8, 0}, {4, 0}, {2, 0}, {1, 0} }, |
342 | { {4, 0}, {2, 0}, {1, 0}, {0, 500000} }, |
343 | { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, |
344 | { {1, 0}, {0, 500000}, {0, 250000}, {0, 125000} }, |
345 | { {0, 250000}, {0, 125000}, {0, 063000}, {0, 031000} }, |
346 | { {0, 250000}, {0, 125000}, {0, 063000}, {0, 031000} }, |
347 | { {0, 250000}, {0, 125000}, {0, 063000}, {0, 031000} } |
348 | } |
349 | }; |
350 | |
351 | /* Datasheet table "MODS Oversampling modes averaging values at each ODR" */ |
352 | static const u16 mma8452_os_ratio[4][8] = { |
353 | /* 800 Hz, 400 Hz, ... , 1.56 Hz */ |
354 | { 2, 4, 4, 4, 4, 16, 32, 128 }, /* normal */ |
355 | { 2, 4, 4, 4, 4, 4, 8, 32 }, /* low power low noise */ |
356 | { 2, 4, 8, 16, 32, 128, 256, 1024 }, /* high resolution */ |
357 | { 2, 2, 2, 2, 2, 2, 4, 16 } /* low power */ |
358 | }; |
359 | |
360 | static int mma8452_get_power_mode(struct mma8452_data *data) |
361 | { |
362 | int reg; |
363 | |
364 | reg = i2c_smbus_read_byte_data(client: data->client, |
365 | MMA8452_CTRL_REG2); |
366 | if (reg < 0) |
367 | return reg; |
368 | |
369 | return ((reg & MMA8452_CTRL_REG2_MODS_MASK) >> |
370 | MMA8452_CTRL_REG2_MODS_SHIFT); |
371 | } |
372 | |
373 | static ssize_t mma8452_show_samp_freq_avail(struct device *dev, |
374 | struct device_attribute *attr, |
375 | char *buf) |
376 | { |
377 | return mma8452_show_int_plus_micros(buf, vals: mma8452_samp_freq, |
378 | ARRAY_SIZE(mma8452_samp_freq)); |
379 | } |
380 | |
381 | static ssize_t mma8452_show_scale_avail(struct device *dev, |
382 | struct device_attribute *attr, |
383 | char *buf) |
384 | { |
385 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
386 | struct mma8452_data *data = iio_priv(indio_dev); |
387 | |
388 | return mma8452_show_int_plus_micros(buf, vals: data->chip_info->mma_scales, |
389 | ARRAY_SIZE(data->chip_info->mma_scales)); |
390 | } |
391 | |
392 | static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev, |
393 | struct device_attribute *attr, |
394 | char *buf) |
395 | { |
396 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
397 | struct mma8452_data *data = iio_priv(indio_dev); |
398 | int i, j; |
399 | |
400 | i = mma8452_get_odr_index(data); |
401 | j = mma8452_get_power_mode(data); |
402 | if (j < 0) |
403 | return j; |
404 | |
405 | return mma8452_show_int_plus_micros(buf, vals: mma8452_hp_filter_cutoff[j][i], |
406 | ARRAY_SIZE(mma8452_hp_filter_cutoff[0][0])); |
407 | } |
408 | |
409 | static ssize_t mma8452_show_os_ratio_avail(struct device *dev, |
410 | struct device_attribute *attr, |
411 | char *buf) |
412 | { |
413 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
414 | struct mma8452_data *data = iio_priv(indio_dev); |
415 | int i = mma8452_get_odr_index(data); |
416 | int j; |
417 | u16 val = 0; |
418 | size_t len = 0; |
419 | |
420 | for (j = 0; j < ARRAY_SIZE(mma8452_os_ratio); j++) { |
421 | if (val == mma8452_os_ratio[j][i]) |
422 | continue; |
423 | |
424 | val = mma8452_os_ratio[j][i]; |
425 | |
426 | len += scnprintf(buf: buf + len, PAGE_SIZE - len, fmt: "%d " , val); |
427 | } |
428 | buf[len - 1] = '\n'; |
429 | |
430 | return len; |
431 | } |
432 | |
433 | static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail); |
434 | static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, |
435 | mma8452_show_scale_avail, NULL, 0); |
436 | static IIO_DEVICE_ATTR(in_accel_filter_high_pass_3db_frequency_available, |
437 | 0444, mma8452_show_hp_cutoff_avail, NULL, 0); |
438 | static IIO_DEVICE_ATTR(in_accel_oversampling_ratio_available, 0444, |
439 | mma8452_show_os_ratio_avail, NULL, 0); |
440 | |
441 | static int mma8452_get_samp_freq_index(struct mma8452_data *data, |
442 | int val, int val2) |
443 | { |
444 | return mma8452_get_int_plus_micros_index(vals: mma8452_samp_freq, |
445 | ARRAY_SIZE(mma8452_samp_freq), |
446 | val, val2); |
447 | } |
448 | |
449 | static int mma8452_get_scale_index(struct mma8452_data *data, int val, int val2) |
450 | { |
451 | return mma8452_get_int_plus_micros_index(vals: data->chip_info->mma_scales, |
452 | ARRAY_SIZE(data->chip_info->mma_scales), val, val2); |
453 | } |
454 | |
455 | static int mma8452_get_hp_filter_index(struct mma8452_data *data, |
456 | int val, int val2) |
457 | { |
458 | int i, j; |
459 | |
460 | i = mma8452_get_odr_index(data); |
461 | j = mma8452_get_power_mode(data); |
462 | if (j < 0) |
463 | return j; |
464 | |
465 | return mma8452_get_int_plus_micros_index(vals: mma8452_hp_filter_cutoff[j][i], |
466 | ARRAY_SIZE(mma8452_hp_filter_cutoff[0][0]), val, val2); |
467 | } |
468 | |
469 | static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz) |
470 | { |
471 | int j, i, ret; |
472 | |
473 | ret = i2c_smbus_read_byte_data(client: data->client, MMA8452_HP_FILTER_CUTOFF); |
474 | if (ret < 0) |
475 | return ret; |
476 | |
477 | i = mma8452_get_odr_index(data); |
478 | j = mma8452_get_power_mode(data); |
479 | if (j < 0) |
480 | return j; |
481 | |
482 | ret &= MMA8452_HP_FILTER_CUTOFF_SEL_MASK; |
483 | *hz = mma8452_hp_filter_cutoff[j][i][ret][0]; |
484 | *uHz = mma8452_hp_filter_cutoff[j][i][ret][1]; |
485 | |
486 | return 0; |
487 | } |
488 | |
489 | static int mma8452_read_raw(struct iio_dev *indio_dev, |
490 | struct iio_chan_spec const *chan, |
491 | int *val, int *val2, long mask) |
492 | { |
493 | struct mma8452_data *data = iio_priv(indio_dev); |
494 | __be16 buffer[3]; |
495 | int i, ret; |
496 | |
497 | switch (mask) { |
498 | case IIO_CHAN_INFO_RAW: |
499 | ret = iio_device_claim_direct_mode(indio_dev); |
500 | if (ret) |
501 | return ret; |
502 | |
503 | mutex_lock(&data->lock); |
504 | ret = mma8452_read(data, buf: buffer); |
505 | mutex_unlock(lock: &data->lock); |
506 | iio_device_release_direct_mode(indio_dev); |
507 | if (ret < 0) |
508 | return ret; |
509 | |
510 | *val = sign_extend32(be16_to_cpu( |
511 | buffer[chan->scan_index]) >> chan->scan_type.shift, |
512 | index: chan->scan_type.realbits - 1); |
513 | |
514 | return IIO_VAL_INT; |
515 | case IIO_CHAN_INFO_SCALE: |
516 | i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK; |
517 | *val = data->chip_info->mma_scales[i][0]; |
518 | *val2 = data->chip_info->mma_scales[i][1]; |
519 | |
520 | return IIO_VAL_INT_PLUS_MICRO; |
521 | case IIO_CHAN_INFO_SAMP_FREQ: |
522 | i = mma8452_get_odr_index(data); |
523 | *val = mma8452_samp_freq[i][0]; |
524 | *val2 = mma8452_samp_freq[i][1]; |
525 | |
526 | return IIO_VAL_INT_PLUS_MICRO; |
527 | case IIO_CHAN_INFO_CALIBBIAS: |
528 | ret = i2c_smbus_read_byte_data(client: data->client, |
529 | MMA8452_OFF_X + |
530 | chan->scan_index); |
531 | if (ret < 0) |
532 | return ret; |
533 | |
534 | *val = sign_extend32(value: ret, index: 7); |
535 | |
536 | return IIO_VAL_INT; |
537 | case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: |
538 | if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) { |
539 | ret = mma8452_read_hp_filter(data, hz: val, uHz: val2); |
540 | if (ret < 0) |
541 | return ret; |
542 | } else { |
543 | *val = 0; |
544 | *val2 = 0; |
545 | } |
546 | |
547 | return IIO_VAL_INT_PLUS_MICRO; |
548 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
549 | ret = mma8452_get_power_mode(data); |
550 | if (ret < 0) |
551 | return ret; |
552 | |
553 | i = mma8452_get_odr_index(data); |
554 | |
555 | *val = mma8452_os_ratio[ret][i]; |
556 | return IIO_VAL_INT; |
557 | } |
558 | |
559 | return -EINVAL; |
560 | } |
561 | |
562 | static int mma8452_calculate_sleep(struct mma8452_data *data) |
563 | { |
564 | int ret, i = mma8452_get_odr_index(data); |
565 | |
566 | if (mma8452_samp_freq[i][0] > 0) |
567 | ret = 1000 / mma8452_samp_freq[i][0]; |
568 | else |
569 | ret = 1000; |
570 | |
571 | return ret == 0 ? 1 : ret; |
572 | } |
573 | |
574 | static int mma8452_standby(struct mma8452_data *data) |
575 | { |
576 | return i2c_smbus_write_byte_data(client: data->client, MMA8452_CTRL_REG1, |
577 | value: data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE); |
578 | } |
579 | |
580 | static int mma8452_active(struct mma8452_data *data) |
581 | { |
582 | return i2c_smbus_write_byte_data(client: data->client, MMA8452_CTRL_REG1, |
583 | value: data->ctrl_reg1); |
584 | } |
585 | |
586 | /* returns >0 if active, 0 if in standby and <0 on error */ |
587 | static int mma8452_is_active(struct mma8452_data *data) |
588 | { |
589 | int reg; |
590 | |
591 | reg = i2c_smbus_read_byte_data(client: data->client, MMA8452_CTRL_REG1); |
592 | if (reg < 0) |
593 | return reg; |
594 | |
595 | return reg & MMA8452_CTRL_ACTIVE; |
596 | } |
597 | |
598 | static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val) |
599 | { |
600 | int ret; |
601 | int is_active; |
602 | |
603 | mutex_lock(&data->lock); |
604 | |
605 | is_active = mma8452_is_active(data); |
606 | if (is_active < 0) { |
607 | ret = is_active; |
608 | goto fail; |
609 | } |
610 | |
611 | /* config can only be changed when in standby */ |
612 | if (is_active > 0) { |
613 | ret = mma8452_standby(data); |
614 | if (ret < 0) |
615 | goto fail; |
616 | } |
617 | |
618 | ret = i2c_smbus_write_byte_data(client: data->client, command: reg, value: val); |
619 | if (ret < 0) |
620 | goto fail; |
621 | |
622 | if (is_active > 0) { |
623 | ret = mma8452_active(data); |
624 | if (ret < 0) |
625 | goto fail; |
626 | } |
627 | |
628 | ret = 0; |
629 | fail: |
630 | mutex_unlock(lock: &data->lock); |
631 | |
632 | return ret; |
633 | } |
634 | |
635 | static int mma8452_set_power_mode(struct mma8452_data *data, u8 mode) |
636 | { |
637 | int reg; |
638 | |
639 | reg = i2c_smbus_read_byte_data(client: data->client, |
640 | MMA8452_CTRL_REG2); |
641 | if (reg < 0) |
642 | return reg; |
643 | |
644 | reg &= ~MMA8452_CTRL_REG2_MODS_MASK; |
645 | reg |= mode << MMA8452_CTRL_REG2_MODS_SHIFT; |
646 | |
647 | return mma8452_change_config(data, MMA8452_CTRL_REG2, val: reg); |
648 | } |
649 | |
650 | /* returns >0 if in freefall mode, 0 if not or <0 if an error occurred */ |
651 | static int mma8452_freefall_mode_enabled(struct mma8452_data *data) |
652 | { |
653 | int val; |
654 | |
655 | val = i2c_smbus_read_byte_data(client: data->client, MMA8452_FF_MT_CFG); |
656 | if (val < 0) |
657 | return val; |
658 | |
659 | return !(val & MMA8452_FF_MT_CFG_OAE); |
660 | } |
661 | |
662 | static int mma8452_set_freefall_mode(struct mma8452_data *data, bool state) |
663 | { |
664 | int val; |
665 | |
666 | if ((state && mma8452_freefall_mode_enabled(data)) || |
667 | (!state && !(mma8452_freefall_mode_enabled(data)))) |
668 | return 0; |
669 | |
670 | val = i2c_smbus_read_byte_data(client: data->client, MMA8452_FF_MT_CFG); |
671 | if (val < 0) |
672 | return val; |
673 | |
674 | if (state) { |
675 | val |= BIT(idx_x + MMA8452_FF_MT_CHAN_SHIFT); |
676 | val |= BIT(idx_y + MMA8452_FF_MT_CHAN_SHIFT); |
677 | val |= BIT(idx_z + MMA8452_FF_MT_CHAN_SHIFT); |
678 | val &= ~MMA8452_FF_MT_CFG_OAE; |
679 | } else { |
680 | val &= ~BIT(idx_x + MMA8452_FF_MT_CHAN_SHIFT); |
681 | val &= ~BIT(idx_y + MMA8452_FF_MT_CHAN_SHIFT); |
682 | val &= ~BIT(idx_z + MMA8452_FF_MT_CHAN_SHIFT); |
683 | val |= MMA8452_FF_MT_CFG_OAE; |
684 | } |
685 | |
686 | return mma8452_change_config(data, MMA8452_FF_MT_CFG, val); |
687 | } |
688 | |
689 | static int mma8452_set_hp_filter_frequency(struct mma8452_data *data, |
690 | int val, int val2) |
691 | { |
692 | int i, reg; |
693 | |
694 | i = mma8452_get_hp_filter_index(data, val, val2); |
695 | if (i < 0) |
696 | return i; |
697 | |
698 | reg = i2c_smbus_read_byte_data(client: data->client, |
699 | MMA8452_HP_FILTER_CUTOFF); |
700 | if (reg < 0) |
701 | return reg; |
702 | |
703 | reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK; |
704 | reg |= i; |
705 | |
706 | return mma8452_change_config(data, MMA8452_HP_FILTER_CUTOFF, val: reg); |
707 | } |
708 | |
709 | static int mma8452_write_raw(struct iio_dev *indio_dev, |
710 | struct iio_chan_spec const *chan, |
711 | int val, int val2, long mask) |
712 | { |
713 | struct mma8452_data *data = iio_priv(indio_dev); |
714 | int i, ret; |
715 | |
716 | ret = iio_device_claim_direct_mode(indio_dev); |
717 | if (ret) |
718 | return ret; |
719 | |
720 | switch (mask) { |
721 | case IIO_CHAN_INFO_SAMP_FREQ: |
722 | i = mma8452_get_samp_freq_index(data, val, val2); |
723 | if (i < 0) { |
724 | ret = i; |
725 | break; |
726 | } |
727 | data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK; |
728 | data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT; |
729 | |
730 | data->sleep_val = mma8452_calculate_sleep(data); |
731 | |
732 | ret = mma8452_change_config(data, MMA8452_CTRL_REG1, |
733 | val: data->ctrl_reg1); |
734 | break; |
735 | case IIO_CHAN_INFO_SCALE: |
736 | i = mma8452_get_scale_index(data, val, val2); |
737 | if (i < 0) { |
738 | ret = i; |
739 | break; |
740 | } |
741 | |
742 | data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK; |
743 | data->data_cfg |= i; |
744 | |
745 | ret = mma8452_change_config(data, MMA8452_DATA_CFG, |
746 | val: data->data_cfg); |
747 | break; |
748 | case IIO_CHAN_INFO_CALIBBIAS: |
749 | if (val < -128 || val > 127) { |
750 | ret = -EINVAL; |
751 | break; |
752 | } |
753 | |
754 | ret = mma8452_change_config(data, |
755 | MMA8452_OFF_X + chan->scan_index, |
756 | val); |
757 | break; |
758 | |
759 | case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: |
760 | if (val == 0 && val2 == 0) { |
761 | data->data_cfg &= ~MMA8452_DATA_CFG_HPF_MASK; |
762 | } else { |
763 | data->data_cfg |= MMA8452_DATA_CFG_HPF_MASK; |
764 | ret = mma8452_set_hp_filter_frequency(data, val, val2); |
765 | if (ret < 0) |
766 | break; |
767 | } |
768 | |
769 | ret = mma8452_change_config(data, MMA8452_DATA_CFG, |
770 | val: data->data_cfg); |
771 | break; |
772 | |
773 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
774 | ret = mma8452_get_odr_index(data); |
775 | |
776 | for (i = 0; i < ARRAY_SIZE(mma8452_os_ratio); i++) { |
777 | if (mma8452_os_ratio[i][ret] == val) { |
778 | ret = mma8452_set_power_mode(data, mode: i); |
779 | break; |
780 | } |
781 | } |
782 | break; |
783 | default: |
784 | ret = -EINVAL; |
785 | break; |
786 | } |
787 | |
788 | iio_device_release_direct_mode(indio_dev); |
789 | return ret; |
790 | } |
791 | |
792 | static int mma8452_get_event_regs(struct mma8452_data *data, |
793 | const struct iio_chan_spec *chan, enum iio_event_direction dir, |
794 | const struct mma8452_event_regs **ev_reg) |
795 | { |
796 | if (!chan) |
797 | return -EINVAL; |
798 | |
799 | switch (chan->type) { |
800 | case IIO_ACCEL: |
801 | switch (dir) { |
802 | case IIO_EV_DIR_RISING: |
803 | if ((data->chip_info->all_events |
804 | & MMA8452_INT_TRANS) && |
805 | (data->chip_info->enabled_events |
806 | & MMA8452_INT_TRANS)) |
807 | *ev_reg = &trans_ev_regs; |
808 | else |
809 | *ev_reg = &ff_mt_ev_regs; |
810 | return 0; |
811 | case IIO_EV_DIR_FALLING: |
812 | *ev_reg = &ff_mt_ev_regs; |
813 | return 0; |
814 | default: |
815 | return -EINVAL; |
816 | } |
817 | default: |
818 | return -EINVAL; |
819 | } |
820 | } |
821 | |
822 | static int mma8452_read_event_value(struct iio_dev *indio_dev, |
823 | const struct iio_chan_spec *chan, |
824 | enum iio_event_type type, |
825 | enum iio_event_direction dir, |
826 | enum iio_event_info info, |
827 | int *val, int *val2) |
828 | { |
829 | struct mma8452_data *data = iio_priv(indio_dev); |
830 | int ret, us, power_mode; |
831 | const struct mma8452_event_regs *ev_regs; |
832 | |
833 | ret = mma8452_get_event_regs(data, chan, dir, ev_reg: &ev_regs); |
834 | if (ret) |
835 | return ret; |
836 | |
837 | switch (info) { |
838 | case IIO_EV_INFO_VALUE: |
839 | ret = i2c_smbus_read_byte_data(client: data->client, command: ev_regs->ev_ths); |
840 | if (ret < 0) |
841 | return ret; |
842 | |
843 | *val = ret & ev_regs->ev_ths_mask; |
844 | |
845 | return IIO_VAL_INT; |
846 | |
847 | case IIO_EV_INFO_PERIOD: |
848 | ret = i2c_smbus_read_byte_data(client: data->client, command: ev_regs->ev_count); |
849 | if (ret < 0) |
850 | return ret; |
851 | |
852 | power_mode = mma8452_get_power_mode(data); |
853 | if (power_mode < 0) |
854 | return power_mode; |
855 | |
856 | us = ret * mma8452_time_step_us[power_mode][ |
857 | mma8452_get_odr_index(data)]; |
858 | *val = us / USEC_PER_SEC; |
859 | *val2 = us % USEC_PER_SEC; |
860 | |
861 | return IIO_VAL_INT_PLUS_MICRO; |
862 | |
863 | case IIO_EV_INFO_HIGH_PASS_FILTER_3DB: |
864 | ret = i2c_smbus_read_byte_data(client: data->client, |
865 | MMA8452_TRANSIENT_CFG); |
866 | if (ret < 0) |
867 | return ret; |
868 | |
869 | if (ret & MMA8452_TRANSIENT_CFG_HPF_BYP) { |
870 | *val = 0; |
871 | *val2 = 0; |
872 | } else { |
873 | ret = mma8452_read_hp_filter(data, hz: val, uHz: val2); |
874 | if (ret < 0) |
875 | return ret; |
876 | } |
877 | |
878 | return IIO_VAL_INT_PLUS_MICRO; |
879 | |
880 | default: |
881 | return -EINVAL; |
882 | } |
883 | } |
884 | |
885 | static int mma8452_write_event_value(struct iio_dev *indio_dev, |
886 | const struct iio_chan_spec *chan, |
887 | enum iio_event_type type, |
888 | enum iio_event_direction dir, |
889 | enum iio_event_info info, |
890 | int val, int val2) |
891 | { |
892 | struct mma8452_data *data = iio_priv(indio_dev); |
893 | int ret, reg, steps; |
894 | const struct mma8452_event_regs *ev_regs; |
895 | |
896 | ret = mma8452_get_event_regs(data, chan, dir, ev_reg: &ev_regs); |
897 | if (ret) |
898 | return ret; |
899 | |
900 | switch (info) { |
901 | case IIO_EV_INFO_VALUE: |
902 | if (val < 0 || val > ev_regs->ev_ths_mask) |
903 | return -EINVAL; |
904 | |
905 | return mma8452_change_config(data, reg: ev_regs->ev_ths, val); |
906 | |
907 | case IIO_EV_INFO_PERIOD: |
908 | ret = mma8452_get_power_mode(data); |
909 | if (ret < 0) |
910 | return ret; |
911 | |
912 | steps = (val * USEC_PER_SEC + val2) / |
913 | mma8452_time_step_us[ret][ |
914 | mma8452_get_odr_index(data)]; |
915 | |
916 | if (steps < 0 || steps > 0xff) |
917 | return -EINVAL; |
918 | |
919 | return mma8452_change_config(data, reg: ev_regs->ev_count, val: steps); |
920 | |
921 | case IIO_EV_INFO_HIGH_PASS_FILTER_3DB: |
922 | reg = i2c_smbus_read_byte_data(client: data->client, |
923 | MMA8452_TRANSIENT_CFG); |
924 | if (reg < 0) |
925 | return reg; |
926 | |
927 | if (val == 0 && val2 == 0) { |
928 | reg |= MMA8452_TRANSIENT_CFG_HPF_BYP; |
929 | } else { |
930 | reg &= ~MMA8452_TRANSIENT_CFG_HPF_BYP; |
931 | ret = mma8452_set_hp_filter_frequency(data, val, val2); |
932 | if (ret < 0) |
933 | return ret; |
934 | } |
935 | |
936 | return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, val: reg); |
937 | |
938 | default: |
939 | return -EINVAL; |
940 | } |
941 | } |
942 | |
943 | static int mma8452_read_event_config(struct iio_dev *indio_dev, |
944 | const struct iio_chan_spec *chan, |
945 | enum iio_event_type type, |
946 | enum iio_event_direction dir) |
947 | { |
948 | struct mma8452_data *data = iio_priv(indio_dev); |
949 | int ret; |
950 | const struct mma8452_event_regs *ev_regs; |
951 | |
952 | ret = mma8452_get_event_regs(data, chan, dir, ev_reg: &ev_regs); |
953 | if (ret) |
954 | return ret; |
955 | |
956 | switch (dir) { |
957 | case IIO_EV_DIR_FALLING: |
958 | return mma8452_freefall_mode_enabled(data); |
959 | case IIO_EV_DIR_RISING: |
960 | ret = i2c_smbus_read_byte_data(client: data->client, |
961 | command: ev_regs->ev_cfg); |
962 | if (ret < 0) |
963 | return ret; |
964 | |
965 | return !!(ret & BIT(chan->scan_index + |
966 | ev_regs->ev_cfg_chan_shift)); |
967 | default: |
968 | return -EINVAL; |
969 | } |
970 | } |
971 | |
972 | static int mma8452_write_event_config(struct iio_dev *indio_dev, |
973 | const struct iio_chan_spec *chan, |
974 | enum iio_event_type type, |
975 | enum iio_event_direction dir, |
976 | int state) |
977 | { |
978 | struct mma8452_data *data = iio_priv(indio_dev); |
979 | int val, ret; |
980 | const struct mma8452_event_regs *ev_regs; |
981 | |
982 | ret = mma8452_get_event_regs(data, chan, dir, ev_reg: &ev_regs); |
983 | if (ret) |
984 | return ret; |
985 | |
986 | ret = mma8452_set_runtime_pm_state(client: data->client, on: state); |
987 | if (ret) |
988 | return ret; |
989 | |
990 | switch (dir) { |
991 | case IIO_EV_DIR_FALLING: |
992 | return mma8452_set_freefall_mode(data, state); |
993 | case IIO_EV_DIR_RISING: |
994 | val = i2c_smbus_read_byte_data(client: data->client, command: ev_regs->ev_cfg); |
995 | if (val < 0) |
996 | return val; |
997 | |
998 | if (state) { |
999 | if (mma8452_freefall_mode_enabled(data)) { |
1000 | val &= ~BIT(idx_x + ev_regs->ev_cfg_chan_shift); |
1001 | val &= ~BIT(idx_y + ev_regs->ev_cfg_chan_shift); |
1002 | val &= ~BIT(idx_z + ev_regs->ev_cfg_chan_shift); |
1003 | val |= MMA8452_FF_MT_CFG_OAE; |
1004 | } |
1005 | val |= BIT(chan->scan_index + |
1006 | ev_regs->ev_cfg_chan_shift); |
1007 | } else { |
1008 | if (mma8452_freefall_mode_enabled(data)) |
1009 | return 0; |
1010 | |
1011 | val &= ~BIT(chan->scan_index + |
1012 | ev_regs->ev_cfg_chan_shift); |
1013 | } |
1014 | |
1015 | val |= ev_regs->ev_cfg_ele; |
1016 | |
1017 | return mma8452_change_config(data, reg: ev_regs->ev_cfg, val); |
1018 | default: |
1019 | return -EINVAL; |
1020 | } |
1021 | } |
1022 | |
1023 | static void mma8452_transient_interrupt(struct iio_dev *indio_dev) |
1024 | { |
1025 | struct mma8452_data *data = iio_priv(indio_dev); |
1026 | s64 ts = iio_get_time_ns(indio_dev); |
1027 | int src; |
1028 | |
1029 | src = i2c_smbus_read_byte_data(client: data->client, MMA8452_TRANSIENT_SRC); |
1030 | if (src < 0) |
1031 | return; |
1032 | |
1033 | if (src & MMA8452_TRANSIENT_SRC_XTRANSE) |
1034 | iio_push_event(indio_dev, |
1035 | IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X, |
1036 | IIO_EV_TYPE_MAG, |
1037 | IIO_EV_DIR_RISING), |
1038 | timestamp: ts); |
1039 | |
1040 | if (src & MMA8452_TRANSIENT_SRC_YTRANSE) |
1041 | iio_push_event(indio_dev, |
1042 | IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Y, |
1043 | IIO_EV_TYPE_MAG, |
1044 | IIO_EV_DIR_RISING), |
1045 | timestamp: ts); |
1046 | |
1047 | if (src & MMA8452_TRANSIENT_SRC_ZTRANSE) |
1048 | iio_push_event(indio_dev, |
1049 | IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Z, |
1050 | IIO_EV_TYPE_MAG, |
1051 | IIO_EV_DIR_RISING), |
1052 | timestamp: ts); |
1053 | } |
1054 | |
1055 | static irqreturn_t mma8452_interrupt(int irq, void *p) |
1056 | { |
1057 | struct iio_dev *indio_dev = p; |
1058 | struct mma8452_data *data = iio_priv(indio_dev); |
1059 | irqreturn_t ret = IRQ_NONE; |
1060 | int src; |
1061 | |
1062 | src = i2c_smbus_read_byte_data(client: data->client, MMA8452_INT_SRC); |
1063 | if (src < 0) |
1064 | return IRQ_NONE; |
1065 | |
1066 | if (!(src & (data->chip_info->enabled_events | MMA8452_INT_DRDY))) |
1067 | return IRQ_NONE; |
1068 | |
1069 | if (src & MMA8452_INT_DRDY) { |
1070 | iio_trigger_poll_nested(trig: indio_dev->trig); |
1071 | ret = IRQ_HANDLED; |
1072 | } |
1073 | |
1074 | if (src & MMA8452_INT_FF_MT) { |
1075 | if (mma8452_freefall_mode_enabled(data)) { |
1076 | s64 ts = iio_get_time_ns(indio_dev); |
1077 | |
1078 | iio_push_event(indio_dev, |
1079 | IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, |
1080 | IIO_MOD_X_AND_Y_AND_Z, |
1081 | IIO_EV_TYPE_MAG, |
1082 | IIO_EV_DIR_FALLING), |
1083 | timestamp: ts); |
1084 | } |
1085 | ret = IRQ_HANDLED; |
1086 | } |
1087 | |
1088 | if (src & MMA8452_INT_TRANS) { |
1089 | mma8452_transient_interrupt(indio_dev); |
1090 | ret = IRQ_HANDLED; |
1091 | } |
1092 | |
1093 | return ret; |
1094 | } |
1095 | |
1096 | static irqreturn_t mma8452_trigger_handler(int irq, void *p) |
1097 | { |
1098 | struct iio_poll_func *pf = p; |
1099 | struct iio_dev *indio_dev = pf->indio_dev; |
1100 | struct mma8452_data *data = iio_priv(indio_dev); |
1101 | int ret; |
1102 | |
1103 | ret = mma8452_read(data, buf: data->buffer.channels); |
1104 | if (ret < 0) |
1105 | goto done; |
1106 | |
1107 | iio_push_to_buffers_with_timestamp(indio_dev, data: &data->buffer, |
1108 | timestamp: iio_get_time_ns(indio_dev)); |
1109 | |
1110 | done: |
1111 | iio_trigger_notify_done(trig: indio_dev->trig); |
1112 | |
1113 | return IRQ_HANDLED; |
1114 | } |
1115 | |
1116 | static int mma8452_reg_access_dbg(struct iio_dev *indio_dev, |
1117 | unsigned int reg, unsigned int writeval, |
1118 | unsigned int *readval) |
1119 | { |
1120 | int ret; |
1121 | struct mma8452_data *data = iio_priv(indio_dev); |
1122 | |
1123 | if (reg > MMA8452_MAX_REG) |
1124 | return -EINVAL; |
1125 | |
1126 | if (!readval) |
1127 | return mma8452_change_config(data, reg, val: writeval); |
1128 | |
1129 | ret = i2c_smbus_read_byte_data(client: data->client, command: reg); |
1130 | if (ret < 0) |
1131 | return ret; |
1132 | |
1133 | *readval = ret; |
1134 | |
1135 | return 0; |
1136 | } |
1137 | |
1138 | static const struct iio_event_spec mma8452_freefall_event[] = { |
1139 | { |
1140 | .type = IIO_EV_TYPE_MAG, |
1141 | .dir = IIO_EV_DIR_FALLING, |
1142 | .mask_separate = BIT(IIO_EV_INFO_ENABLE), |
1143 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | |
1144 | BIT(IIO_EV_INFO_PERIOD) | |
1145 | BIT(IIO_EV_INFO_HIGH_PASS_FILTER_3DB) |
1146 | }, |
1147 | }; |
1148 | |
1149 | static const struct iio_event_spec mma8652_freefall_event[] = { |
1150 | { |
1151 | .type = IIO_EV_TYPE_MAG, |
1152 | .dir = IIO_EV_DIR_FALLING, |
1153 | .mask_separate = BIT(IIO_EV_INFO_ENABLE), |
1154 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | |
1155 | BIT(IIO_EV_INFO_PERIOD) |
1156 | }, |
1157 | }; |
1158 | |
1159 | static const struct iio_event_spec mma8452_transient_event[] = { |
1160 | { |
1161 | .type = IIO_EV_TYPE_MAG, |
1162 | .dir = IIO_EV_DIR_RISING, |
1163 | .mask_separate = BIT(IIO_EV_INFO_ENABLE), |
1164 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | |
1165 | BIT(IIO_EV_INFO_PERIOD) | |
1166 | BIT(IIO_EV_INFO_HIGH_PASS_FILTER_3DB) |
1167 | }, |
1168 | }; |
1169 | |
1170 | static const struct iio_event_spec mma8452_motion_event[] = { |
1171 | { |
1172 | .type = IIO_EV_TYPE_MAG, |
1173 | .dir = IIO_EV_DIR_RISING, |
1174 | .mask_separate = BIT(IIO_EV_INFO_ENABLE), |
1175 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | |
1176 | BIT(IIO_EV_INFO_PERIOD) |
1177 | }, |
1178 | }; |
1179 | |
1180 | /* |
1181 | * Threshold is configured in fixed 8G/127 steps regardless of |
1182 | * currently selected scale for measurement. |
1183 | */ |
1184 | static IIO_CONST_ATTR_NAMED(accel_transient_scale, in_accel_scale, "0.617742" ); |
1185 | |
1186 | static struct attribute *mma8452_event_attributes[] = { |
1187 | &iio_const_attr_accel_transient_scale.dev_attr.attr, |
1188 | NULL, |
1189 | }; |
1190 | |
1191 | static const struct attribute_group mma8452_event_attribute_group = { |
1192 | .attrs = mma8452_event_attributes, |
1193 | }; |
1194 | |
1195 | static const struct iio_mount_matrix * |
1196 | mma8452_get_mount_matrix(const struct iio_dev *indio_dev, |
1197 | const struct iio_chan_spec *chan) |
1198 | { |
1199 | struct mma8452_data *data = iio_priv(indio_dev); |
1200 | |
1201 | return &data->orientation; |
1202 | } |
1203 | |
1204 | static const struct iio_chan_spec_ext_info mma8452_ext_info[] = { |
1205 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, mma8452_get_mount_matrix), |
1206 | { } |
1207 | }; |
1208 | |
1209 | #define MMA8452_FREEFALL_CHANNEL(modifier) { \ |
1210 | .type = IIO_ACCEL, \ |
1211 | .modified = 1, \ |
1212 | .channel2 = modifier, \ |
1213 | .scan_index = -1, \ |
1214 | .event_spec = mma8452_freefall_event, \ |
1215 | .num_event_specs = ARRAY_SIZE(mma8452_freefall_event), \ |
1216 | } |
1217 | |
1218 | #define MMA8652_FREEFALL_CHANNEL(modifier) { \ |
1219 | .type = IIO_ACCEL, \ |
1220 | .modified = 1, \ |
1221 | .channel2 = modifier, \ |
1222 | .scan_index = -1, \ |
1223 | .event_spec = mma8652_freefall_event, \ |
1224 | .num_event_specs = ARRAY_SIZE(mma8652_freefall_event), \ |
1225 | } |
1226 | |
1227 | #define MMA8452_CHANNEL(axis, idx, bits) { \ |
1228 | .type = IIO_ACCEL, \ |
1229 | .modified = 1, \ |
1230 | .channel2 = IIO_MOD_##axis, \ |
1231 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
1232 | BIT(IIO_CHAN_INFO_CALIBBIAS), \ |
1233 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ |
1234 | BIT(IIO_CHAN_INFO_SCALE) | \ |
1235 | BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY) | \ |
1236 | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ |
1237 | .scan_index = idx, \ |
1238 | .scan_type = { \ |
1239 | .sign = 's', \ |
1240 | .realbits = (bits), \ |
1241 | .storagebits = 16, \ |
1242 | .shift = 16 - (bits), \ |
1243 | .endianness = IIO_BE, \ |
1244 | }, \ |
1245 | .event_spec = mma8452_transient_event, \ |
1246 | .num_event_specs = ARRAY_SIZE(mma8452_transient_event), \ |
1247 | .ext_info = mma8452_ext_info, \ |
1248 | } |
1249 | |
1250 | #define MMA8652_CHANNEL(axis, idx, bits) { \ |
1251 | .type = IIO_ACCEL, \ |
1252 | .modified = 1, \ |
1253 | .channel2 = IIO_MOD_##axis, \ |
1254 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
1255 | BIT(IIO_CHAN_INFO_CALIBBIAS), \ |
1256 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ |
1257 | BIT(IIO_CHAN_INFO_SCALE) | \ |
1258 | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ |
1259 | .scan_index = idx, \ |
1260 | .scan_type = { \ |
1261 | .sign = 's', \ |
1262 | .realbits = (bits), \ |
1263 | .storagebits = 16, \ |
1264 | .shift = 16 - (bits), \ |
1265 | .endianness = IIO_BE, \ |
1266 | }, \ |
1267 | .event_spec = mma8452_motion_event, \ |
1268 | .num_event_specs = ARRAY_SIZE(mma8452_motion_event), \ |
1269 | .ext_info = mma8452_ext_info, \ |
1270 | } |
1271 | |
1272 | static const struct iio_chan_spec mma8451_channels[] = { |
1273 | MMA8452_CHANNEL(X, idx_x, 14), |
1274 | MMA8452_CHANNEL(Y, idx_y, 14), |
1275 | MMA8452_CHANNEL(Z, idx_z, 14), |
1276 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
1277 | MMA8452_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z), |
1278 | }; |
1279 | |
1280 | static const struct iio_chan_spec mma8452_channels[] = { |
1281 | MMA8452_CHANNEL(X, idx_x, 12), |
1282 | MMA8452_CHANNEL(Y, idx_y, 12), |
1283 | MMA8452_CHANNEL(Z, idx_z, 12), |
1284 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
1285 | MMA8452_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z), |
1286 | }; |
1287 | |
1288 | static const struct iio_chan_spec mma8453_channels[] = { |
1289 | MMA8452_CHANNEL(X, idx_x, 10), |
1290 | MMA8452_CHANNEL(Y, idx_y, 10), |
1291 | MMA8452_CHANNEL(Z, idx_z, 10), |
1292 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
1293 | MMA8452_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z), |
1294 | }; |
1295 | |
1296 | static const struct iio_chan_spec mma8652_channels[] = { |
1297 | MMA8652_CHANNEL(X, idx_x, 12), |
1298 | MMA8652_CHANNEL(Y, idx_y, 12), |
1299 | MMA8652_CHANNEL(Z, idx_z, 12), |
1300 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
1301 | MMA8652_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z), |
1302 | }; |
1303 | |
1304 | static const struct iio_chan_spec mma8653_channels[] = { |
1305 | MMA8652_CHANNEL(X, idx_x, 10), |
1306 | MMA8652_CHANNEL(Y, idx_y, 10), |
1307 | MMA8652_CHANNEL(Z, idx_z, 10), |
1308 | IIO_CHAN_SOFT_TIMESTAMP(idx_ts), |
1309 | MMA8652_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z), |
1310 | }; |
1311 | |
1312 | enum { |
1313 | mma8451, |
1314 | mma8452, |
1315 | mma8453, |
1316 | mma8652, |
1317 | mma8653, |
1318 | fxls8471, |
1319 | }; |
1320 | |
1321 | static const struct mma_chip_info mma_chip_info_table[] = { |
1322 | [mma8451] = { |
1323 | .name = "mma8451" , |
1324 | .chip_id = MMA8451_DEVICE_ID, |
1325 | .channels = mma8451_channels, |
1326 | .num_channels = ARRAY_SIZE(mma8451_channels), |
1327 | /* |
1328 | * Hardware has fullscale of -2G, -4G, -8G corresponding to |
1329 | * raw value -8192 for 14 bit, -2048 for 12 bit or -512 for 10 |
1330 | * bit. |
1331 | * The userspace interface uses m/s^2 and we declare micro units |
1332 | * So scale factor for 12 bit here is given by: |
1333 | * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665 |
1334 | */ |
1335 | .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} }, |
1336 | /* |
1337 | * Although we enable the interrupt sources once and for |
1338 | * all here the event detection itself is not enabled until |
1339 | * userspace asks for it by mma8452_write_event_config() |
1340 | */ |
1341 | .all_events = MMA8452_INT_DRDY | |
1342 | MMA8452_INT_TRANS | |
1343 | MMA8452_INT_FF_MT, |
1344 | .enabled_events = MMA8452_INT_TRANS | |
1345 | MMA8452_INT_FF_MT, |
1346 | }, |
1347 | [mma8452] = { |
1348 | .name = "mma8452" , |
1349 | .chip_id = MMA8452_DEVICE_ID, |
1350 | .channels = mma8452_channels, |
1351 | .num_channels = ARRAY_SIZE(mma8452_channels), |
1352 | .mma_scales = { {0, 9577}, {0, 19154}, {0, 38307} }, |
1353 | /* |
1354 | * Although we enable the interrupt sources once and for |
1355 | * all here the event detection itself is not enabled until |
1356 | * userspace asks for it by mma8452_write_event_config() |
1357 | */ |
1358 | .all_events = MMA8452_INT_DRDY | |
1359 | MMA8452_INT_TRANS | |
1360 | MMA8452_INT_FF_MT, |
1361 | .enabled_events = MMA8452_INT_TRANS | |
1362 | MMA8452_INT_FF_MT, |
1363 | }, |
1364 | [mma8453] = { |
1365 | .name = "mma8453" , |
1366 | .chip_id = MMA8453_DEVICE_ID, |
1367 | .channels = mma8453_channels, |
1368 | .num_channels = ARRAY_SIZE(mma8453_channels), |
1369 | .mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} }, |
1370 | /* |
1371 | * Although we enable the interrupt sources once and for |
1372 | * all here the event detection itself is not enabled until |
1373 | * userspace asks for it by mma8452_write_event_config() |
1374 | */ |
1375 | .all_events = MMA8452_INT_DRDY | |
1376 | MMA8452_INT_TRANS | |
1377 | MMA8452_INT_FF_MT, |
1378 | .enabled_events = MMA8452_INT_TRANS | |
1379 | MMA8452_INT_FF_MT, |
1380 | }, |
1381 | [mma8652] = { |
1382 | .name = "mma8652" , |
1383 | .chip_id = MMA8652_DEVICE_ID, |
1384 | .channels = mma8652_channels, |
1385 | .num_channels = ARRAY_SIZE(mma8652_channels), |
1386 | .mma_scales = { {0, 9577}, {0, 19154}, {0, 38307} }, |
1387 | .all_events = MMA8452_INT_DRDY | |
1388 | MMA8452_INT_FF_MT, |
1389 | .enabled_events = MMA8452_INT_FF_MT, |
1390 | }, |
1391 | [mma8653] = { |
1392 | .name = "mma8653" , |
1393 | .chip_id = MMA8653_DEVICE_ID, |
1394 | .channels = mma8653_channels, |
1395 | .num_channels = ARRAY_SIZE(mma8653_channels), |
1396 | .mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} }, |
1397 | /* |
1398 | * Although we enable the interrupt sources once and for |
1399 | * all here the event detection itself is not enabled until |
1400 | * userspace asks for it by mma8452_write_event_config() |
1401 | */ |
1402 | .all_events = MMA8452_INT_DRDY | |
1403 | MMA8452_INT_FF_MT, |
1404 | .enabled_events = MMA8452_INT_FF_MT, |
1405 | }, |
1406 | [fxls8471] = { |
1407 | .name = "fxls8471" , |
1408 | .chip_id = FXLS8471_DEVICE_ID, |
1409 | .channels = mma8451_channels, |
1410 | .num_channels = ARRAY_SIZE(mma8451_channels), |
1411 | .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} }, |
1412 | /* |
1413 | * Although we enable the interrupt sources once and for |
1414 | * all here the event detection itself is not enabled until |
1415 | * userspace asks for it by mma8452_write_event_config() |
1416 | */ |
1417 | .all_events = MMA8452_INT_DRDY | |
1418 | MMA8452_INT_TRANS | |
1419 | MMA8452_INT_FF_MT, |
1420 | .enabled_events = MMA8452_INT_TRANS | |
1421 | MMA8452_INT_FF_MT, |
1422 | }, |
1423 | }; |
1424 | |
1425 | static struct attribute *mma8452_attributes[] = { |
1426 | &iio_dev_attr_sampling_frequency_available.dev_attr.attr, |
1427 | &iio_dev_attr_in_accel_scale_available.dev_attr.attr, |
1428 | &iio_dev_attr_in_accel_filter_high_pass_3db_frequency_available.dev_attr.attr, |
1429 | &iio_dev_attr_in_accel_oversampling_ratio_available.dev_attr.attr, |
1430 | NULL |
1431 | }; |
1432 | |
1433 | static const struct attribute_group mma8452_group = { |
1434 | .attrs = mma8452_attributes, |
1435 | }; |
1436 | |
1437 | static const struct iio_info mma8452_info = { |
1438 | .attrs = &mma8452_group, |
1439 | .read_raw = &mma8452_read_raw, |
1440 | .write_raw = &mma8452_write_raw, |
1441 | .event_attrs = &mma8452_event_attribute_group, |
1442 | .read_event_value = &mma8452_read_event_value, |
1443 | .write_event_value = &mma8452_write_event_value, |
1444 | .read_event_config = &mma8452_read_event_config, |
1445 | .write_event_config = &mma8452_write_event_config, |
1446 | .debugfs_reg_access = &mma8452_reg_access_dbg, |
1447 | }; |
1448 | |
1449 | static const unsigned long mma8452_scan_masks[] = {0x7, 0}; |
1450 | |
1451 | static int mma8452_data_rdy_trigger_set_state(struct iio_trigger *trig, |
1452 | bool state) |
1453 | { |
1454 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
1455 | struct mma8452_data *data = iio_priv(indio_dev); |
1456 | int reg, ret; |
1457 | |
1458 | ret = mma8452_set_runtime_pm_state(client: data->client, on: state); |
1459 | if (ret) |
1460 | return ret; |
1461 | |
1462 | reg = i2c_smbus_read_byte_data(client: data->client, MMA8452_CTRL_REG4); |
1463 | if (reg < 0) |
1464 | return reg; |
1465 | |
1466 | if (state) |
1467 | reg |= MMA8452_INT_DRDY; |
1468 | else |
1469 | reg &= ~MMA8452_INT_DRDY; |
1470 | |
1471 | return mma8452_change_config(data, MMA8452_CTRL_REG4, val: reg); |
1472 | } |
1473 | |
1474 | static const struct iio_trigger_ops mma8452_trigger_ops = { |
1475 | .set_trigger_state = mma8452_data_rdy_trigger_set_state, |
1476 | .validate_device = iio_trigger_validate_own_device, |
1477 | }; |
1478 | |
1479 | static int mma8452_trigger_setup(struct iio_dev *indio_dev) |
1480 | { |
1481 | struct mma8452_data *data = iio_priv(indio_dev); |
1482 | struct iio_trigger *trig; |
1483 | int ret; |
1484 | |
1485 | trig = devm_iio_trigger_alloc(&data->client->dev, "%s-dev%d" , |
1486 | indio_dev->name, |
1487 | iio_device_id(indio_dev)); |
1488 | if (!trig) |
1489 | return -ENOMEM; |
1490 | |
1491 | trig->ops = &mma8452_trigger_ops; |
1492 | iio_trigger_set_drvdata(trig, data: indio_dev); |
1493 | |
1494 | ret = iio_trigger_register(trig_info: trig); |
1495 | if (ret) |
1496 | return ret; |
1497 | |
1498 | indio_dev->trig = iio_trigger_get(trig); |
1499 | |
1500 | return 0; |
1501 | } |
1502 | |
1503 | static void mma8452_trigger_cleanup(struct iio_dev *indio_dev) |
1504 | { |
1505 | if (indio_dev->trig) |
1506 | iio_trigger_unregister(trig_info: indio_dev->trig); |
1507 | } |
1508 | |
1509 | static int mma8452_reset(struct i2c_client *client) |
1510 | { |
1511 | int i; |
1512 | int ret; |
1513 | |
1514 | /* |
1515 | * Find on fxls8471, after config reset bit, it reset immediately, |
1516 | * and will not give ACK, so here do not check the return value. |
1517 | * The following code will read the reset register, and check whether |
1518 | * this reset works. |
1519 | */ |
1520 | i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG2, |
1521 | MMA8452_CTRL_REG2_RST); |
1522 | |
1523 | for (i = 0; i < 10; i++) { |
1524 | usleep_range(min: 100, max: 200); |
1525 | ret = i2c_smbus_read_byte_data(client, MMA8452_CTRL_REG2); |
1526 | if (ret == -EIO) |
1527 | continue; /* I2C comm reset */ |
1528 | if (ret < 0) |
1529 | return ret; |
1530 | if (!(ret & MMA8452_CTRL_REG2_RST)) |
1531 | return 0; |
1532 | } |
1533 | |
1534 | return -ETIMEDOUT; |
1535 | } |
1536 | |
1537 | static const struct of_device_id mma8452_dt_ids[] = { |
1538 | { .compatible = "fsl,fxls8471" , .data = &mma_chip_info_table[fxls8471] }, |
1539 | { .compatible = "fsl,mma8451" , .data = &mma_chip_info_table[mma8451] }, |
1540 | { .compatible = "fsl,mma8452" , .data = &mma_chip_info_table[mma8452] }, |
1541 | { .compatible = "fsl,mma8453" , .data = &mma_chip_info_table[mma8453] }, |
1542 | { .compatible = "fsl,mma8652" , .data = &mma_chip_info_table[mma8652] }, |
1543 | { .compatible = "fsl,mma8653" , .data = &mma_chip_info_table[mma8653] }, |
1544 | { } |
1545 | }; |
1546 | MODULE_DEVICE_TABLE(of, mma8452_dt_ids); |
1547 | |
1548 | static int mma8452_probe(struct i2c_client *client) |
1549 | { |
1550 | struct mma8452_data *data; |
1551 | struct iio_dev *indio_dev; |
1552 | int ret; |
1553 | |
1554 | indio_dev = devm_iio_device_alloc(parent: &client->dev, sizeof_priv: sizeof(*data)); |
1555 | if (!indio_dev) |
1556 | return -ENOMEM; |
1557 | |
1558 | data = iio_priv(indio_dev); |
1559 | data->client = client; |
1560 | mutex_init(&data->lock); |
1561 | |
1562 | data->chip_info = i2c_get_match_data(client); |
1563 | if (!data->chip_info) |
1564 | return dev_err_probe(dev: &client->dev, err: -ENODEV, |
1565 | fmt: "unknown device model\n" ); |
1566 | |
1567 | ret = iio_read_mount_matrix(dev: &client->dev, matrix: &data->orientation); |
1568 | if (ret) |
1569 | return ret; |
1570 | |
1571 | data->vdd_reg = devm_regulator_get(dev: &client->dev, id: "vdd" ); |
1572 | if (IS_ERR(ptr: data->vdd_reg)) |
1573 | return dev_err_probe(dev: &client->dev, err: PTR_ERR(ptr: data->vdd_reg), |
1574 | fmt: "failed to get VDD regulator!\n" ); |
1575 | |
1576 | data->vddio_reg = devm_regulator_get(dev: &client->dev, id: "vddio" ); |
1577 | if (IS_ERR(ptr: data->vddio_reg)) |
1578 | return dev_err_probe(dev: &client->dev, err: PTR_ERR(ptr: data->vddio_reg), |
1579 | fmt: "failed to get VDDIO regulator!\n" ); |
1580 | |
1581 | ret = regulator_enable(regulator: data->vdd_reg); |
1582 | if (ret) { |
1583 | dev_err(&client->dev, "failed to enable VDD regulator!\n" ); |
1584 | return ret; |
1585 | } |
1586 | |
1587 | ret = regulator_enable(regulator: data->vddio_reg); |
1588 | if (ret) { |
1589 | dev_err(&client->dev, "failed to enable VDDIO regulator!\n" ); |
1590 | goto disable_regulator_vdd; |
1591 | } |
1592 | |
1593 | ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I); |
1594 | if (ret < 0) |
1595 | goto disable_regulators; |
1596 | |
1597 | switch (ret) { |
1598 | case MMA8451_DEVICE_ID: |
1599 | case MMA8452_DEVICE_ID: |
1600 | case MMA8453_DEVICE_ID: |
1601 | case MMA8652_DEVICE_ID: |
1602 | case MMA8653_DEVICE_ID: |
1603 | case FXLS8471_DEVICE_ID: |
1604 | if (ret == data->chip_info->chip_id) |
1605 | break; |
1606 | fallthrough; |
1607 | default: |
1608 | ret = -ENODEV; |
1609 | goto disable_regulators; |
1610 | } |
1611 | |
1612 | dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n" , |
1613 | data->chip_info->name, data->chip_info->chip_id); |
1614 | |
1615 | i2c_set_clientdata(client, data: indio_dev); |
1616 | indio_dev->info = &mma8452_info; |
1617 | indio_dev->name = data->chip_info->name; |
1618 | indio_dev->modes = INDIO_DIRECT_MODE; |
1619 | indio_dev->channels = data->chip_info->channels; |
1620 | indio_dev->num_channels = data->chip_info->num_channels; |
1621 | indio_dev->available_scan_masks = mma8452_scan_masks; |
1622 | |
1623 | ret = mma8452_reset(client); |
1624 | if (ret < 0) |
1625 | goto disable_regulators; |
1626 | |
1627 | data->data_cfg = MMA8452_DATA_CFG_FS_2G; |
1628 | ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG, |
1629 | value: data->data_cfg); |
1630 | if (ret < 0) |
1631 | goto disable_regulators; |
1632 | |
1633 | /* |
1634 | * By default set transient threshold to max to avoid events if |
1635 | * enabling without configuring threshold. |
1636 | */ |
1637 | ret = i2c_smbus_write_byte_data(client, MMA8452_TRANSIENT_THS, |
1638 | MMA8452_TRANSIENT_THS_MASK); |
1639 | if (ret < 0) |
1640 | goto disable_regulators; |
1641 | |
1642 | if (client->irq) { |
1643 | int irq2; |
1644 | |
1645 | irq2 = of_irq_get_byname(dev: client->dev.of_node, name: "INT2" ); |
1646 | |
1647 | if (irq2 == client->irq) { |
1648 | dev_dbg(&client->dev, "using interrupt line INT2\n" ); |
1649 | } else { |
1650 | ret = i2c_smbus_write_byte_data(client, |
1651 | MMA8452_CTRL_REG5, |
1652 | value: data->chip_info->all_events); |
1653 | if (ret < 0) |
1654 | goto disable_regulators; |
1655 | |
1656 | dev_dbg(&client->dev, "using interrupt line INT1\n" ); |
1657 | } |
1658 | |
1659 | ret = i2c_smbus_write_byte_data(client, |
1660 | MMA8452_CTRL_REG4, |
1661 | value: data->chip_info->enabled_events); |
1662 | if (ret < 0) |
1663 | goto disable_regulators; |
1664 | |
1665 | ret = mma8452_trigger_setup(indio_dev); |
1666 | if (ret < 0) |
1667 | goto disable_regulators; |
1668 | } |
1669 | |
1670 | data->ctrl_reg1 = MMA8452_CTRL_ACTIVE | |
1671 | (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT); |
1672 | |
1673 | data->sleep_val = mma8452_calculate_sleep(data); |
1674 | |
1675 | ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1, |
1676 | value: data->ctrl_reg1); |
1677 | if (ret < 0) |
1678 | goto trigger_cleanup; |
1679 | |
1680 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
1681 | mma8452_trigger_handler, NULL); |
1682 | if (ret < 0) |
1683 | goto trigger_cleanup; |
1684 | |
1685 | if (client->irq) { |
1686 | ret = devm_request_threaded_irq(dev: &client->dev, |
1687 | irq: client->irq, |
1688 | NULL, thread_fn: mma8452_interrupt, |
1689 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
1690 | devname: client->name, dev_id: indio_dev); |
1691 | if (ret) |
1692 | goto buffer_cleanup; |
1693 | } |
1694 | |
1695 | ret = pm_runtime_set_active(dev: &client->dev); |
1696 | if (ret < 0) |
1697 | goto buffer_cleanup; |
1698 | |
1699 | pm_runtime_enable(dev: &client->dev); |
1700 | pm_runtime_set_autosuspend_delay(dev: &client->dev, |
1701 | MMA8452_AUTO_SUSPEND_DELAY_MS); |
1702 | pm_runtime_use_autosuspend(dev: &client->dev); |
1703 | |
1704 | ret = iio_device_register(indio_dev); |
1705 | if (ret < 0) |
1706 | goto buffer_cleanup; |
1707 | |
1708 | ret = mma8452_set_freefall_mode(data, state: false); |
1709 | if (ret < 0) |
1710 | goto unregister_device; |
1711 | |
1712 | return 0; |
1713 | |
1714 | unregister_device: |
1715 | iio_device_unregister(indio_dev); |
1716 | |
1717 | buffer_cleanup: |
1718 | iio_triggered_buffer_cleanup(indio_dev); |
1719 | |
1720 | trigger_cleanup: |
1721 | mma8452_trigger_cleanup(indio_dev); |
1722 | |
1723 | disable_regulators: |
1724 | regulator_disable(regulator: data->vddio_reg); |
1725 | |
1726 | disable_regulator_vdd: |
1727 | regulator_disable(regulator: data->vdd_reg); |
1728 | |
1729 | return ret; |
1730 | } |
1731 | |
1732 | static void mma8452_remove(struct i2c_client *client) |
1733 | { |
1734 | struct iio_dev *indio_dev = i2c_get_clientdata(client); |
1735 | struct mma8452_data *data = iio_priv(indio_dev); |
1736 | |
1737 | iio_device_unregister(indio_dev); |
1738 | |
1739 | pm_runtime_disable(dev: &client->dev); |
1740 | pm_runtime_set_suspended(dev: &client->dev); |
1741 | |
1742 | iio_triggered_buffer_cleanup(indio_dev); |
1743 | mma8452_trigger_cleanup(indio_dev); |
1744 | mma8452_standby(data: iio_priv(indio_dev)); |
1745 | |
1746 | regulator_disable(regulator: data->vddio_reg); |
1747 | regulator_disable(regulator: data->vdd_reg); |
1748 | } |
1749 | |
1750 | #ifdef CONFIG_PM |
1751 | static int mma8452_runtime_suspend(struct device *dev) |
1752 | { |
1753 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
1754 | struct mma8452_data *data = iio_priv(indio_dev); |
1755 | int ret; |
1756 | |
1757 | mutex_lock(&data->lock); |
1758 | ret = mma8452_standby(data); |
1759 | mutex_unlock(lock: &data->lock); |
1760 | if (ret < 0) { |
1761 | dev_err(&data->client->dev, "powering off device failed\n" ); |
1762 | return -EAGAIN; |
1763 | } |
1764 | |
1765 | ret = regulator_disable(regulator: data->vddio_reg); |
1766 | if (ret) { |
1767 | dev_err(dev, "failed to disable VDDIO regulator\n" ); |
1768 | return ret; |
1769 | } |
1770 | |
1771 | ret = regulator_disable(regulator: data->vdd_reg); |
1772 | if (ret) { |
1773 | dev_err(dev, "failed to disable VDD regulator\n" ); |
1774 | return ret; |
1775 | } |
1776 | |
1777 | return 0; |
1778 | } |
1779 | |
1780 | static int mma8452_runtime_resume(struct device *dev) |
1781 | { |
1782 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
1783 | struct mma8452_data *data = iio_priv(indio_dev); |
1784 | int ret, sleep_val; |
1785 | |
1786 | ret = regulator_enable(regulator: data->vdd_reg); |
1787 | if (ret) { |
1788 | dev_err(dev, "failed to enable VDD regulator\n" ); |
1789 | return ret; |
1790 | } |
1791 | |
1792 | ret = regulator_enable(regulator: data->vddio_reg); |
1793 | if (ret) { |
1794 | dev_err(dev, "failed to enable VDDIO regulator\n" ); |
1795 | regulator_disable(regulator: data->vdd_reg); |
1796 | return ret; |
1797 | } |
1798 | |
1799 | ret = mma8452_active(data); |
1800 | if (ret < 0) |
1801 | goto runtime_resume_failed; |
1802 | |
1803 | ret = mma8452_get_odr_index(data); |
1804 | sleep_val = 1000 / mma8452_samp_freq[ret][0]; |
1805 | if (sleep_val < 20) |
1806 | usleep_range(min: sleep_val * 1000, max: 20000); |
1807 | else |
1808 | msleep_interruptible(msecs: sleep_val); |
1809 | |
1810 | return 0; |
1811 | |
1812 | runtime_resume_failed: |
1813 | regulator_disable(regulator: data->vddio_reg); |
1814 | regulator_disable(regulator: data->vdd_reg); |
1815 | |
1816 | return ret; |
1817 | } |
1818 | #endif |
1819 | |
1820 | static const struct dev_pm_ops mma8452_pm_ops = { |
1821 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) |
1822 | SET_RUNTIME_PM_OPS(mma8452_runtime_suspend, |
1823 | mma8452_runtime_resume, NULL) |
1824 | }; |
1825 | |
1826 | static const struct i2c_device_id mma8452_id[] = { |
1827 | { "fxls8471" , (kernel_ulong_t)&mma_chip_info_table[fxls8471] }, |
1828 | { "mma8451" , (kernel_ulong_t)&mma_chip_info_table[mma8451] }, |
1829 | { "mma8452" , (kernel_ulong_t)&mma_chip_info_table[mma8452] }, |
1830 | { "mma8453" , (kernel_ulong_t)&mma_chip_info_table[mma8453] }, |
1831 | { "mma8652" , (kernel_ulong_t)&mma_chip_info_table[mma8652] }, |
1832 | { "mma8653" , (kernel_ulong_t)&mma_chip_info_table[mma8653] }, |
1833 | { } |
1834 | }; |
1835 | MODULE_DEVICE_TABLE(i2c, mma8452_id); |
1836 | |
1837 | static struct i2c_driver mma8452_driver = { |
1838 | .driver = { |
1839 | .name = "mma8452" , |
1840 | .of_match_table = mma8452_dt_ids, |
1841 | .pm = &mma8452_pm_ops, |
1842 | }, |
1843 | .probe = mma8452_probe, |
1844 | .remove = mma8452_remove, |
1845 | .id_table = mma8452_id, |
1846 | }; |
1847 | module_i2c_driver(mma8452_driver); |
1848 | |
1849 | MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>" ); |
1850 | MODULE_DESCRIPTION("Freescale / NXP MMA8452 accelerometer driver" ); |
1851 | MODULE_LICENSE("GPL" ); |
1852 | |