1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Bosch BMC150 three-axis magnetic field sensor driver |
4 | * |
5 | * Copyright (c) 2015, Intel Corporation. |
6 | * |
7 | * This code is based on bmm050_api.c authored by contact@bosch.sensortec.com: |
8 | * |
9 | * (C) Copyright 2011~2014 Bosch Sensortec GmbH All Rights Reserved |
10 | */ |
11 | |
12 | #include <linux/module.h> |
13 | #include <linux/i2c.h> |
14 | #include <linux/interrupt.h> |
15 | #include <linux/delay.h> |
16 | #include <linux/slab.h> |
17 | #include <linux/acpi.h> |
18 | #include <linux/pm.h> |
19 | #include <linux/pm_runtime.h> |
20 | #include <linux/iio/iio.h> |
21 | #include <linux/iio/sysfs.h> |
22 | #include <linux/iio/buffer.h> |
23 | #include <linux/iio/events.h> |
24 | #include <linux/iio/trigger.h> |
25 | #include <linux/iio/trigger_consumer.h> |
26 | #include <linux/iio/triggered_buffer.h> |
27 | #include <linux/regmap.h> |
28 | #include <linux/regulator/consumer.h> |
29 | |
30 | #include "bmc150_magn.h" |
31 | |
32 | #define BMC150_MAGN_DRV_NAME "bmc150_magn" |
33 | #define BMC150_MAGN_IRQ_NAME "bmc150_magn_event" |
34 | |
35 | #define BMC150_MAGN_REG_CHIP_ID 0x40 |
36 | #define BMC150_MAGN_CHIP_ID_VAL 0x32 |
37 | |
38 | #define BMC150_MAGN_REG_X_L 0x42 |
39 | #define BMC150_MAGN_REG_X_M 0x43 |
40 | #define BMC150_MAGN_REG_Y_L 0x44 |
41 | #define BMC150_MAGN_REG_Y_M 0x45 |
42 | #define BMC150_MAGN_SHIFT_XY_L 3 |
43 | #define BMC150_MAGN_REG_Z_L 0x46 |
44 | #define BMC150_MAGN_REG_Z_M 0x47 |
45 | #define BMC150_MAGN_SHIFT_Z_L 1 |
46 | #define BMC150_MAGN_REG_RHALL_L 0x48 |
47 | #define BMC150_MAGN_REG_RHALL_M 0x49 |
48 | #define BMC150_MAGN_SHIFT_RHALL_L 2 |
49 | |
50 | #define BMC150_MAGN_REG_INT_STATUS 0x4A |
51 | |
52 | #define BMC150_MAGN_REG_POWER 0x4B |
53 | #define BMC150_MAGN_MASK_POWER_CTL BIT(0) |
54 | |
55 | #define BMC150_MAGN_REG_OPMODE_ODR 0x4C |
56 | #define BMC150_MAGN_MASK_OPMODE GENMASK(2, 1) |
57 | #define BMC150_MAGN_SHIFT_OPMODE 1 |
58 | #define BMC150_MAGN_MODE_NORMAL 0x00 |
59 | #define BMC150_MAGN_MODE_FORCED 0x01 |
60 | #define BMC150_MAGN_MODE_SLEEP 0x03 |
61 | #define BMC150_MAGN_MASK_ODR GENMASK(5, 3) |
62 | #define BMC150_MAGN_SHIFT_ODR 3 |
63 | |
64 | #define BMC150_MAGN_REG_INT 0x4D |
65 | |
66 | #define BMC150_MAGN_REG_INT_DRDY 0x4E |
67 | #define BMC150_MAGN_MASK_DRDY_EN BIT(7) |
68 | #define BMC150_MAGN_SHIFT_DRDY_EN 7 |
69 | #define BMC150_MAGN_MASK_DRDY_INT3 BIT(6) |
70 | #define BMC150_MAGN_MASK_DRDY_Z_EN BIT(5) |
71 | #define BMC150_MAGN_MASK_DRDY_Y_EN BIT(4) |
72 | #define BMC150_MAGN_MASK_DRDY_X_EN BIT(3) |
73 | #define BMC150_MAGN_MASK_DRDY_DR_POLARITY BIT(2) |
74 | #define BMC150_MAGN_MASK_DRDY_LATCHING BIT(1) |
75 | #define BMC150_MAGN_MASK_DRDY_INT3_POLARITY BIT(0) |
76 | |
77 | #define BMC150_MAGN_REG_LOW_THRESH 0x4F |
78 | #define BMC150_MAGN_REG_HIGH_THRESH 0x50 |
79 | #define BMC150_MAGN_REG_REP_XY 0x51 |
80 | #define BMC150_MAGN_REG_REP_Z 0x52 |
81 | #define BMC150_MAGN_REG_REP_DATAMASK GENMASK(7, 0) |
82 | |
83 | #define BMC150_MAGN_REG_TRIM_START 0x5D |
84 | #define BMC150_MAGN_REG_TRIM_END 0x71 |
85 | |
86 | #define BMC150_MAGN_XY_OVERFLOW_VAL -4096 |
87 | #define BMC150_MAGN_Z_OVERFLOW_VAL -16384 |
88 | |
89 | /* Time from SUSPEND to SLEEP */ |
90 | #define BMC150_MAGN_START_UP_TIME_MS 3 |
91 | |
92 | #define BMC150_MAGN_AUTO_SUSPEND_DELAY_MS 2000 |
93 | |
94 | #define BMC150_MAGN_REGVAL_TO_REPXY(regval) (((regval) * 2) + 1) |
95 | #define BMC150_MAGN_REGVAL_TO_REPZ(regval) ((regval) + 1) |
96 | #define BMC150_MAGN_REPXY_TO_REGVAL(rep) (((rep) - 1) / 2) |
97 | #define BMC150_MAGN_REPZ_TO_REGVAL(rep) ((rep) - 1) |
98 | |
99 | enum bmc150_magn_axis { |
100 | AXIS_X, |
101 | AXIS_Y, |
102 | AXIS_Z, |
103 | RHALL, |
104 | AXIS_XYZ_MAX = RHALL, |
105 | AXIS_XYZR_MAX, |
106 | }; |
107 | |
108 | enum bmc150_magn_power_modes { |
109 | BMC150_MAGN_POWER_MODE_SUSPEND, |
110 | BMC150_MAGN_POWER_MODE_SLEEP, |
111 | BMC150_MAGN_POWER_MODE_NORMAL, |
112 | }; |
113 | |
114 | struct bmc150_magn_trim_regs { |
115 | s8 x1; |
116 | s8 y1; |
117 | __le16 reserved1; |
118 | u8 reserved2; |
119 | __le16 z4; |
120 | s8 x2; |
121 | s8 y2; |
122 | __le16 reserved3; |
123 | __le16 z2; |
124 | __le16 z1; |
125 | __le16 xyz1; |
126 | __le16 z3; |
127 | s8 xy2; |
128 | u8 xy1; |
129 | } __packed; |
130 | |
131 | struct bmc150_magn_data { |
132 | struct device *dev; |
133 | /* |
134 | * 1. Protect this structure. |
135 | * 2. Serialize sequences that power on/off the device and access HW. |
136 | */ |
137 | struct mutex mutex; |
138 | struct regmap *regmap; |
139 | struct regulator_bulk_data regulators[2]; |
140 | struct iio_mount_matrix orientation; |
141 | /* Ensure timestamp is naturally aligned */ |
142 | struct { |
143 | s32 chans[3]; |
144 | s64 timestamp __aligned(8); |
145 | } scan; |
146 | struct iio_trigger *dready_trig; |
147 | bool dready_trigger_on; |
148 | int max_odr; |
149 | int irq; |
150 | }; |
151 | |
152 | static const struct { |
153 | int freq; |
154 | u8 reg_val; |
155 | } bmc150_magn_samp_freq_table[] = { {2, 0x01}, |
156 | {6, 0x02}, |
157 | {8, 0x03}, |
158 | {10, 0x00}, |
159 | {15, 0x04}, |
160 | {20, 0x05}, |
161 | {25, 0x06}, |
162 | {30, 0x07} }; |
163 | |
164 | enum bmc150_magn_presets { |
165 | LOW_POWER_PRESET, |
166 | REGULAR_PRESET, |
167 | ENHANCED_REGULAR_PRESET, |
168 | HIGH_ACCURACY_PRESET |
169 | }; |
170 | |
171 | static const struct bmc150_magn_preset { |
172 | u8 rep_xy; |
173 | u8 rep_z; |
174 | u8 odr; |
175 | } bmc150_magn_presets_table[] = { |
176 | [LOW_POWER_PRESET] = {3, 3, 10}, |
177 | [REGULAR_PRESET] = {.rep_xy: 9, .rep_z: 15, .odr: 10}, |
178 | [ENHANCED_REGULAR_PRESET] = {.rep_xy: 15, .rep_z: 27, .odr: 10}, |
179 | [HIGH_ACCURACY_PRESET] = {.rep_xy: 47, .rep_z: 83, .odr: 20}, |
180 | }; |
181 | |
182 | #define BMC150_MAGN_DEFAULT_PRESET REGULAR_PRESET |
183 | |
184 | static bool bmc150_magn_is_writeable_reg(struct device *dev, unsigned int reg) |
185 | { |
186 | switch (reg) { |
187 | case BMC150_MAGN_REG_POWER: |
188 | case BMC150_MAGN_REG_OPMODE_ODR: |
189 | case BMC150_MAGN_REG_INT: |
190 | case BMC150_MAGN_REG_INT_DRDY: |
191 | case BMC150_MAGN_REG_LOW_THRESH: |
192 | case BMC150_MAGN_REG_HIGH_THRESH: |
193 | case BMC150_MAGN_REG_REP_XY: |
194 | case BMC150_MAGN_REG_REP_Z: |
195 | return true; |
196 | default: |
197 | return false; |
198 | } |
199 | } |
200 | |
201 | static bool bmc150_magn_is_volatile_reg(struct device *dev, unsigned int reg) |
202 | { |
203 | switch (reg) { |
204 | case BMC150_MAGN_REG_X_L: |
205 | case BMC150_MAGN_REG_X_M: |
206 | case BMC150_MAGN_REG_Y_L: |
207 | case BMC150_MAGN_REG_Y_M: |
208 | case BMC150_MAGN_REG_Z_L: |
209 | case BMC150_MAGN_REG_Z_M: |
210 | case BMC150_MAGN_REG_RHALL_L: |
211 | case BMC150_MAGN_REG_RHALL_M: |
212 | case BMC150_MAGN_REG_INT_STATUS: |
213 | return true; |
214 | default: |
215 | return false; |
216 | } |
217 | } |
218 | |
219 | const struct regmap_config bmc150_magn_regmap_config = { |
220 | .reg_bits = 8, |
221 | .val_bits = 8, |
222 | |
223 | .max_register = BMC150_MAGN_REG_TRIM_END, |
224 | .cache_type = REGCACHE_RBTREE, |
225 | |
226 | .writeable_reg = bmc150_magn_is_writeable_reg, |
227 | .volatile_reg = bmc150_magn_is_volatile_reg, |
228 | }; |
229 | EXPORT_SYMBOL_NS(bmc150_magn_regmap_config, IIO_BMC150_MAGN); |
230 | |
231 | static int bmc150_magn_set_power_mode(struct bmc150_magn_data *data, |
232 | enum bmc150_magn_power_modes mode, |
233 | bool state) |
234 | { |
235 | int ret; |
236 | |
237 | switch (mode) { |
238 | case BMC150_MAGN_POWER_MODE_SUSPEND: |
239 | ret = regmap_update_bits(map: data->regmap, BMC150_MAGN_REG_POWER, |
240 | BMC150_MAGN_MASK_POWER_CTL, val: !state); |
241 | if (ret < 0) |
242 | return ret; |
243 | usleep_range(BMC150_MAGN_START_UP_TIME_MS * 1000, max: 20000); |
244 | return 0; |
245 | case BMC150_MAGN_POWER_MODE_SLEEP: |
246 | return regmap_update_bits(map: data->regmap, |
247 | BMC150_MAGN_REG_OPMODE_ODR, |
248 | BMC150_MAGN_MASK_OPMODE, |
249 | BMC150_MAGN_MODE_SLEEP << |
250 | BMC150_MAGN_SHIFT_OPMODE); |
251 | case BMC150_MAGN_POWER_MODE_NORMAL: |
252 | return regmap_update_bits(map: data->regmap, |
253 | BMC150_MAGN_REG_OPMODE_ODR, |
254 | BMC150_MAGN_MASK_OPMODE, |
255 | BMC150_MAGN_MODE_NORMAL << |
256 | BMC150_MAGN_SHIFT_OPMODE); |
257 | } |
258 | |
259 | return -EINVAL; |
260 | } |
261 | |
262 | static int bmc150_magn_set_power_state(struct bmc150_magn_data *data, bool on) |
263 | { |
264 | #ifdef CONFIG_PM |
265 | int ret; |
266 | |
267 | if (on) { |
268 | ret = pm_runtime_resume_and_get(dev: data->dev); |
269 | } else { |
270 | pm_runtime_mark_last_busy(dev: data->dev); |
271 | ret = pm_runtime_put_autosuspend(dev: data->dev); |
272 | } |
273 | |
274 | if (ret < 0) { |
275 | dev_err(data->dev, |
276 | "failed to change power state to %d\n" , on); |
277 | return ret; |
278 | } |
279 | #endif |
280 | |
281 | return 0; |
282 | } |
283 | |
284 | static int bmc150_magn_get_odr(struct bmc150_magn_data *data, int *val) |
285 | { |
286 | int ret, reg_val; |
287 | u8 i, odr_val; |
288 | |
289 | ret = regmap_read(map: data->regmap, BMC150_MAGN_REG_OPMODE_ODR, val: ®_val); |
290 | if (ret < 0) |
291 | return ret; |
292 | odr_val = (reg_val & BMC150_MAGN_MASK_ODR) >> BMC150_MAGN_SHIFT_ODR; |
293 | |
294 | for (i = 0; i < ARRAY_SIZE(bmc150_magn_samp_freq_table); i++) |
295 | if (bmc150_magn_samp_freq_table[i].reg_val == odr_val) { |
296 | *val = bmc150_magn_samp_freq_table[i].freq; |
297 | return 0; |
298 | } |
299 | |
300 | return -EINVAL; |
301 | } |
302 | |
303 | static int bmc150_magn_set_odr(struct bmc150_magn_data *data, int val) |
304 | { |
305 | int ret; |
306 | u8 i; |
307 | |
308 | for (i = 0; i < ARRAY_SIZE(bmc150_magn_samp_freq_table); i++) { |
309 | if (bmc150_magn_samp_freq_table[i].freq == val) { |
310 | ret = regmap_update_bits(map: data->regmap, |
311 | BMC150_MAGN_REG_OPMODE_ODR, |
312 | BMC150_MAGN_MASK_ODR, |
313 | val: bmc150_magn_samp_freq_table[i]. |
314 | reg_val << |
315 | BMC150_MAGN_SHIFT_ODR); |
316 | if (ret < 0) |
317 | return ret; |
318 | return 0; |
319 | } |
320 | } |
321 | |
322 | return -EINVAL; |
323 | } |
324 | |
325 | static int bmc150_magn_set_max_odr(struct bmc150_magn_data *data, int rep_xy, |
326 | int rep_z, int odr) |
327 | { |
328 | int ret, reg_val, max_odr; |
329 | |
330 | if (rep_xy <= 0) { |
331 | ret = regmap_read(map: data->regmap, BMC150_MAGN_REG_REP_XY, |
332 | val: ®_val); |
333 | if (ret < 0) |
334 | return ret; |
335 | rep_xy = BMC150_MAGN_REGVAL_TO_REPXY(reg_val); |
336 | } |
337 | if (rep_z <= 0) { |
338 | ret = regmap_read(map: data->regmap, BMC150_MAGN_REG_REP_Z, |
339 | val: ®_val); |
340 | if (ret < 0) |
341 | return ret; |
342 | rep_z = BMC150_MAGN_REGVAL_TO_REPZ(reg_val); |
343 | } |
344 | if (odr <= 0) { |
345 | ret = bmc150_magn_get_odr(data, val: &odr); |
346 | if (ret < 0) |
347 | return ret; |
348 | } |
349 | /* the maximum selectable read-out frequency from datasheet */ |
350 | max_odr = 1000000 / (145 * rep_xy + 500 * rep_z + 980); |
351 | if (odr > max_odr) { |
352 | dev_err(data->dev, |
353 | "Can't set oversampling with sampling freq %d\n" , |
354 | odr); |
355 | return -EINVAL; |
356 | } |
357 | data->max_odr = max_odr; |
358 | |
359 | return 0; |
360 | } |
361 | |
362 | static s32 bmc150_magn_compensate_x(struct bmc150_magn_trim_regs *tregs, s16 x, |
363 | u16 rhall) |
364 | { |
365 | s16 val; |
366 | u16 xyz1 = le16_to_cpu(tregs->xyz1); |
367 | |
368 | if (x == BMC150_MAGN_XY_OVERFLOW_VAL) |
369 | return S32_MIN; |
370 | |
371 | if (!rhall) |
372 | rhall = xyz1; |
373 | |
374 | val = ((s16)(((u16)((((s32)xyz1) << 14) / rhall)) - ((u16)0x4000))); |
375 | val = ((s16)((((s32)x) * ((((((((s32)tregs->xy2) * ((((s32)val) * |
376 | ((s32)val)) >> 7)) + (((s32)val) * |
377 | ((s32)(((s16)tregs->xy1) << 7)))) >> 9) + ((s32)0x100000)) * |
378 | ((s32)(((s16)tregs->x2) + ((s16)0xA0)))) >> 12)) >> 13)) + |
379 | (((s16)tregs->x1) << 3); |
380 | |
381 | return (s32)val; |
382 | } |
383 | |
384 | static s32 bmc150_magn_compensate_y(struct bmc150_magn_trim_regs *tregs, s16 y, |
385 | u16 rhall) |
386 | { |
387 | s16 val; |
388 | u16 xyz1 = le16_to_cpu(tregs->xyz1); |
389 | |
390 | if (y == BMC150_MAGN_XY_OVERFLOW_VAL) |
391 | return S32_MIN; |
392 | |
393 | if (!rhall) |
394 | rhall = xyz1; |
395 | |
396 | val = ((s16)(((u16)((((s32)xyz1) << 14) / rhall)) - ((u16)0x4000))); |
397 | val = ((s16)((((s32)y) * ((((((((s32)tregs->xy2) * ((((s32)val) * |
398 | ((s32)val)) >> 7)) + (((s32)val) * |
399 | ((s32)(((s16)tregs->xy1) << 7)))) >> 9) + ((s32)0x100000)) * |
400 | ((s32)(((s16)tregs->y2) + ((s16)0xA0)))) >> 12)) >> 13)) + |
401 | (((s16)tregs->y1) << 3); |
402 | |
403 | return (s32)val; |
404 | } |
405 | |
406 | static s32 bmc150_magn_compensate_z(struct bmc150_magn_trim_regs *tregs, s16 z, |
407 | u16 rhall) |
408 | { |
409 | s32 val; |
410 | u16 xyz1 = le16_to_cpu(tregs->xyz1); |
411 | u16 z1 = le16_to_cpu(tregs->z1); |
412 | s16 z2 = le16_to_cpu(tregs->z2); |
413 | s16 z3 = le16_to_cpu(tregs->z3); |
414 | s16 z4 = le16_to_cpu(tregs->z4); |
415 | |
416 | if (z == BMC150_MAGN_Z_OVERFLOW_VAL) |
417 | return S32_MIN; |
418 | |
419 | val = (((((s32)(z - z4)) << 15) - ((((s32)z3) * ((s32)(((s16)rhall) - |
420 | ((s16)xyz1)))) >> 2)) / (z2 + ((s16)(((((s32)z1) * |
421 | ((((s16)rhall) << 1))) + (1 << 15)) >> 16)))); |
422 | |
423 | return val; |
424 | } |
425 | |
426 | static int bmc150_magn_read_xyz(struct bmc150_magn_data *data, s32 *buffer) |
427 | { |
428 | int ret; |
429 | __le16 values[AXIS_XYZR_MAX]; |
430 | s16 raw_x, raw_y, raw_z; |
431 | u16 rhall; |
432 | struct bmc150_magn_trim_regs tregs; |
433 | |
434 | ret = regmap_bulk_read(map: data->regmap, BMC150_MAGN_REG_X_L, |
435 | val: values, val_count: sizeof(values)); |
436 | if (ret < 0) |
437 | return ret; |
438 | |
439 | raw_x = (s16)le16_to_cpu(values[AXIS_X]) >> BMC150_MAGN_SHIFT_XY_L; |
440 | raw_y = (s16)le16_to_cpu(values[AXIS_Y]) >> BMC150_MAGN_SHIFT_XY_L; |
441 | raw_z = (s16)le16_to_cpu(values[AXIS_Z]) >> BMC150_MAGN_SHIFT_Z_L; |
442 | rhall = le16_to_cpu(values[RHALL]) >> BMC150_MAGN_SHIFT_RHALL_L; |
443 | |
444 | ret = regmap_bulk_read(map: data->regmap, BMC150_MAGN_REG_TRIM_START, |
445 | val: &tregs, val_count: sizeof(tregs)); |
446 | if (ret < 0) |
447 | return ret; |
448 | |
449 | buffer[AXIS_X] = bmc150_magn_compensate_x(tregs: &tregs, x: raw_x, rhall); |
450 | buffer[AXIS_Y] = bmc150_magn_compensate_y(tregs: &tregs, y: raw_y, rhall); |
451 | buffer[AXIS_Z] = bmc150_magn_compensate_z(tregs: &tregs, z: raw_z, rhall); |
452 | |
453 | return 0; |
454 | } |
455 | |
456 | static int bmc150_magn_read_raw(struct iio_dev *indio_dev, |
457 | struct iio_chan_spec const *chan, |
458 | int *val, int *val2, long mask) |
459 | { |
460 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
461 | int ret, tmp; |
462 | s32 values[AXIS_XYZ_MAX]; |
463 | |
464 | switch (mask) { |
465 | case IIO_CHAN_INFO_RAW: |
466 | if (iio_buffer_enabled(indio_dev)) |
467 | return -EBUSY; |
468 | mutex_lock(&data->mutex); |
469 | |
470 | ret = bmc150_magn_set_power_state(data, on: true); |
471 | if (ret < 0) { |
472 | mutex_unlock(lock: &data->mutex); |
473 | return ret; |
474 | } |
475 | |
476 | ret = bmc150_magn_read_xyz(data, buffer: values); |
477 | if (ret < 0) { |
478 | bmc150_magn_set_power_state(data, on: false); |
479 | mutex_unlock(lock: &data->mutex); |
480 | return ret; |
481 | } |
482 | *val = values[chan->scan_index]; |
483 | |
484 | ret = bmc150_magn_set_power_state(data, on: false); |
485 | if (ret < 0) { |
486 | mutex_unlock(lock: &data->mutex); |
487 | return ret; |
488 | } |
489 | |
490 | mutex_unlock(lock: &data->mutex); |
491 | return IIO_VAL_INT; |
492 | case IIO_CHAN_INFO_SCALE: |
493 | /* |
494 | * The API/driver performs an off-chip temperature |
495 | * compensation and outputs x/y/z magnetic field data in |
496 | * 16 LSB/uT to the upper application layer. |
497 | */ |
498 | *val = 0; |
499 | *val2 = 625; |
500 | return IIO_VAL_INT_PLUS_MICRO; |
501 | case IIO_CHAN_INFO_SAMP_FREQ: |
502 | ret = bmc150_magn_get_odr(data, val); |
503 | if (ret < 0) |
504 | return ret; |
505 | return IIO_VAL_INT; |
506 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
507 | switch (chan->channel2) { |
508 | case IIO_MOD_X: |
509 | case IIO_MOD_Y: |
510 | ret = regmap_read(map: data->regmap, BMC150_MAGN_REG_REP_XY, |
511 | val: &tmp); |
512 | if (ret < 0) |
513 | return ret; |
514 | *val = BMC150_MAGN_REGVAL_TO_REPXY(tmp); |
515 | return IIO_VAL_INT; |
516 | case IIO_MOD_Z: |
517 | ret = regmap_read(map: data->regmap, BMC150_MAGN_REG_REP_Z, |
518 | val: &tmp); |
519 | if (ret < 0) |
520 | return ret; |
521 | *val = BMC150_MAGN_REGVAL_TO_REPZ(tmp); |
522 | return IIO_VAL_INT; |
523 | default: |
524 | return -EINVAL; |
525 | } |
526 | default: |
527 | return -EINVAL; |
528 | } |
529 | } |
530 | |
531 | static int bmc150_magn_write_raw(struct iio_dev *indio_dev, |
532 | struct iio_chan_spec const *chan, |
533 | int val, int val2, long mask) |
534 | { |
535 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
536 | int ret; |
537 | |
538 | switch (mask) { |
539 | case IIO_CHAN_INFO_SAMP_FREQ: |
540 | if (val > data->max_odr) |
541 | return -EINVAL; |
542 | mutex_lock(&data->mutex); |
543 | ret = bmc150_magn_set_odr(data, val); |
544 | mutex_unlock(lock: &data->mutex); |
545 | return ret; |
546 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
547 | switch (chan->channel2) { |
548 | case IIO_MOD_X: |
549 | case IIO_MOD_Y: |
550 | if (val < 1 || val > 511) |
551 | return -EINVAL; |
552 | mutex_lock(&data->mutex); |
553 | ret = bmc150_magn_set_max_odr(data, rep_xy: val, rep_z: 0, odr: 0); |
554 | if (ret < 0) { |
555 | mutex_unlock(lock: &data->mutex); |
556 | return ret; |
557 | } |
558 | ret = regmap_update_bits(map: data->regmap, |
559 | BMC150_MAGN_REG_REP_XY, |
560 | BMC150_MAGN_REG_REP_DATAMASK, |
561 | BMC150_MAGN_REPXY_TO_REGVAL |
562 | (val)); |
563 | mutex_unlock(lock: &data->mutex); |
564 | return ret; |
565 | case IIO_MOD_Z: |
566 | if (val < 1 || val > 256) |
567 | return -EINVAL; |
568 | mutex_lock(&data->mutex); |
569 | ret = bmc150_magn_set_max_odr(data, rep_xy: 0, rep_z: val, odr: 0); |
570 | if (ret < 0) { |
571 | mutex_unlock(lock: &data->mutex); |
572 | return ret; |
573 | } |
574 | ret = regmap_update_bits(map: data->regmap, |
575 | BMC150_MAGN_REG_REP_Z, |
576 | BMC150_MAGN_REG_REP_DATAMASK, |
577 | BMC150_MAGN_REPZ_TO_REGVAL |
578 | (val)); |
579 | mutex_unlock(lock: &data->mutex); |
580 | return ret; |
581 | default: |
582 | return -EINVAL; |
583 | } |
584 | default: |
585 | return -EINVAL; |
586 | } |
587 | } |
588 | |
589 | static ssize_t bmc150_magn_show_samp_freq_avail(struct device *dev, |
590 | struct device_attribute *attr, |
591 | char *buf) |
592 | { |
593 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
594 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
595 | size_t len = 0; |
596 | u8 i; |
597 | |
598 | for (i = 0; i < ARRAY_SIZE(bmc150_magn_samp_freq_table); i++) { |
599 | if (bmc150_magn_samp_freq_table[i].freq > data->max_odr) |
600 | break; |
601 | len += scnprintf(buf: buf + len, PAGE_SIZE - len, fmt: "%d " , |
602 | bmc150_magn_samp_freq_table[i].freq); |
603 | } |
604 | /* replace last space with a newline */ |
605 | buf[len - 1] = '\n'; |
606 | |
607 | return len; |
608 | } |
609 | |
610 | static const struct iio_mount_matrix * |
611 | bmc150_magn_get_mount_matrix(const struct iio_dev *indio_dev, |
612 | const struct iio_chan_spec *chan) |
613 | { |
614 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
615 | |
616 | return &data->orientation; |
617 | } |
618 | |
619 | static const struct iio_chan_spec_ext_info bmc150_magn_ext_info[] = { |
620 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bmc150_magn_get_mount_matrix), |
621 | { } |
622 | }; |
623 | |
624 | static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(bmc150_magn_show_samp_freq_avail); |
625 | |
626 | static struct attribute *bmc150_magn_attributes[] = { |
627 | &iio_dev_attr_sampling_frequency_available.dev_attr.attr, |
628 | NULL, |
629 | }; |
630 | |
631 | static const struct attribute_group bmc150_magn_attrs_group = { |
632 | .attrs = bmc150_magn_attributes, |
633 | }; |
634 | |
635 | #define BMC150_MAGN_CHANNEL(_axis) { \ |
636 | .type = IIO_MAGN, \ |
637 | .modified = 1, \ |
638 | .channel2 = IIO_MOD_##_axis, \ |
639 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
640 | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ |
641 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ |
642 | BIT(IIO_CHAN_INFO_SCALE), \ |
643 | .scan_index = AXIS_##_axis, \ |
644 | .scan_type = { \ |
645 | .sign = 's', \ |
646 | .realbits = 32, \ |
647 | .storagebits = 32, \ |
648 | .endianness = IIO_LE \ |
649 | }, \ |
650 | .ext_info = bmc150_magn_ext_info, \ |
651 | } |
652 | |
653 | static const struct iio_chan_spec bmc150_magn_channels[] = { |
654 | BMC150_MAGN_CHANNEL(X), |
655 | BMC150_MAGN_CHANNEL(Y), |
656 | BMC150_MAGN_CHANNEL(Z), |
657 | IIO_CHAN_SOFT_TIMESTAMP(3), |
658 | }; |
659 | |
660 | static const struct iio_info bmc150_magn_info = { |
661 | .attrs = &bmc150_magn_attrs_group, |
662 | .read_raw = bmc150_magn_read_raw, |
663 | .write_raw = bmc150_magn_write_raw, |
664 | }; |
665 | |
666 | static const unsigned long bmc150_magn_scan_masks[] = { |
667 | BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), |
668 | 0}; |
669 | |
670 | static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p) |
671 | { |
672 | struct iio_poll_func *pf = p; |
673 | struct iio_dev *indio_dev = pf->indio_dev; |
674 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
675 | int ret; |
676 | |
677 | mutex_lock(&data->mutex); |
678 | ret = bmc150_magn_read_xyz(data, buffer: data->scan.chans); |
679 | if (ret < 0) |
680 | goto err; |
681 | |
682 | iio_push_to_buffers_with_timestamp(indio_dev, data: &data->scan, |
683 | timestamp: pf->timestamp); |
684 | |
685 | err: |
686 | mutex_unlock(lock: &data->mutex); |
687 | iio_trigger_notify_done(trig: indio_dev->trig); |
688 | |
689 | return IRQ_HANDLED; |
690 | } |
691 | |
692 | static int bmc150_magn_init(struct bmc150_magn_data *data) |
693 | { |
694 | int ret, chip_id; |
695 | struct bmc150_magn_preset preset; |
696 | |
697 | ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), |
698 | consumers: data->regulators); |
699 | if (ret < 0) { |
700 | dev_err(data->dev, "Failed to enable regulators: %d\n" , ret); |
701 | return ret; |
702 | } |
703 | /* |
704 | * 3ms power-on time according to datasheet, let's better |
705 | * be safe than sorry and set this delay to 5ms. |
706 | */ |
707 | msleep(msecs: 5); |
708 | |
709 | ret = bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_SUSPEND, |
710 | state: false); |
711 | if (ret < 0) { |
712 | dev_err(data->dev, |
713 | "Failed to bring up device from suspend mode\n" ); |
714 | goto err_regulator_disable; |
715 | } |
716 | |
717 | ret = regmap_read(map: data->regmap, BMC150_MAGN_REG_CHIP_ID, val: &chip_id); |
718 | if (ret < 0) { |
719 | dev_err(data->dev, "Failed reading chip id\n" ); |
720 | goto err_poweroff; |
721 | } |
722 | if (chip_id != BMC150_MAGN_CHIP_ID_VAL) { |
723 | dev_err(data->dev, "Invalid chip id 0x%x\n" , chip_id); |
724 | ret = -ENODEV; |
725 | goto err_poweroff; |
726 | } |
727 | dev_dbg(data->dev, "Chip id %x\n" , chip_id); |
728 | |
729 | preset = bmc150_magn_presets_table[BMC150_MAGN_DEFAULT_PRESET]; |
730 | ret = bmc150_magn_set_odr(data, val: preset.odr); |
731 | if (ret < 0) { |
732 | dev_err(data->dev, "Failed to set ODR to %d\n" , |
733 | preset.odr); |
734 | goto err_poweroff; |
735 | } |
736 | |
737 | ret = regmap_write(map: data->regmap, BMC150_MAGN_REG_REP_XY, |
738 | BMC150_MAGN_REPXY_TO_REGVAL(preset.rep_xy)); |
739 | if (ret < 0) { |
740 | dev_err(data->dev, "Failed to set REP XY to %d\n" , |
741 | preset.rep_xy); |
742 | goto err_poweroff; |
743 | } |
744 | |
745 | ret = regmap_write(map: data->regmap, BMC150_MAGN_REG_REP_Z, |
746 | BMC150_MAGN_REPZ_TO_REGVAL(preset.rep_z)); |
747 | if (ret < 0) { |
748 | dev_err(data->dev, "Failed to set REP Z to %d\n" , |
749 | preset.rep_z); |
750 | goto err_poweroff; |
751 | } |
752 | |
753 | ret = bmc150_magn_set_max_odr(data, rep_xy: preset.rep_xy, rep_z: preset.rep_z, |
754 | odr: preset.odr); |
755 | if (ret < 0) |
756 | goto err_poweroff; |
757 | |
758 | ret = bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_NORMAL, |
759 | state: true); |
760 | if (ret < 0) { |
761 | dev_err(data->dev, "Failed to power on device\n" ); |
762 | goto err_poweroff; |
763 | } |
764 | |
765 | return 0; |
766 | |
767 | err_poweroff: |
768 | bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_SUSPEND, state: true); |
769 | err_regulator_disable: |
770 | regulator_bulk_disable(ARRAY_SIZE(data->regulators), consumers: data->regulators); |
771 | return ret; |
772 | } |
773 | |
774 | static int bmc150_magn_reset_intr(struct bmc150_magn_data *data) |
775 | { |
776 | int tmp; |
777 | |
778 | /* |
779 | * Data Ready (DRDY) is always cleared after |
780 | * readout of data registers ends. |
781 | */ |
782 | return regmap_read(map: data->regmap, BMC150_MAGN_REG_X_L, val: &tmp); |
783 | } |
784 | |
785 | static void bmc150_magn_trig_reen(struct iio_trigger *trig) |
786 | { |
787 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
788 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
789 | int ret; |
790 | |
791 | if (!data->dready_trigger_on) |
792 | return; |
793 | |
794 | mutex_lock(&data->mutex); |
795 | ret = bmc150_magn_reset_intr(data); |
796 | mutex_unlock(lock: &data->mutex); |
797 | if (ret) |
798 | dev_err(data->dev, "Failed to reset interrupt\n" ); |
799 | } |
800 | |
801 | static int bmc150_magn_data_rdy_trigger_set_state(struct iio_trigger *trig, |
802 | bool state) |
803 | { |
804 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
805 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
806 | int ret = 0; |
807 | |
808 | mutex_lock(&data->mutex); |
809 | if (state == data->dready_trigger_on) |
810 | goto err_unlock; |
811 | |
812 | ret = regmap_update_bits(map: data->regmap, BMC150_MAGN_REG_INT_DRDY, |
813 | BMC150_MAGN_MASK_DRDY_EN, |
814 | val: state << BMC150_MAGN_SHIFT_DRDY_EN); |
815 | if (ret < 0) |
816 | goto err_unlock; |
817 | |
818 | data->dready_trigger_on = state; |
819 | |
820 | if (state) { |
821 | ret = bmc150_magn_reset_intr(data); |
822 | if (ret < 0) |
823 | goto err_unlock; |
824 | } |
825 | mutex_unlock(lock: &data->mutex); |
826 | |
827 | return 0; |
828 | |
829 | err_unlock: |
830 | mutex_unlock(lock: &data->mutex); |
831 | return ret; |
832 | } |
833 | |
834 | static const struct iio_trigger_ops bmc150_magn_trigger_ops = { |
835 | .set_trigger_state = bmc150_magn_data_rdy_trigger_set_state, |
836 | .reenable = bmc150_magn_trig_reen, |
837 | }; |
838 | |
839 | static int bmc150_magn_buffer_preenable(struct iio_dev *indio_dev) |
840 | { |
841 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
842 | |
843 | return bmc150_magn_set_power_state(data, on: true); |
844 | } |
845 | |
846 | static int bmc150_magn_buffer_postdisable(struct iio_dev *indio_dev) |
847 | { |
848 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
849 | |
850 | return bmc150_magn_set_power_state(data, on: false); |
851 | } |
852 | |
853 | static const struct iio_buffer_setup_ops bmc150_magn_buffer_setup_ops = { |
854 | .preenable = bmc150_magn_buffer_preenable, |
855 | .postdisable = bmc150_magn_buffer_postdisable, |
856 | }; |
857 | |
858 | static const char *bmc150_magn_match_acpi_device(struct device *dev) |
859 | { |
860 | const struct acpi_device_id *id; |
861 | |
862 | id = acpi_match_device(ids: dev->driver->acpi_match_table, dev); |
863 | if (!id) |
864 | return NULL; |
865 | |
866 | return dev_name(dev); |
867 | } |
868 | |
869 | int bmc150_magn_probe(struct device *dev, struct regmap *regmap, |
870 | int irq, const char *name) |
871 | { |
872 | struct bmc150_magn_data *data; |
873 | struct iio_dev *indio_dev; |
874 | int ret; |
875 | |
876 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*data)); |
877 | if (!indio_dev) |
878 | return -ENOMEM; |
879 | |
880 | data = iio_priv(indio_dev); |
881 | dev_set_drvdata(dev, data: indio_dev); |
882 | data->regmap = regmap; |
883 | data->irq = irq; |
884 | data->dev = dev; |
885 | |
886 | data->regulators[0].supply = "vdd" ; |
887 | data->regulators[1].supply = "vddio" ; |
888 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->regulators), |
889 | consumers: data->regulators); |
890 | if (ret) |
891 | return dev_err_probe(dev, err: ret, fmt: "failed to get regulators\n" ); |
892 | |
893 | ret = iio_read_mount_matrix(dev, matrix: &data->orientation); |
894 | if (ret) |
895 | return ret; |
896 | |
897 | if (!name && ACPI_HANDLE(dev)) |
898 | name = bmc150_magn_match_acpi_device(dev); |
899 | |
900 | mutex_init(&data->mutex); |
901 | |
902 | ret = bmc150_magn_init(data); |
903 | if (ret < 0) |
904 | return ret; |
905 | |
906 | indio_dev->channels = bmc150_magn_channels; |
907 | indio_dev->num_channels = ARRAY_SIZE(bmc150_magn_channels); |
908 | indio_dev->available_scan_masks = bmc150_magn_scan_masks; |
909 | indio_dev->name = name; |
910 | indio_dev->modes = INDIO_DIRECT_MODE; |
911 | indio_dev->info = &bmc150_magn_info; |
912 | |
913 | if (irq > 0) { |
914 | data->dready_trig = devm_iio_trigger_alloc(dev, |
915 | "%s-dev%d" , |
916 | indio_dev->name, |
917 | iio_device_id(indio_dev)); |
918 | if (!data->dready_trig) { |
919 | ret = -ENOMEM; |
920 | dev_err(dev, "iio trigger alloc failed\n" ); |
921 | goto err_poweroff; |
922 | } |
923 | |
924 | data->dready_trig->ops = &bmc150_magn_trigger_ops; |
925 | iio_trigger_set_drvdata(trig: data->dready_trig, data: indio_dev); |
926 | ret = iio_trigger_register(trig_info: data->dready_trig); |
927 | if (ret) { |
928 | dev_err(dev, "iio trigger register failed\n" ); |
929 | goto err_poweroff; |
930 | } |
931 | |
932 | ret = request_threaded_irq(irq, |
933 | handler: iio_trigger_generic_data_rdy_poll, |
934 | NULL, |
935 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
936 | BMC150_MAGN_IRQ_NAME, |
937 | dev: data->dready_trig); |
938 | if (ret < 0) { |
939 | dev_err(dev, "request irq %d failed\n" , irq); |
940 | goto err_trigger_unregister; |
941 | } |
942 | } |
943 | |
944 | ret = iio_triggered_buffer_setup(indio_dev, |
945 | iio_pollfunc_store_time, |
946 | bmc150_magn_trigger_handler, |
947 | &bmc150_magn_buffer_setup_ops); |
948 | if (ret < 0) { |
949 | dev_err(dev, "iio triggered buffer setup failed\n" ); |
950 | goto err_free_irq; |
951 | } |
952 | |
953 | ret = pm_runtime_set_active(dev); |
954 | if (ret) |
955 | goto err_buffer_cleanup; |
956 | |
957 | pm_runtime_enable(dev); |
958 | pm_runtime_set_autosuspend_delay(dev, |
959 | BMC150_MAGN_AUTO_SUSPEND_DELAY_MS); |
960 | pm_runtime_use_autosuspend(dev); |
961 | |
962 | ret = iio_device_register(indio_dev); |
963 | if (ret < 0) { |
964 | dev_err(dev, "unable to register iio device\n" ); |
965 | goto err_pm_cleanup; |
966 | } |
967 | |
968 | dev_dbg(dev, "Registered device %s\n" , name); |
969 | return 0; |
970 | |
971 | err_pm_cleanup: |
972 | pm_runtime_dont_use_autosuspend(dev); |
973 | pm_runtime_disable(dev); |
974 | err_buffer_cleanup: |
975 | iio_triggered_buffer_cleanup(indio_dev); |
976 | err_free_irq: |
977 | if (irq > 0) |
978 | free_irq(irq, data->dready_trig); |
979 | err_trigger_unregister: |
980 | if (data->dready_trig) |
981 | iio_trigger_unregister(trig_info: data->dready_trig); |
982 | err_poweroff: |
983 | bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_SUSPEND, state: true); |
984 | return ret; |
985 | } |
986 | EXPORT_SYMBOL_NS(bmc150_magn_probe, IIO_BMC150_MAGN); |
987 | |
988 | void bmc150_magn_remove(struct device *dev) |
989 | { |
990 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
991 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
992 | |
993 | iio_device_unregister(indio_dev); |
994 | |
995 | pm_runtime_disable(dev); |
996 | pm_runtime_set_suspended(dev); |
997 | |
998 | iio_triggered_buffer_cleanup(indio_dev); |
999 | |
1000 | if (data->irq > 0) |
1001 | free_irq(data->irq, data->dready_trig); |
1002 | |
1003 | if (data->dready_trig) |
1004 | iio_trigger_unregister(trig_info: data->dready_trig); |
1005 | |
1006 | mutex_lock(&data->mutex); |
1007 | bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_SUSPEND, state: true); |
1008 | mutex_unlock(lock: &data->mutex); |
1009 | |
1010 | regulator_bulk_disable(ARRAY_SIZE(data->regulators), consumers: data->regulators); |
1011 | } |
1012 | EXPORT_SYMBOL_NS(bmc150_magn_remove, IIO_BMC150_MAGN); |
1013 | |
1014 | #ifdef CONFIG_PM |
1015 | static int bmc150_magn_runtime_suspend(struct device *dev) |
1016 | { |
1017 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1018 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
1019 | int ret; |
1020 | |
1021 | mutex_lock(&data->mutex); |
1022 | ret = bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_SLEEP, |
1023 | state: true); |
1024 | mutex_unlock(lock: &data->mutex); |
1025 | if (ret < 0) { |
1026 | dev_err(dev, "powering off device failed\n" ); |
1027 | return ret; |
1028 | } |
1029 | return 0; |
1030 | } |
1031 | |
1032 | /* |
1033 | * Should be called with data->mutex held. |
1034 | */ |
1035 | static int bmc150_magn_runtime_resume(struct device *dev) |
1036 | { |
1037 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1038 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
1039 | |
1040 | return bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_NORMAL, |
1041 | state: true); |
1042 | } |
1043 | #endif |
1044 | |
1045 | #ifdef CONFIG_PM_SLEEP |
1046 | static int bmc150_magn_suspend(struct device *dev) |
1047 | { |
1048 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1049 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
1050 | int ret; |
1051 | |
1052 | mutex_lock(&data->mutex); |
1053 | ret = bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_SLEEP, |
1054 | state: true); |
1055 | mutex_unlock(lock: &data->mutex); |
1056 | |
1057 | return ret; |
1058 | } |
1059 | |
1060 | static int bmc150_magn_resume(struct device *dev) |
1061 | { |
1062 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1063 | struct bmc150_magn_data *data = iio_priv(indio_dev); |
1064 | int ret; |
1065 | |
1066 | mutex_lock(&data->mutex); |
1067 | ret = bmc150_magn_set_power_mode(data, mode: BMC150_MAGN_POWER_MODE_NORMAL, |
1068 | state: true); |
1069 | mutex_unlock(lock: &data->mutex); |
1070 | |
1071 | return ret; |
1072 | } |
1073 | #endif |
1074 | |
1075 | const struct dev_pm_ops bmc150_magn_pm_ops = { |
1076 | SET_SYSTEM_SLEEP_PM_OPS(bmc150_magn_suspend, bmc150_magn_resume) |
1077 | SET_RUNTIME_PM_OPS(bmc150_magn_runtime_suspend, |
1078 | bmc150_magn_runtime_resume, NULL) |
1079 | }; |
1080 | EXPORT_SYMBOL_NS(bmc150_magn_pm_ops, IIO_BMC150_MAGN); |
1081 | |
1082 | MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>" ); |
1083 | MODULE_LICENSE("GPL v2" ); |
1084 | MODULE_DESCRIPTION("BMC150 magnetometer core driver" ); |
1085 | |