1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Driver for the Yamaha YAS magnetic sensors, often used in Samsung |
4 | * mobile phones. While all are not yet handled because of lacking |
5 | * hardware, expand this driver to handle the different variants: |
6 | * |
7 | * YAS530 MS-3E (2011 Samsung Galaxy S Advance) |
8 | * YAS532 MS-3R (2011 Samsung Galaxy S4) |
9 | * YAS533 MS-3F (Vivo 1633, 1707, V3, Y21L) |
10 | * (YAS534 is a magnetic switch, not handled) |
11 | * YAS535 MS-6C |
12 | * YAS536 MS-3W |
13 | * YAS537 MS-3T (2015 Samsung Galaxy S6, Note 5, Galaxy S7) |
14 | * YAS539 MS-3S (2018 Samsung Galaxy A7 SM-A750FN) |
15 | * |
16 | * Code functions found in the MPU3050 YAS530 and YAS532 drivers |
17 | * named "inv_compass" in the Tegra Android kernel tree. |
18 | * Copyright (C) 2012 InvenSense Corporation |
19 | * |
20 | * Code functions for YAS537 based on Yamaha Android kernel driver. |
21 | * Copyright (c) 2014 Yamaha Corporation |
22 | * |
23 | * Author: Linus Walleij <linus.walleij@linaro.org> |
24 | */ |
25 | #include <linux/bitfield.h> |
26 | #include <linux/bitops.h> |
27 | #include <linux/delay.h> |
28 | #include <linux/err.h> |
29 | #include <linux/gpio/consumer.h> |
30 | #include <linux/i2c.h> |
31 | #include <linux/module.h> |
32 | #include <linux/mod_devicetable.h> |
33 | #include <linux/mutex.h> |
34 | #include <linux/pm_runtime.h> |
35 | #include <linux/property.h> |
36 | #include <linux/regmap.h> |
37 | #include <linux/regulator/consumer.h> |
38 | #include <linux/random.h> |
39 | #include <linux/units.h> |
40 | |
41 | #include <linux/iio/buffer.h> |
42 | #include <linux/iio/iio.h> |
43 | #include <linux/iio/trigger_consumer.h> |
44 | #include <linux/iio/triggered_buffer.h> |
45 | |
46 | #include <asm/unaligned.h> |
47 | |
48 | /* Commonly used registers */ |
49 | #define YAS5XX_DEVICE_ID 0x80 |
50 | #define YAS5XX_MEASURE_DATA 0xB0 |
51 | |
52 | /* These registers are used by YAS530, YAS532 and YAS533 */ |
53 | #define YAS530_ACTUATE_INIT_COIL 0x81 |
54 | #define YAS530_MEASURE 0x82 |
55 | #define YAS530_CONFIG 0x83 |
56 | #define YAS530_MEASURE_INTERVAL 0x84 |
57 | #define YAS530_OFFSET_X 0x85 /* [-31 .. 31] */ |
58 | #define YAS530_OFFSET_Y1 0x86 /* [-31 .. 31] */ |
59 | #define YAS530_OFFSET_Y2 0x87 /* [-31 .. 31] */ |
60 | #define YAS530_TEST1 0x88 |
61 | #define YAS530_TEST2 0x89 |
62 | #define YAS530_CAL 0x90 |
63 | |
64 | /* Registers used by YAS537 */ |
65 | #define YAS537_MEASURE 0x81 /* Originally YAS537_REG_CMDR */ |
66 | #define YAS537_CONFIG 0x82 /* Originally YAS537_REG_CONFR */ |
67 | #define YAS537_MEASURE_INTERVAL 0x83 /* Originally YAS537_REG_INTRVLR */ |
68 | #define YAS537_OFFSET_X 0x84 /* Originally YAS537_REG_OXR */ |
69 | #define YAS537_OFFSET_Y1 0x85 /* Originally YAS537_REG_OY1R */ |
70 | #define YAS537_OFFSET_Y2 0x86 /* Originally YAS537_REG_OY2R */ |
71 | #define YAS537_AVR 0x87 |
72 | #define YAS537_HCK 0x88 |
73 | #define YAS537_LCK 0x89 |
74 | #define YAS537_SRST 0x90 |
75 | #define YAS537_ADCCAL 0x91 |
76 | #define YAS537_MTC 0x93 |
77 | #define YAS537_OC 0x9E |
78 | #define YAS537_TRM 0x9F |
79 | #define YAS537_CAL 0xC0 |
80 | |
81 | /* Bits in the YAS5xx config register */ |
82 | #define YAS5XX_CONFIG_INTON BIT(0) /* Interrupt on? */ |
83 | #define YAS5XX_CONFIG_INTHACT BIT(1) /* Interrupt active high? */ |
84 | #define YAS5XX_CONFIG_CCK_MASK GENMASK(4, 2) |
85 | #define YAS5XX_CONFIG_CCK_SHIFT 2 |
86 | |
87 | /* Bits in the measure command register */ |
88 | #define YAS5XX_MEASURE_START BIT(0) |
89 | #define YAS5XX_MEASURE_LDTC BIT(1) |
90 | #define YAS5XX_MEASURE_FORS BIT(2) |
91 | #define YAS5XX_MEASURE_DLYMES BIT(4) |
92 | #define YAS5XX_MEASURE_CONT BIT(5) |
93 | |
94 | /* Bits in the measure data register */ |
95 | #define YAS5XX_MEASURE_DATA_BUSY BIT(7) |
96 | |
97 | #define YAS530_DEVICE_ID 0x01 /* YAS530 (MS-3E) */ |
98 | #define YAS530_VERSION_A 0 /* YAS530 (MS-3E A) */ |
99 | #define YAS530_VERSION_B 1 /* YAS530B (MS-3E B) */ |
100 | #define YAS530_VERSION_A_COEF 380 |
101 | #define YAS530_VERSION_B_COEF 550 |
102 | #define YAS530_DATA_BITS 12 |
103 | #define YAS530_DATA_CENTER BIT(YAS530_DATA_BITS - 1) |
104 | #define YAS530_DATA_OVERFLOW (BIT(YAS530_DATA_BITS) - 1) |
105 | |
106 | #define YAS532_DEVICE_ID 0x02 /* YAS532/YAS533 (MS-3R/F) */ |
107 | #define YAS532_VERSION_AB 0 /* YAS532/533 AB (MS-3R/F AB) */ |
108 | #define YAS532_VERSION_AC 1 /* YAS532/533 AC (MS-3R/F AC) */ |
109 | #define YAS532_VERSION_AB_COEF 1800 |
110 | #define YAS532_VERSION_AC_COEF_X 850 |
111 | #define YAS532_VERSION_AC_COEF_Y1 750 |
112 | #define YAS532_VERSION_AC_COEF_Y2 750 |
113 | #define YAS532_DATA_BITS 13 |
114 | #define YAS532_DATA_CENTER BIT(YAS532_DATA_BITS - 1) |
115 | #define YAS532_DATA_OVERFLOW (BIT(YAS532_DATA_BITS) - 1) |
116 | |
117 | #define YAS537_DEVICE_ID 0x07 /* YAS537 (MS-3T) */ |
118 | #define YAS537_VERSION_0 0 /* Version naming unknown */ |
119 | #define YAS537_VERSION_1 1 /* Version naming unknown */ |
120 | #define YAS537_MAG_AVERAGE_32_MASK GENMASK(6, 4) |
121 | #define YAS537_MEASURE_TIME_WORST_US 1500 |
122 | #define YAS537_DEFAULT_SENSOR_DELAY_MS 50 |
123 | #define YAS537_MAG_RCOIL_TIME_US 65 |
124 | #define YAS537_MTC3_MASK_PREP GENMASK(7, 0) |
125 | #define YAS537_MTC3_MASK_GET GENMASK(7, 5) |
126 | #define YAS537_MTC3_ADD_BIT BIT(4) |
127 | #define YAS537_HCK_MASK_PREP GENMASK(4, 0) |
128 | #define YAS537_HCK_MASK_GET GENMASK(7, 4) |
129 | #define YAS537_LCK_MASK_PREP GENMASK(4, 0) |
130 | #define YAS537_LCK_MASK_GET GENMASK(3, 0) |
131 | #define YAS537_OC_MASK_GET GENMASK(5, 0) |
132 | |
133 | /* Turn off device regulators etc after 5 seconds of inactivity */ |
134 | #define YAS5XX_AUTOSUSPEND_DELAY_MS 5000 |
135 | |
136 | enum chip_ids { |
137 | yas530, |
138 | yas532, |
139 | yas533, |
140 | yas537, |
141 | }; |
142 | |
143 | static const int yas530_volatile_reg[] = { |
144 | YAS530_ACTUATE_INIT_COIL, |
145 | YAS530_MEASURE, |
146 | }; |
147 | |
148 | static const int yas537_volatile_reg[] = { |
149 | YAS537_MEASURE, |
150 | }; |
151 | |
152 | struct yas5xx_calibration { |
153 | /* Linearization calibration x, y1, y2 */ |
154 | s32 r[3]; |
155 | u32 f[3]; |
156 | /* Temperature compensation calibration */ |
157 | s16 Cx, Cy1, Cy2; |
158 | /* Misc calibration coefficients */ |
159 | s8 a2, a3, a4, a6, a7, a8; |
160 | s16 a5, a9; |
161 | u8 k; |
162 | /* clock divider */ |
163 | u8 dck; |
164 | }; |
165 | |
166 | struct yas5xx; |
167 | |
168 | /** |
169 | * struct yas5xx_chip_info - device-specific data and function pointers |
170 | * @devid: device ID number |
171 | * @product_name: product name of the YAS variant |
172 | * @version_names: version letters or namings |
173 | * @volatile_reg: device-specific volatile registers |
174 | * @volatile_reg_qty: quantity of device-specific volatile registers |
175 | * @scaling_val2: scaling value for IIO_CHAN_INFO_SCALE |
176 | * @t_ref: number of counts at reference temperature 20 °C |
177 | * @min_temp_x10: starting point of temperature counting in 1/10:s degrees Celsius |
178 | * @get_measure: function pointer to get a measurement |
179 | * @get_calibration_data: function pointer to get calibration data |
180 | * @dump_calibration: function pointer to dump calibration for debugging |
181 | * @measure_offsets: function pointer to measure the offsets |
182 | * @power_on: function pointer to power-on procedure |
183 | * |
184 | * The "t_ref" value for YAS532/533 is known from the Android driver. |
185 | * For YAS530 and YAS537 it was approximately measured. |
186 | * |
187 | * The temperatures "min_temp_x10" are derived from the temperature resolutions |
188 | * given in the data sheets. |
189 | */ |
190 | struct yas5xx_chip_info { |
191 | unsigned int devid; |
192 | const char *product_name; |
193 | const char *version_names[2]; |
194 | const int *volatile_reg; |
195 | int volatile_reg_qty; |
196 | u32 scaling_val2; |
197 | u16 t_ref; |
198 | s16 min_temp_x10; |
199 | int (*get_measure)(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo); |
200 | int (*get_calibration_data)(struct yas5xx *yas5xx); |
201 | void (*dump_calibration)(struct yas5xx *yas5xx); |
202 | int (*measure_offsets)(struct yas5xx *yas5xx); |
203 | int (*power_on)(struct yas5xx *yas5xx); |
204 | }; |
205 | |
206 | /** |
207 | * struct yas5xx - state container for the YAS5xx driver |
208 | * @dev: parent device pointer |
209 | * @chip_info: device-specific data and function pointers |
210 | * @version: device version |
211 | * @calibration: calibration settings from the OTP storage |
212 | * @hard_offsets: offsets for each axis measured with initcoil actuated |
213 | * @orientation: mounting matrix, flipped axis etc |
214 | * @map: regmap to access the YAX5xx registers over I2C |
215 | * @regs: the vdd and vddio power regulators |
216 | * @reset: optional GPIO line used for handling RESET |
217 | * @lock: locks the magnetometer for exclusive use during a measurement (which |
218 | * involves several register transactions so the regmap lock is not enough) |
219 | * so that measurements get serialized in a first-come-first serve manner |
220 | * @scan: naturally aligned measurements |
221 | */ |
222 | struct yas5xx { |
223 | struct device *dev; |
224 | const struct yas5xx_chip_info *chip_info; |
225 | unsigned int version; |
226 | struct yas5xx_calibration calibration; |
227 | s8 hard_offsets[3]; |
228 | struct iio_mount_matrix orientation; |
229 | struct regmap *map; |
230 | struct regulator_bulk_data regs[2]; |
231 | struct gpio_desc *reset; |
232 | struct mutex lock; |
233 | /* |
234 | * The scanout is 4 x 32 bits in CPU endianness. |
235 | * Ensure timestamp is naturally aligned |
236 | */ |
237 | struct { |
238 | s32 channels[4]; |
239 | s64 ts __aligned(8); |
240 | } scan; |
241 | }; |
242 | |
243 | /* On YAS530 the x, y1 and y2 values are 12 bits */ |
244 | static u16 (u8 *data) |
245 | { |
246 | u16 val; |
247 | |
248 | /* |
249 | * These are the bits used in a 16bit word: |
250 | * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
251 | * x x x x x x x x x x x x |
252 | */ |
253 | val = get_unaligned_be16(p: &data[0]); |
254 | val = FIELD_GET(GENMASK(14, 3), val); |
255 | return val; |
256 | } |
257 | |
258 | /* On YAS532 the x, y1 and y2 values are 13 bits */ |
259 | static u16 (u8 *data) |
260 | { |
261 | u16 val; |
262 | |
263 | /* |
264 | * These are the bits used in a 16bit word: |
265 | * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
266 | * x x x x x x x x x x x x x |
267 | */ |
268 | val = get_unaligned_be16(p: &data[0]); |
269 | val = FIELD_GET(GENMASK(14, 2), val); |
270 | return val; |
271 | } |
272 | |
273 | /** |
274 | * yas530_measure() - Make a measure from the hardware |
275 | * @yas5xx: The device state |
276 | * @t: the raw temperature measurement |
277 | * @x: the raw x axis measurement |
278 | * @y1: the y1 axis measurement |
279 | * @y2: the y2 axis measurement |
280 | * @return: 0 on success or error code |
281 | * |
282 | * Used by YAS530, YAS532 and YAS533. |
283 | */ |
284 | static int yas530_measure(struct yas5xx *yas5xx, u16 *t, u16 *x, u16 *y1, u16 *y2) |
285 | { |
286 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
287 | unsigned int busy; |
288 | u8 data[8]; |
289 | int ret; |
290 | u16 val; |
291 | |
292 | mutex_lock(&yas5xx->lock); |
293 | ret = regmap_write(map: yas5xx->map, YAS530_MEASURE, YAS5XX_MEASURE_START); |
294 | if (ret < 0) |
295 | goto out_unlock; |
296 | |
297 | /* |
298 | * Typical time to measure 1500 us, max 2000 us so wait min 500 us |
299 | * and at most 20000 us (one magnitude more than the datsheet max) |
300 | * before timeout. |
301 | */ |
302 | ret = regmap_read_poll_timeout(yas5xx->map, YAS5XX_MEASURE_DATA, busy, |
303 | !(busy & YAS5XX_MEASURE_DATA_BUSY), |
304 | 500, 20000); |
305 | if (ret) { |
306 | dev_err(yas5xx->dev, "timeout waiting for measurement\n" ); |
307 | goto out_unlock; |
308 | } |
309 | |
310 | ret = regmap_bulk_read(map: yas5xx->map, YAS5XX_MEASURE_DATA, |
311 | val: data, val_count: sizeof(data)); |
312 | if (ret) |
313 | goto out_unlock; |
314 | |
315 | mutex_unlock(lock: &yas5xx->lock); |
316 | |
317 | switch (ci->devid) { |
318 | case YAS530_DEVICE_ID: |
319 | /* |
320 | * The t value is 9 bits in big endian format |
321 | * These are the bits used in a 16bit word: |
322 | * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
323 | * x x x x x x x x x |
324 | */ |
325 | val = get_unaligned_be16(p: &data[0]); |
326 | val = FIELD_GET(GENMASK(14, 6), val); |
327 | *t = val; |
328 | *x = yas530_extract_axis(data: &data[2]); |
329 | *y1 = yas530_extract_axis(data: &data[4]); |
330 | *y2 = yas530_extract_axis(data: &data[6]); |
331 | break; |
332 | case YAS532_DEVICE_ID: |
333 | /* |
334 | * The t value is 10 bits in big endian format |
335 | * These are the bits used in a 16bit word: |
336 | * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
337 | * x x x x x x x x x x |
338 | */ |
339 | val = get_unaligned_be16(p: &data[0]); |
340 | val = FIELD_GET(GENMASK(14, 5), val); |
341 | *t = val; |
342 | *x = yas532_extract_axis(data: &data[2]); |
343 | *y1 = yas532_extract_axis(data: &data[4]); |
344 | *y2 = yas532_extract_axis(data: &data[6]); |
345 | break; |
346 | default: |
347 | dev_err(yas5xx->dev, "unknown data format\n" ); |
348 | ret = -EINVAL; |
349 | break; |
350 | } |
351 | |
352 | return ret; |
353 | |
354 | out_unlock: |
355 | mutex_unlock(lock: &yas5xx->lock); |
356 | return ret; |
357 | } |
358 | |
359 | /** |
360 | * yas537_measure() - Make a measure from the hardware |
361 | * @yas5xx: The device state |
362 | * @t: the raw temperature measurement |
363 | * @x: the raw x axis measurement |
364 | * @y1: the y1 axis measurement |
365 | * @y2: the y2 axis measurement |
366 | * @return: 0 on success or error code |
367 | */ |
368 | static int yas537_measure(struct yas5xx *yas5xx, u16 *t, u16 *x, u16 *y1, u16 *y2) |
369 | { |
370 | struct yas5xx_calibration *c = &yas5xx->calibration; |
371 | unsigned int busy; |
372 | u8 data[8]; |
373 | u16 xy1y2[3]; |
374 | s32 h[3], s[3]; |
375 | int i, ret; |
376 | |
377 | mutex_lock(&yas5xx->lock); |
378 | |
379 | /* Contrary to YAS530/532, also a "cont" bit is set, meaning unknown */ |
380 | ret = regmap_write(map: yas5xx->map, YAS537_MEASURE, YAS5XX_MEASURE_START | |
381 | YAS5XX_MEASURE_CONT); |
382 | if (ret < 0) |
383 | goto out_unlock; |
384 | |
385 | /* Use same timeout like YAS530/532 but the bit is in data row 2 */ |
386 | ret = regmap_read_poll_timeout(yas5xx->map, YAS5XX_MEASURE_DATA + 2, busy, |
387 | !(busy & YAS5XX_MEASURE_DATA_BUSY), |
388 | 500, 20000); |
389 | if (ret) { |
390 | dev_err(yas5xx->dev, "timeout waiting for measurement\n" ); |
391 | goto out_unlock; |
392 | } |
393 | |
394 | ret = regmap_bulk_read(map: yas5xx->map, YAS5XX_MEASURE_DATA, |
395 | val: data, val_count: sizeof(data)); |
396 | if (ret) |
397 | goto out_unlock; |
398 | |
399 | mutex_unlock(lock: &yas5xx->lock); |
400 | |
401 | *t = get_unaligned_be16(p: &data[0]); |
402 | xy1y2[0] = FIELD_GET(GENMASK(13, 0), get_unaligned_be16(&data[2])); |
403 | xy1y2[1] = get_unaligned_be16(p: &data[4]); |
404 | xy1y2[2] = get_unaligned_be16(p: &data[6]); |
405 | |
406 | /* The second version of YAS537 needs to include calibration coefficients */ |
407 | if (yas5xx->version == YAS537_VERSION_1) { |
408 | for (i = 0; i < 3; i++) |
409 | s[i] = xy1y2[i] - BIT(13); |
410 | h[0] = (c->k * (128 * s[0] + c->a2 * s[1] + c->a3 * s[2])) / BIT(13); |
411 | h[1] = (c->k * (c->a4 * s[0] + c->a5 * s[1] + c->a6 * s[2])) / BIT(13); |
412 | h[2] = (c->k * (c->a7 * s[0] + c->a8 * s[1] + c->a9 * s[2])) / BIT(13); |
413 | for (i = 0; i < 3; i++) { |
414 | clamp_val(h[i], -BIT(13), BIT(13) - 1); |
415 | xy1y2[i] = h[i] + BIT(13); |
416 | } |
417 | } |
418 | |
419 | *x = xy1y2[0]; |
420 | *y1 = xy1y2[1]; |
421 | *y2 = xy1y2[2]; |
422 | |
423 | return 0; |
424 | |
425 | out_unlock: |
426 | mutex_unlock(lock: &yas5xx->lock); |
427 | return ret; |
428 | } |
429 | |
430 | /* Used by YAS530, YAS532 and YAS533 */ |
431 | static s32 yas530_linearize(struct yas5xx *yas5xx, u16 val, int axis) |
432 | { |
433 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
434 | struct yas5xx_calibration *c = &yas5xx->calibration; |
435 | static const s32 yas532ac_coef[] = { |
436 | YAS532_VERSION_AC_COEF_X, |
437 | YAS532_VERSION_AC_COEF_Y1, |
438 | YAS532_VERSION_AC_COEF_Y2, |
439 | }; |
440 | s32 coef; |
441 | |
442 | /* Select coefficients */ |
443 | switch (ci->devid) { |
444 | case YAS530_DEVICE_ID: |
445 | if (yas5xx->version == YAS530_VERSION_A) |
446 | coef = YAS530_VERSION_A_COEF; |
447 | else |
448 | coef = YAS530_VERSION_B_COEF; |
449 | break; |
450 | case YAS532_DEVICE_ID: |
451 | if (yas5xx->version == YAS532_VERSION_AB) |
452 | coef = YAS532_VERSION_AB_COEF; |
453 | else |
454 | /* Elaborate coefficients */ |
455 | coef = yas532ac_coef[axis]; |
456 | break; |
457 | default: |
458 | dev_err(yas5xx->dev, "unknown device type\n" ); |
459 | return val; |
460 | } |
461 | /* |
462 | * Linearization formula: |
463 | * |
464 | * x' = x - (3721 + 50 * f) + (xoffset - r) * c |
465 | * |
466 | * Where f and r are calibration values, c is a per-device |
467 | * and sometimes per-axis coefficient. |
468 | */ |
469 | return val - (3721 + 50 * c->f[axis]) + |
470 | (yas5xx->hard_offsets[axis] - c->r[axis]) * coef; |
471 | } |
472 | |
473 | static s32 yas5xx_calc_temperature(struct yas5xx *yas5xx, u16 t) |
474 | { |
475 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
476 | s32 to; |
477 | u16 t_ref; |
478 | s16 min_temp_x10; |
479 | int ref_temp_x10; |
480 | |
481 | t_ref = ci->t_ref; |
482 | min_temp_x10 = ci->min_temp_x10; |
483 | ref_temp_x10 = 200; |
484 | |
485 | to = (min_temp_x10 + ((ref_temp_x10 - min_temp_x10) * t / t_ref)) * 100; |
486 | return to; |
487 | } |
488 | |
489 | /** |
490 | * yas530_get_measure() - Measure a sample of all axis and process |
491 | * @yas5xx: The device state |
492 | * @to: Temperature out |
493 | * @xo: X axis out |
494 | * @yo: Y axis out |
495 | * @zo: Z axis out |
496 | * @return: 0 on success or error code |
497 | * |
498 | * Used by YAS530, YAS532 and YAS533. |
499 | */ |
500 | static int yas530_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo) |
501 | { |
502 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
503 | struct yas5xx_calibration *c = &yas5xx->calibration; |
504 | u16 t_ref, t_comp, t, x, y1, y2; |
505 | /* These are signed x, signed y1 etc */ |
506 | s32 sx, sy1, sy2, sy, sz; |
507 | int ret; |
508 | |
509 | /* We first get raw data that needs to be translated to [x,y,z] */ |
510 | ret = yas530_measure(yas5xx, t: &t, x: &x, y1: &y1, y2: &y2); |
511 | if (ret) |
512 | return ret; |
513 | |
514 | /* Do some linearization if available */ |
515 | sx = yas530_linearize(yas5xx, val: x, axis: 0); |
516 | sy1 = yas530_linearize(yas5xx, val: y1, axis: 1); |
517 | sy2 = yas530_linearize(yas5xx, val: y2, axis: 2); |
518 | |
519 | /* |
520 | * Set the temperature for compensation (unit: counts): |
521 | * YAS532/YAS533 version AC uses the temperature deviation as a |
522 | * multiplier. YAS530 and YAS532 version AB use solely the t value. |
523 | */ |
524 | t_ref = ci->t_ref; |
525 | if (ci->devid == YAS532_DEVICE_ID && |
526 | yas5xx->version == YAS532_VERSION_AC) { |
527 | t_comp = t - t_ref; |
528 | } else { |
529 | t_comp = t; |
530 | } |
531 | |
532 | /* |
533 | * Temperature compensation for x, y1, y2 respectively: |
534 | * |
535 | * Cx * t_comp |
536 | * x' = x - ----------- |
537 | * 100 |
538 | */ |
539 | sx = sx - (c->Cx * t_comp) / 100; |
540 | sy1 = sy1 - (c->Cy1 * t_comp) / 100; |
541 | sy2 = sy2 - (c->Cy2 * t_comp) / 100; |
542 | |
543 | /* |
544 | * Break y1 and y2 into y and z, y1 and y2 are apparently encoding |
545 | * y and z. |
546 | */ |
547 | sy = sy1 - sy2; |
548 | sz = -sy1 - sy2; |
549 | |
550 | /* Calculate temperature readout */ |
551 | *to = yas5xx_calc_temperature(yas5xx, t); |
552 | |
553 | /* |
554 | * Calibrate [x,y,z] with some formulas like this: |
555 | * |
556 | * 100 * x + a_2 * y + a_3 * z |
557 | * x' = k * --------------------------- |
558 | * 10 |
559 | * |
560 | * a_4 * x + a_5 * y + a_6 * z |
561 | * y' = k * --------------------------- |
562 | * 10 |
563 | * |
564 | * a_7 * x + a_8 * y + a_9 * z |
565 | * z' = k * --------------------------- |
566 | * 10 |
567 | */ |
568 | *xo = c->k * ((100 * sx + c->a2 * sy + c->a3 * sz) / 10); |
569 | *yo = c->k * ((c->a4 * sx + c->a5 * sy + c->a6 * sz) / 10); |
570 | *zo = c->k * ((c->a7 * sx + c->a8 * sy + c->a9 * sz) / 10); |
571 | |
572 | return 0; |
573 | } |
574 | |
575 | /** |
576 | * yas537_get_measure() - Measure a sample of all axis and process |
577 | * @yas5xx: The device state |
578 | * @to: Temperature out |
579 | * @xo: X axis out |
580 | * @yo: Y axis out |
581 | * @zo: Z axis out |
582 | * @return: 0 on success or error code |
583 | */ |
584 | static int yas537_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo) |
585 | { |
586 | u16 t, x, y1, y2; |
587 | int ret; |
588 | |
589 | /* We first get raw data that needs to be translated to [x,y,z] */ |
590 | ret = yas537_measure(yas5xx, t: &t, x: &x, y1: &y1, y2: &y2); |
591 | if (ret) |
592 | return ret; |
593 | |
594 | /* Calculate temperature readout */ |
595 | *to = yas5xx_calc_temperature(yas5xx, t); |
596 | |
597 | /* |
598 | * Unfortunately, no linearization or temperature compensation formulas |
599 | * are known for YAS537. |
600 | */ |
601 | |
602 | /* Calculate x, y, z from x, y1, y2 */ |
603 | *xo = (x - BIT(13)) * 300; |
604 | *yo = (y1 - y2) * 1732 / 10; |
605 | *zo = (-y1 - y2 + BIT(14)) * 300; |
606 | |
607 | return 0; |
608 | } |
609 | |
610 | static int yas5xx_read_raw(struct iio_dev *indio_dev, |
611 | struct iio_chan_spec const *chan, |
612 | int *val, int *val2, |
613 | long mask) |
614 | { |
615 | struct yas5xx *yas5xx = iio_priv(indio_dev); |
616 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
617 | s32 t, x, y, z; |
618 | int ret; |
619 | |
620 | switch (mask) { |
621 | case IIO_CHAN_INFO_PROCESSED: |
622 | case IIO_CHAN_INFO_RAW: |
623 | pm_runtime_get_sync(dev: yas5xx->dev); |
624 | ret = ci->get_measure(yas5xx, &t, &x, &y, &z); |
625 | pm_runtime_mark_last_busy(dev: yas5xx->dev); |
626 | pm_runtime_put_autosuspend(dev: yas5xx->dev); |
627 | if (ret) |
628 | return ret; |
629 | switch (chan->address) { |
630 | case 0: |
631 | *val = t; |
632 | break; |
633 | case 1: |
634 | *val = x; |
635 | break; |
636 | case 2: |
637 | *val = y; |
638 | break; |
639 | case 3: |
640 | *val = z; |
641 | break; |
642 | default: |
643 | dev_err(yas5xx->dev, "unknown channel\n" ); |
644 | return -EINVAL; |
645 | } |
646 | return IIO_VAL_INT; |
647 | case IIO_CHAN_INFO_SCALE: |
648 | *val = 1; |
649 | *val2 = ci->scaling_val2; |
650 | return IIO_VAL_FRACTIONAL; |
651 | default: |
652 | /* Unknown request */ |
653 | return -EINVAL; |
654 | } |
655 | } |
656 | |
657 | static void yas5xx_fill_buffer(struct iio_dev *indio_dev) |
658 | { |
659 | struct yas5xx *yas5xx = iio_priv(indio_dev); |
660 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
661 | s32 t, x, y, z; |
662 | int ret; |
663 | |
664 | pm_runtime_get_sync(dev: yas5xx->dev); |
665 | ret = ci->get_measure(yas5xx, &t, &x, &y, &z); |
666 | pm_runtime_mark_last_busy(dev: yas5xx->dev); |
667 | pm_runtime_put_autosuspend(dev: yas5xx->dev); |
668 | if (ret) { |
669 | dev_err(yas5xx->dev, "error refilling buffer\n" ); |
670 | return; |
671 | } |
672 | yas5xx->scan.channels[0] = t; |
673 | yas5xx->scan.channels[1] = x; |
674 | yas5xx->scan.channels[2] = y; |
675 | yas5xx->scan.channels[3] = z; |
676 | iio_push_to_buffers_with_timestamp(indio_dev, data: &yas5xx->scan, |
677 | timestamp: iio_get_time_ns(indio_dev)); |
678 | } |
679 | |
680 | static irqreturn_t yas5xx_handle_trigger(int irq, void *p) |
681 | { |
682 | const struct iio_poll_func *pf = p; |
683 | struct iio_dev *indio_dev = pf->indio_dev; |
684 | |
685 | yas5xx_fill_buffer(indio_dev); |
686 | iio_trigger_notify_done(trig: indio_dev->trig); |
687 | |
688 | return IRQ_HANDLED; |
689 | } |
690 | |
691 | |
692 | static const struct iio_mount_matrix * |
693 | yas5xx_get_mount_matrix(const struct iio_dev *indio_dev, |
694 | const struct iio_chan_spec *chan) |
695 | { |
696 | struct yas5xx *yas5xx = iio_priv(indio_dev); |
697 | |
698 | return &yas5xx->orientation; |
699 | } |
700 | |
701 | static const struct iio_chan_spec_ext_info yas5xx_ext_info[] = { |
702 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, yas5xx_get_mount_matrix), |
703 | { } |
704 | }; |
705 | |
706 | #define YAS5XX_AXIS_CHANNEL(axis, index) \ |
707 | { \ |
708 | .type = IIO_MAGN, \ |
709 | .modified = 1, \ |
710 | .channel2 = IIO_MOD_##axis, \ |
711 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
712 | BIT(IIO_CHAN_INFO_SCALE), \ |
713 | .ext_info = yas5xx_ext_info, \ |
714 | .address = index, \ |
715 | .scan_index = index, \ |
716 | .scan_type = { \ |
717 | .sign = 's', \ |
718 | .realbits = 32, \ |
719 | .storagebits = 32, \ |
720 | .endianness = IIO_CPU, \ |
721 | }, \ |
722 | } |
723 | |
724 | static const struct iio_chan_spec yas5xx_channels[] = { |
725 | { |
726 | .type = IIO_TEMP, |
727 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), |
728 | .address = 0, |
729 | .scan_index = 0, |
730 | .scan_type = { |
731 | .sign = 's', |
732 | .realbits = 32, |
733 | .storagebits = 32, |
734 | .endianness = IIO_CPU, |
735 | }, |
736 | }, |
737 | YAS5XX_AXIS_CHANNEL(X, 1), |
738 | YAS5XX_AXIS_CHANNEL(Y, 2), |
739 | YAS5XX_AXIS_CHANNEL(Z, 3), |
740 | IIO_CHAN_SOFT_TIMESTAMP(4), |
741 | }; |
742 | |
743 | static const unsigned long yas5xx_scan_masks[] = { GENMASK(3, 0), 0 }; |
744 | |
745 | static const struct iio_info yas5xx_info = { |
746 | .read_raw = &yas5xx_read_raw, |
747 | }; |
748 | |
749 | static bool yas5xx_volatile_reg(struct device *dev, unsigned int reg) |
750 | { |
751 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
752 | struct yas5xx *yas5xx = iio_priv(indio_dev); |
753 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
754 | int reg_qty; |
755 | int i; |
756 | |
757 | if (reg >= YAS5XX_MEASURE_DATA && reg < YAS5XX_MEASURE_DATA + 8) |
758 | return true; |
759 | |
760 | /* |
761 | * YAS versions share different registers on the same address, |
762 | * need to differentiate. |
763 | */ |
764 | reg_qty = ci->volatile_reg_qty; |
765 | for (i = 0; i < reg_qty; i++) { |
766 | if (reg == ci->volatile_reg[i]) |
767 | return true; |
768 | } |
769 | |
770 | return false; |
771 | } |
772 | |
773 | /* TODO: enable regmap cache, using mark dirty and sync at runtime resume */ |
774 | static const struct regmap_config yas5xx_regmap_config = { |
775 | .reg_bits = 8, |
776 | .val_bits = 8, |
777 | .max_register = 0xff, |
778 | .volatile_reg = yas5xx_volatile_reg, |
779 | }; |
780 | |
781 | /** |
782 | * yas530_extract_calibration() - extracts the a2-a9 and k calibration |
783 | * @data: the bitfield to use |
784 | * @c: the calibration to populate |
785 | * |
786 | * Used by YAS530, YAS532 and YAS533. |
787 | */ |
788 | static void (u8 *data, struct yas5xx_calibration *c) |
789 | { |
790 | u64 val = get_unaligned_be64(p: data); |
791 | |
792 | /* |
793 | * Bitfield layout for the axis calibration data, for factor |
794 | * a2 = 2 etc, k = k, c = clock divider |
795 | * |
796 | * n 7 6 5 4 3 2 1 0 |
797 | * 0 [ 2 2 2 2 2 2 3 3 ] bits 63 .. 56 |
798 | * 1 [ 3 3 4 4 4 4 4 4 ] bits 55 .. 48 |
799 | * 2 [ 5 5 5 5 5 5 6 6 ] bits 47 .. 40 |
800 | * 3 [ 6 6 6 6 7 7 7 7 ] bits 39 .. 32 |
801 | * 4 [ 7 7 7 8 8 8 8 8 ] bits 31 .. 24 |
802 | * 5 [ 8 9 9 9 9 9 9 9 ] bits 23 .. 16 |
803 | * 6 [ 9 k k k k k c c ] bits 15 .. 8 |
804 | * 7 [ c x x x x x x x ] bits 7 .. 0 |
805 | */ |
806 | c->a2 = FIELD_GET(GENMASK_ULL(63, 58), val) - 32; |
807 | c->a3 = FIELD_GET(GENMASK_ULL(57, 54), val) - 8; |
808 | c->a4 = FIELD_GET(GENMASK_ULL(53, 48), val) - 32; |
809 | c->a5 = FIELD_GET(GENMASK_ULL(47, 42), val) + 38; |
810 | c->a6 = FIELD_GET(GENMASK_ULL(41, 36), val) - 32; |
811 | c->a7 = FIELD_GET(GENMASK_ULL(35, 29), val) - 64; |
812 | c->a8 = FIELD_GET(GENMASK_ULL(28, 23), val) - 32; |
813 | c->a9 = FIELD_GET(GENMASK_ULL(22, 15), val); |
814 | c->k = FIELD_GET(GENMASK_ULL(14, 10), val) + 10; |
815 | c->dck = FIELD_GET(GENMASK_ULL(9, 7), val); |
816 | } |
817 | |
818 | static int yas530_get_calibration_data(struct yas5xx *yas5xx) |
819 | { |
820 | struct yas5xx_calibration *c = &yas5xx->calibration; |
821 | u8 data[16]; |
822 | u32 val; |
823 | int ret; |
824 | |
825 | /* Dummy read, first read is ALWAYS wrong */ |
826 | ret = regmap_bulk_read(map: yas5xx->map, YAS530_CAL, val: data, val_count: sizeof(data)); |
827 | if (ret) |
828 | return ret; |
829 | |
830 | /* Actual calibration readout */ |
831 | ret = regmap_bulk_read(map: yas5xx->map, YAS530_CAL, val: data, val_count: sizeof(data)); |
832 | if (ret) |
833 | return ret; |
834 | dev_dbg(yas5xx->dev, "calibration data: %16ph\n" , data); |
835 | |
836 | /* Contribute calibration data to the input pool for kernel entropy */ |
837 | add_device_randomness(buf: data, len: sizeof(data)); |
838 | |
839 | /* Extract version */ |
840 | yas5xx->version = data[15] & GENMASK(1, 0); |
841 | |
842 | /* Extract the calibration from the bitfield */ |
843 | c->Cx = data[0] * 6 - 768; |
844 | c->Cy1 = data[1] * 6 - 768; |
845 | c->Cy2 = data[2] * 6 - 768; |
846 | yas530_extract_calibration(data: &data[3], c); |
847 | |
848 | /* |
849 | * Extract linearization: |
850 | * Linearization layout in the 32 bits at byte 11: |
851 | * The r factors are 6 bit values where bit 5 is the sign |
852 | * |
853 | * n 7 6 5 4 3 2 1 0 |
854 | * 0 [ xx xx xx r0 r0 r0 r0 r0 ] bits 31 .. 24 |
855 | * 1 [ r0 f0 f0 r1 r1 r1 r1 r1 ] bits 23 .. 16 |
856 | * 2 [ r1 f1 f1 r2 r2 r2 r2 r2 ] bits 15 .. 8 |
857 | * 3 [ r2 f2 f2 xx xx xx xx xx ] bits 7 .. 0 |
858 | */ |
859 | val = get_unaligned_be32(p: &data[11]); |
860 | c->f[0] = FIELD_GET(GENMASK(22, 21), val); |
861 | c->f[1] = FIELD_GET(GENMASK(14, 13), val); |
862 | c->f[2] = FIELD_GET(GENMASK(6, 5), val); |
863 | c->r[0] = sign_extend32(FIELD_GET(GENMASK(28, 23), val), index: 5); |
864 | c->r[1] = sign_extend32(FIELD_GET(GENMASK(20, 15), val), index: 5); |
865 | c->r[2] = sign_extend32(FIELD_GET(GENMASK(12, 7), val), index: 5); |
866 | |
867 | return 0; |
868 | } |
869 | |
870 | static int yas532_get_calibration_data(struct yas5xx *yas5xx) |
871 | { |
872 | struct yas5xx_calibration *c = &yas5xx->calibration; |
873 | u8 data[14]; |
874 | u32 val; |
875 | int ret; |
876 | |
877 | /* Dummy read, first read is ALWAYS wrong */ |
878 | ret = regmap_bulk_read(map: yas5xx->map, YAS530_CAL, val: data, val_count: sizeof(data)); |
879 | if (ret) |
880 | return ret; |
881 | /* Actual calibration readout */ |
882 | ret = regmap_bulk_read(map: yas5xx->map, YAS530_CAL, val: data, val_count: sizeof(data)); |
883 | if (ret) |
884 | return ret; |
885 | dev_dbg(yas5xx->dev, "calibration data: %14ph\n" , data); |
886 | |
887 | /* Sanity check, is this all zeroes? */ |
888 | if (!memchr_inv(p: data, c: 0x00, size: 13) && !(data[13] & BIT(7))) |
889 | dev_warn(yas5xx->dev, "calibration is blank!\n" ); |
890 | |
891 | /* Contribute calibration data to the input pool for kernel entropy */ |
892 | add_device_randomness(buf: data, len: sizeof(data)); |
893 | |
894 | /* Only one bit of version info reserved here as far as we know */ |
895 | yas5xx->version = data[13] & BIT(0); |
896 | |
897 | /* Extract calibration from the bitfield */ |
898 | c->Cx = data[0] * 10 - 1280; |
899 | c->Cy1 = data[1] * 10 - 1280; |
900 | c->Cy2 = data[2] * 10 - 1280; |
901 | yas530_extract_calibration(data: &data[3], c); |
902 | |
903 | /* |
904 | * Extract linearization: |
905 | * Linearization layout in the 32 bits at byte 10: |
906 | * The r factors are 6 bit values where bit 5 is the sign |
907 | * |
908 | * n 7 6 5 4 3 2 1 0 |
909 | * 0 [ xx r0 r0 r0 r0 r0 r0 f0 ] bits 31 .. 24 |
910 | * 1 [ f0 r1 r1 r1 r1 r1 r1 f1 ] bits 23 .. 16 |
911 | * 2 [ f1 r2 r2 r2 r2 r2 r2 f2 ] bits 15 .. 8 |
912 | * 3 [ f2 xx xx xx xx xx xx xx ] bits 7 .. 0 |
913 | */ |
914 | val = get_unaligned_be32(p: &data[10]); |
915 | c->f[0] = FIELD_GET(GENMASK(24, 23), val); |
916 | c->f[1] = FIELD_GET(GENMASK(16, 15), val); |
917 | c->f[2] = FIELD_GET(GENMASK(8, 7), val); |
918 | c->r[0] = sign_extend32(FIELD_GET(GENMASK(30, 25), val), index: 5); |
919 | c->r[1] = sign_extend32(FIELD_GET(GENMASK(22, 17), val), index: 5); |
920 | c->r[2] = sign_extend32(FIELD_GET(GENMASK(14, 7), val), index: 5); |
921 | |
922 | return 0; |
923 | } |
924 | |
925 | static int yas537_get_calibration_data(struct yas5xx *yas5xx) |
926 | { |
927 | struct yas5xx_calibration *c = &yas5xx->calibration; |
928 | u8 data[17]; |
929 | u32 val1, val2, val3, val4; |
930 | int i, ret; |
931 | |
932 | /* Writing SRST register */ |
933 | ret = regmap_write(map: yas5xx->map, YAS537_SRST, BIT(1)); |
934 | if (ret) |
935 | return ret; |
936 | |
937 | /* Calibration readout, YAS537 needs one readout only */ |
938 | ret = regmap_bulk_read(map: yas5xx->map, YAS537_CAL, val: data, val_count: sizeof(data)); |
939 | if (ret) |
940 | return ret; |
941 | dev_dbg(yas5xx->dev, "calibration data: %17ph\n" , data); |
942 | |
943 | /* Sanity check, is this all zeroes? */ |
944 | if (!memchr_inv(p: data, c: 0x00, size: 16) && !FIELD_GET(GENMASK(5, 0), data[16])) |
945 | dev_warn(yas5xx->dev, "calibration is blank!\n" ); |
946 | |
947 | /* Contribute calibration data to the input pool for kernel entropy */ |
948 | add_device_randomness(buf: data, len: sizeof(data)); |
949 | |
950 | /* Extract version information */ |
951 | yas5xx->version = FIELD_GET(GENMASK(7, 6), data[16]); |
952 | |
953 | /* There are two versions of YAS537 behaving differently */ |
954 | switch (yas5xx->version) { |
955 | case YAS537_VERSION_0: |
956 | /* |
957 | * The first version simply writes data back into registers: |
958 | * |
959 | * data[0] YAS537_MTC 0x93 |
960 | * data[1] 0x94 |
961 | * data[2] 0x95 |
962 | * data[3] 0x96 |
963 | * data[4] 0x97 |
964 | * data[5] 0x98 |
965 | * data[6] 0x99 |
966 | * data[7] 0x9a |
967 | * data[8] 0x9b |
968 | * data[9] 0x9c |
969 | * data[10] 0x9d |
970 | * data[11] YAS537_OC 0x9e |
971 | * |
972 | * data[12] YAS537_OFFSET_X 0x84 |
973 | * data[13] YAS537_OFFSET_Y1 0x85 |
974 | * data[14] YAS537_OFFSET_Y2 0x86 |
975 | * |
976 | * data[15] YAS537_HCK 0x88 |
977 | * data[16] YAS537_LCK 0x89 |
978 | */ |
979 | for (i = 0; i < 12; i++) { |
980 | ret = regmap_write(map: yas5xx->map, YAS537_MTC + i, |
981 | val: data[i]); |
982 | if (ret) |
983 | return ret; |
984 | } |
985 | for (i = 0; i < 3; i++) { |
986 | ret = regmap_write(map: yas5xx->map, YAS537_OFFSET_X + i, |
987 | val: data[i + 12]); |
988 | if (ret) |
989 | return ret; |
990 | yas5xx->hard_offsets[i] = data[i + 12]; |
991 | } |
992 | for (i = 0; i < 2; i++) { |
993 | ret = regmap_write(map: yas5xx->map, YAS537_HCK + i, |
994 | val: data[i + 15]); |
995 | if (ret) |
996 | return ret; |
997 | } |
998 | break; |
999 | case YAS537_VERSION_1: |
1000 | /* |
1001 | * The second version writes some data into registers but also |
1002 | * extracts calibration coefficients. |
1003 | * |
1004 | * Registers being written: |
1005 | * |
1006 | * data[0] YAS537_MTC 0x93 |
1007 | * data[1] YAS537_MTC+1 0x94 |
1008 | * data[2] YAS537_MTC+2 0x95 |
1009 | * data[3] YAS537_MTC+3 (partially) 0x96 |
1010 | * |
1011 | * data[12] YAS537_OFFSET_X 0x84 |
1012 | * data[13] YAS537_OFFSET_Y1 0x85 |
1013 | * data[14] YAS537_OFFSET_Y2 0x86 |
1014 | * |
1015 | * data[15] YAS537_HCK (partially) 0x88 |
1016 | * YAS537_LCK (partially) 0x89 |
1017 | * data[16] YAS537_OC (partially) 0x9e |
1018 | */ |
1019 | for (i = 0; i < 3; i++) { |
1020 | ret = regmap_write(map: yas5xx->map, YAS537_MTC + i, |
1021 | val: data[i]); |
1022 | if (ret) |
1023 | return ret; |
1024 | } |
1025 | for (i = 0; i < 3; i++) { |
1026 | ret = regmap_write(map: yas5xx->map, YAS537_OFFSET_X + i, |
1027 | val: data[i + 12]); |
1028 | if (ret) |
1029 | return ret; |
1030 | yas5xx->hard_offsets[i] = data[i + 12]; |
1031 | } |
1032 | /* |
1033 | * Visualization of partially taken data: |
1034 | * |
1035 | * data[3] n 7 6 5 4 3 2 1 0 |
1036 | * YAS537_MTC+3 x x x 1 0 0 0 0 |
1037 | * |
1038 | * data[15] n 7 6 5 4 3 2 1 0 |
1039 | * YAS537_HCK x x x x 0 |
1040 | * |
1041 | * data[15] n 7 6 5 4 3 2 1 0 |
1042 | * YAS537_LCK x x x x 0 |
1043 | * |
1044 | * data[16] n 7 6 5 4 3 2 1 0 |
1045 | * YAS537_OC x x x x x x |
1046 | */ |
1047 | ret = regmap_write(map: yas5xx->map, YAS537_MTC + 3, |
1048 | FIELD_PREP(YAS537_MTC3_MASK_PREP, |
1049 | FIELD_GET(YAS537_MTC3_MASK_GET, data[3])) | |
1050 | YAS537_MTC3_ADD_BIT); |
1051 | if (ret) |
1052 | return ret; |
1053 | ret = regmap_write(map: yas5xx->map, YAS537_HCK, |
1054 | FIELD_PREP(YAS537_HCK_MASK_PREP, |
1055 | FIELD_GET(YAS537_HCK_MASK_GET, data[15]))); |
1056 | if (ret) |
1057 | return ret; |
1058 | ret = regmap_write(map: yas5xx->map, YAS537_LCK, |
1059 | FIELD_PREP(YAS537_LCK_MASK_PREP, |
1060 | FIELD_GET(YAS537_LCK_MASK_GET, data[15]))); |
1061 | if (ret) |
1062 | return ret; |
1063 | ret = regmap_write(map: yas5xx->map, YAS537_OC, |
1064 | FIELD_GET(YAS537_OC_MASK_GET, data[16])); |
1065 | if (ret) |
1066 | return ret; |
1067 | /* |
1068 | * For data extraction, build some blocks. Four 32-bit blocks |
1069 | * look appropriate. |
1070 | * |
1071 | * n 7 6 5 4 3 2 1 0 |
1072 | * data[0] 0 [ Cx Cx Cx Cx Cx Cx Cx Cx ] bits 31 .. 24 |
1073 | * data[1] 1 [ Cx C1 C1 C1 C1 C1 C1 C1 ] bits 23 .. 16 |
1074 | * data[2] 2 [ C1 C1 C2 C2 C2 C2 C2 C2 ] bits 15 .. 8 |
1075 | * data[3] 3 [ C2 C2 C2 ] bits 7 .. 0 |
1076 | * |
1077 | * n 7 6 5 4 3 2 1 0 |
1078 | * data[3] 0 [ a2 a2 a2 a2 a2 ] bits 31 .. 24 |
1079 | * data[4] 1 [ a2 a2 a3 a3 a3 a3 a3 a3 ] bits 23 .. 16 |
1080 | * data[5] 2 [ a3 a4 a4 a4 a4 a4 a4 a4 ] bits 15 .. 8 |
1081 | * data[6] 3 [ a4 ] bits 7 .. 0 |
1082 | * |
1083 | * n 7 6 5 4 3 2 1 0 |
1084 | * data[6] 0 [ a5 a5 a5 a5 a5 a5 a5 ] bits 31 .. 24 |
1085 | * data[7] 1 [ a5 a5 a6 a6 a6 a6 a6 a6 ] bits 23 .. 16 |
1086 | * data[8] 2 [ a6 a7 a7 a7 a7 a7 a7 a7 ] bits 15 .. 8 |
1087 | * data[9] 3 [ a7 ] bits 7 .. 0 |
1088 | * |
1089 | * n 7 6 5 4 3 2 1 0 |
1090 | * data[9] 0 [ a8 a8 a8 a8 a8 a8 a8 ] bits 31 .. 24 |
1091 | * data[10] 1 [ a9 a9 a9 a9 a9 a9 a9 a9 ] bits 23 .. 16 |
1092 | * data[11] 2 [ a9 k k k k k k k ] bits 15 .. 8 |
1093 | * data[12] 3 [ ] bits 7 .. 0 |
1094 | */ |
1095 | val1 = get_unaligned_be32(p: &data[0]); |
1096 | val2 = get_unaligned_be32(p: &data[3]); |
1097 | val3 = get_unaligned_be32(p: &data[6]); |
1098 | val4 = get_unaligned_be32(p: &data[9]); |
1099 | /* Extract calibration coefficients and modify */ |
1100 | c->Cx = FIELD_GET(GENMASK(31, 23), val1) - 256; |
1101 | c->Cy1 = FIELD_GET(GENMASK(22, 14), val1) - 256; |
1102 | c->Cy2 = FIELD_GET(GENMASK(13, 5), val1) - 256; |
1103 | c->a2 = FIELD_GET(GENMASK(28, 22), val2) - 64; |
1104 | c->a3 = FIELD_GET(GENMASK(21, 15), val2) - 64; |
1105 | c->a4 = FIELD_GET(GENMASK(14, 7), val2) - 128; |
1106 | c->a5 = FIELD_GET(GENMASK(30, 22), val3) - 112; |
1107 | c->a6 = FIELD_GET(GENMASK(21, 15), val3) - 64; |
1108 | c->a7 = FIELD_GET(GENMASK(14, 7), val3) - 128; |
1109 | c->a8 = FIELD_GET(GENMASK(30, 24), val4) - 64; |
1110 | c->a9 = FIELD_GET(GENMASK(23, 15), val4) - 112; |
1111 | c->k = FIELD_GET(GENMASK(14, 8), val4); |
1112 | break; |
1113 | default: |
1114 | dev_err(yas5xx->dev, "unknown version of YAS537\n" ); |
1115 | return -EINVAL; |
1116 | } |
1117 | |
1118 | return 0; |
1119 | } |
1120 | |
1121 | /* Used by YAS530, YAS532 and YAS533 */ |
1122 | static void yas530_dump_calibration(struct yas5xx *yas5xx) |
1123 | { |
1124 | struct yas5xx_calibration *c = &yas5xx->calibration; |
1125 | |
1126 | dev_dbg(yas5xx->dev, "f[] = [%d, %d, %d]\n" , |
1127 | c->f[0], c->f[1], c->f[2]); |
1128 | dev_dbg(yas5xx->dev, "r[] = [%d, %d, %d]\n" , |
1129 | c->r[0], c->r[1], c->r[2]); |
1130 | dev_dbg(yas5xx->dev, "Cx = %d\n" , c->Cx); |
1131 | dev_dbg(yas5xx->dev, "Cy1 = %d\n" , c->Cy1); |
1132 | dev_dbg(yas5xx->dev, "Cy2 = %d\n" , c->Cy2); |
1133 | dev_dbg(yas5xx->dev, "a2 = %d\n" , c->a2); |
1134 | dev_dbg(yas5xx->dev, "a3 = %d\n" , c->a3); |
1135 | dev_dbg(yas5xx->dev, "a4 = %d\n" , c->a4); |
1136 | dev_dbg(yas5xx->dev, "a5 = %d\n" , c->a5); |
1137 | dev_dbg(yas5xx->dev, "a6 = %d\n" , c->a6); |
1138 | dev_dbg(yas5xx->dev, "a7 = %d\n" , c->a7); |
1139 | dev_dbg(yas5xx->dev, "a8 = %d\n" , c->a8); |
1140 | dev_dbg(yas5xx->dev, "a9 = %d\n" , c->a9); |
1141 | dev_dbg(yas5xx->dev, "k = %d\n" , c->k); |
1142 | dev_dbg(yas5xx->dev, "dck = %d\n" , c->dck); |
1143 | } |
1144 | |
1145 | static void yas537_dump_calibration(struct yas5xx *yas5xx) |
1146 | { |
1147 | struct yas5xx_calibration *c = &yas5xx->calibration; |
1148 | |
1149 | if (yas5xx->version == YAS537_VERSION_1) { |
1150 | dev_dbg(yas5xx->dev, "Cx = %d\n" , c->Cx); |
1151 | dev_dbg(yas5xx->dev, "Cy1 = %d\n" , c->Cy1); |
1152 | dev_dbg(yas5xx->dev, "Cy2 = %d\n" , c->Cy2); |
1153 | dev_dbg(yas5xx->dev, "a2 = %d\n" , c->a2); |
1154 | dev_dbg(yas5xx->dev, "a3 = %d\n" , c->a3); |
1155 | dev_dbg(yas5xx->dev, "a4 = %d\n" , c->a4); |
1156 | dev_dbg(yas5xx->dev, "a5 = %d\n" , c->a5); |
1157 | dev_dbg(yas5xx->dev, "a6 = %d\n" , c->a6); |
1158 | dev_dbg(yas5xx->dev, "a7 = %d\n" , c->a7); |
1159 | dev_dbg(yas5xx->dev, "a8 = %d\n" , c->a8); |
1160 | dev_dbg(yas5xx->dev, "a9 = %d\n" , c->a9); |
1161 | dev_dbg(yas5xx->dev, "k = %d\n" , c->k); |
1162 | } |
1163 | } |
1164 | |
1165 | /* Used by YAS530, YAS532 and YAS533 */ |
1166 | static int yas530_set_offsets(struct yas5xx *yas5xx, s8 ox, s8 oy1, s8 oy2) |
1167 | { |
1168 | int ret; |
1169 | |
1170 | ret = regmap_write(map: yas5xx->map, YAS530_OFFSET_X, val: ox); |
1171 | if (ret) |
1172 | return ret; |
1173 | ret = regmap_write(map: yas5xx->map, YAS530_OFFSET_Y1, val: oy1); |
1174 | if (ret) |
1175 | return ret; |
1176 | return regmap_write(map: yas5xx->map, YAS530_OFFSET_Y2, val: oy2); |
1177 | } |
1178 | |
1179 | /* Used by YAS530, YAS532 and YAS533 */ |
1180 | static s8 yas530_adjust_offset(s8 old, int bit, u16 center, u16 measure) |
1181 | { |
1182 | if (measure > center) |
1183 | return old + BIT(bit); |
1184 | if (measure < center) |
1185 | return old - BIT(bit); |
1186 | return old; |
1187 | } |
1188 | |
1189 | /* Used by YAS530, YAS532 and YAS533 */ |
1190 | static int yas530_measure_offsets(struct yas5xx *yas5xx) |
1191 | { |
1192 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
1193 | int ret; |
1194 | u16 center; |
1195 | u16 t, x, y1, y2; |
1196 | s8 ox, oy1, oy2; |
1197 | int i; |
1198 | |
1199 | /* Actuate the init coil and measure offsets */ |
1200 | ret = regmap_write(map: yas5xx->map, YAS530_ACTUATE_INIT_COIL, val: 0); |
1201 | if (ret) |
1202 | return ret; |
1203 | |
1204 | /* When the initcoil is active this should be around the center */ |
1205 | switch (ci->devid) { |
1206 | case YAS530_DEVICE_ID: |
1207 | center = YAS530_DATA_CENTER; |
1208 | break; |
1209 | case YAS532_DEVICE_ID: |
1210 | center = YAS532_DATA_CENTER; |
1211 | break; |
1212 | default: |
1213 | dev_err(yas5xx->dev, "unknown device type\n" ); |
1214 | return -EINVAL; |
1215 | } |
1216 | |
1217 | /* |
1218 | * We set offsets in the interval +-31 by iterating |
1219 | * +-16, +-8, +-4, +-2, +-1 adjusting the offsets each |
1220 | * time, then writing the final offsets into the |
1221 | * registers. |
1222 | * |
1223 | * NOTE: these offsets are NOT in the same unit or magnitude |
1224 | * as the values for [x, y1, y2]. The value is +/-31 |
1225 | * but the effect on the raw values is much larger. |
1226 | * The effect of the offset is to bring the measure |
1227 | * rougly to the center. |
1228 | */ |
1229 | ox = 0; |
1230 | oy1 = 0; |
1231 | oy2 = 0; |
1232 | |
1233 | for (i = 4; i >= 0; i--) { |
1234 | ret = yas530_set_offsets(yas5xx, ox, oy1, oy2); |
1235 | if (ret) |
1236 | return ret; |
1237 | |
1238 | ret = yas530_measure(yas5xx, t: &t, x: &x, y1: &y1, y2: &y2); |
1239 | if (ret) |
1240 | return ret; |
1241 | dev_dbg(yas5xx->dev, "measurement %d: x=%d, y1=%d, y2=%d\n" , |
1242 | 5-i, x, y1, y2); |
1243 | |
1244 | ox = yas530_adjust_offset(old: ox, bit: i, center, measure: x); |
1245 | oy1 = yas530_adjust_offset(old: oy1, bit: i, center, measure: y1); |
1246 | oy2 = yas530_adjust_offset(old: oy2, bit: i, center, measure: y2); |
1247 | } |
1248 | |
1249 | /* Needed for calibration algorithm */ |
1250 | yas5xx->hard_offsets[0] = ox; |
1251 | yas5xx->hard_offsets[1] = oy1; |
1252 | yas5xx->hard_offsets[2] = oy2; |
1253 | ret = yas530_set_offsets(yas5xx, ox, oy1, oy2); |
1254 | if (ret) |
1255 | return ret; |
1256 | |
1257 | dev_info(yas5xx->dev, "discovered hard offsets: x=%d, y1=%d, y2=%d\n" , |
1258 | ox, oy1, oy2); |
1259 | return 0; |
1260 | } |
1261 | |
1262 | /* Used by YAS530, YAS532 and YAS533 */ |
1263 | static int yas530_power_on(struct yas5xx *yas5xx) |
1264 | { |
1265 | unsigned int val; |
1266 | int ret; |
1267 | |
1268 | /* Zero the test registers */ |
1269 | ret = regmap_write(map: yas5xx->map, YAS530_TEST1, val: 0); |
1270 | if (ret) |
1271 | return ret; |
1272 | ret = regmap_write(map: yas5xx->map, YAS530_TEST2, val: 0); |
1273 | if (ret) |
1274 | return ret; |
1275 | |
1276 | /* Set up for no interrupts, calibrated clock divider */ |
1277 | val = FIELD_PREP(YAS5XX_CONFIG_CCK_MASK, yas5xx->calibration.dck); |
1278 | ret = regmap_write(map: yas5xx->map, YAS530_CONFIG, val); |
1279 | if (ret) |
1280 | return ret; |
1281 | |
1282 | /* Measure interval 0 (back-to-back?) */ |
1283 | return regmap_write(map: yas5xx->map, YAS530_MEASURE_INTERVAL, val: 0); |
1284 | } |
1285 | |
1286 | static int yas537_power_on(struct yas5xx *yas5xx) |
1287 | { |
1288 | __be16 buf; |
1289 | int ret; |
1290 | u8 intrvl; |
1291 | |
1292 | /* Writing ADCCAL and TRM registers */ |
1293 | buf = cpu_to_be16(GENMASK(9, 3)); |
1294 | ret = regmap_bulk_write(map: yas5xx->map, YAS537_ADCCAL, val: &buf, val_count: sizeof(buf)); |
1295 | if (ret) |
1296 | return ret; |
1297 | ret = regmap_write(map: yas5xx->map, YAS537_TRM, GENMASK(7, 0)); |
1298 | if (ret) |
1299 | return ret; |
1300 | |
1301 | /* The interval value is static in regular operation */ |
1302 | intrvl = (YAS537_DEFAULT_SENSOR_DELAY_MS * MILLI |
1303 | - YAS537_MEASURE_TIME_WORST_US) / 4100; |
1304 | ret = regmap_write(map: yas5xx->map, YAS537_MEASURE_INTERVAL, val: intrvl); |
1305 | if (ret) |
1306 | return ret; |
1307 | |
1308 | /* The average value is also static in regular operation */ |
1309 | ret = regmap_write(map: yas5xx->map, YAS537_AVR, YAS537_MAG_AVERAGE_32_MASK); |
1310 | if (ret) |
1311 | return ret; |
1312 | |
1313 | /* Perform the "rcoil" part but skip the "last_after_rcoil" read */ |
1314 | ret = regmap_write(map: yas5xx->map, YAS537_CONFIG, BIT(3)); |
1315 | if (ret) |
1316 | return ret; |
1317 | |
1318 | /* Wait until the coil has ramped up */ |
1319 | usleep_range(YAS537_MAG_RCOIL_TIME_US, YAS537_MAG_RCOIL_TIME_US + 100); |
1320 | |
1321 | return 0; |
1322 | } |
1323 | |
1324 | static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = { |
1325 | [yas530] = { |
1326 | .devid = YAS530_DEVICE_ID, |
1327 | .product_name = "YAS530 MS-3E" , |
1328 | .version_names = { "A" , "B" }, |
1329 | .volatile_reg = yas530_volatile_reg, |
1330 | .volatile_reg_qty = ARRAY_SIZE(yas530_volatile_reg), |
1331 | .scaling_val2 = 100000000, /* picotesla to Gauss */ |
1332 | .t_ref = 182, /* counts */ |
1333 | .min_temp_x10 = -620, /* 1/10:s degrees Celsius */ |
1334 | .get_measure = yas530_get_measure, |
1335 | .get_calibration_data = yas530_get_calibration_data, |
1336 | .dump_calibration = yas530_dump_calibration, |
1337 | .measure_offsets = yas530_measure_offsets, |
1338 | .power_on = yas530_power_on, |
1339 | }, |
1340 | [yas532] = { |
1341 | .devid = YAS532_DEVICE_ID, |
1342 | .product_name = "YAS532 MS-3R" , |
1343 | .version_names = { "AB" , "AC" }, |
1344 | .volatile_reg = yas530_volatile_reg, |
1345 | .volatile_reg_qty = ARRAY_SIZE(yas530_volatile_reg), |
1346 | .scaling_val2 = 100000, /* nanotesla to Gauss */ |
1347 | .t_ref = 390, /* counts */ |
1348 | .min_temp_x10 = -500, /* 1/10:s degrees Celsius */ |
1349 | .get_measure = yas530_get_measure, |
1350 | .get_calibration_data = yas532_get_calibration_data, |
1351 | .dump_calibration = yas530_dump_calibration, |
1352 | .measure_offsets = yas530_measure_offsets, |
1353 | .power_on = yas530_power_on, |
1354 | }, |
1355 | [yas533] = { |
1356 | .devid = YAS532_DEVICE_ID, |
1357 | .product_name = "YAS533 MS-3F" , |
1358 | .version_names = { "AB" , "AC" }, |
1359 | .volatile_reg = yas530_volatile_reg, |
1360 | .volatile_reg_qty = ARRAY_SIZE(yas530_volatile_reg), |
1361 | .scaling_val2 = 100000, /* nanotesla to Gauss */ |
1362 | .t_ref = 390, /* counts */ |
1363 | .min_temp_x10 = -500, /* 1/10:s degrees Celsius */ |
1364 | .get_measure = yas530_get_measure, |
1365 | .get_calibration_data = yas532_get_calibration_data, |
1366 | .dump_calibration = yas530_dump_calibration, |
1367 | .measure_offsets = yas530_measure_offsets, |
1368 | .power_on = yas530_power_on, |
1369 | }, |
1370 | [yas537] = { |
1371 | .devid = YAS537_DEVICE_ID, |
1372 | .product_name = "YAS537 MS-3T" , |
1373 | .version_names = { "v0" , "v1" }, /* version naming unknown */ |
1374 | .volatile_reg = yas537_volatile_reg, |
1375 | .volatile_reg_qty = ARRAY_SIZE(yas537_volatile_reg), |
1376 | .scaling_val2 = 100000, /* nanotesla to Gauss */ |
1377 | .t_ref = 8120, /* counts */ |
1378 | .min_temp_x10 = -3860, /* 1/10:s degrees Celsius */ |
1379 | .get_measure = yas537_get_measure, |
1380 | .get_calibration_data = yas537_get_calibration_data, |
1381 | .dump_calibration = yas537_dump_calibration, |
1382 | /* .measure_offets is not needed for yas537 */ |
1383 | .power_on = yas537_power_on, |
1384 | }, |
1385 | }; |
1386 | |
1387 | static int yas5xx_probe(struct i2c_client *i2c) |
1388 | { |
1389 | const struct i2c_device_id *id = i2c_client_get_device_id(client: i2c); |
1390 | struct iio_dev *indio_dev; |
1391 | struct device *dev = &i2c->dev; |
1392 | struct yas5xx *yas5xx; |
1393 | const struct yas5xx_chip_info *ci; |
1394 | int id_check; |
1395 | int ret; |
1396 | |
1397 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*yas5xx)); |
1398 | if (!indio_dev) |
1399 | return -ENOMEM; |
1400 | |
1401 | yas5xx = iio_priv(indio_dev); |
1402 | i2c_set_clientdata(client: i2c, data: indio_dev); |
1403 | yas5xx->dev = dev; |
1404 | mutex_init(&yas5xx->lock); |
1405 | |
1406 | ret = iio_read_mount_matrix(dev, matrix: &yas5xx->orientation); |
1407 | if (ret) |
1408 | return ret; |
1409 | |
1410 | yas5xx->regs[0].supply = "vdd" ; |
1411 | yas5xx->regs[1].supply = "iovdd" ; |
1412 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(yas5xx->regs), |
1413 | consumers: yas5xx->regs); |
1414 | if (ret) |
1415 | return dev_err_probe(dev, err: ret, fmt: "cannot get regulators\n" ); |
1416 | |
1417 | ret = regulator_bulk_enable(ARRAY_SIZE(yas5xx->regs), consumers: yas5xx->regs); |
1418 | if (ret) |
1419 | return dev_err_probe(dev, err: ret, fmt: "cannot enable regulators\n" ); |
1420 | |
1421 | /* See comment in runtime resume callback */ |
1422 | usleep_range(min: 31000, max: 40000); |
1423 | |
1424 | /* This will take the device out of reset if need be */ |
1425 | yas5xx->reset = devm_gpiod_get_optional(dev, con_id: "reset" , flags: GPIOD_OUT_LOW); |
1426 | if (IS_ERR(ptr: yas5xx->reset)) { |
1427 | ret = dev_err_probe(dev, err: PTR_ERR(ptr: yas5xx->reset), fmt: "failed to get reset line\n" ); |
1428 | goto reg_off; |
1429 | } |
1430 | |
1431 | yas5xx->map = devm_regmap_init_i2c(i2c, &yas5xx_regmap_config); |
1432 | if (IS_ERR(ptr: yas5xx->map)) { |
1433 | ret = dev_err_probe(dev, err: PTR_ERR(ptr: yas5xx->map), fmt: "failed to allocate register map\n" ); |
1434 | goto assert_reset; |
1435 | } |
1436 | |
1437 | ci = i2c_get_match_data(client: i2c); |
1438 | yas5xx->chip_info = ci; |
1439 | |
1440 | ret = regmap_read(map: yas5xx->map, YAS5XX_DEVICE_ID, val: &id_check); |
1441 | if (ret) |
1442 | goto assert_reset; |
1443 | |
1444 | if (id_check != ci->devid) { |
1445 | ret = dev_err_probe(dev, err: -ENODEV, |
1446 | fmt: "device ID %02x doesn't match %s\n" , |
1447 | id_check, id->name); |
1448 | goto assert_reset; |
1449 | } |
1450 | |
1451 | ret = ci->get_calibration_data(yas5xx); |
1452 | if (ret) |
1453 | goto assert_reset; |
1454 | |
1455 | dev_info(dev, "detected %s %s\n" , ci->product_name, |
1456 | ci->version_names[yas5xx->version]); |
1457 | |
1458 | ci->dump_calibration(yas5xx); |
1459 | |
1460 | ret = ci->power_on(yas5xx); |
1461 | if (ret) |
1462 | goto assert_reset; |
1463 | |
1464 | if (ci->measure_offsets) { |
1465 | ret = ci->measure_offsets(yas5xx); |
1466 | if (ret) |
1467 | goto assert_reset; |
1468 | } |
1469 | |
1470 | indio_dev->info = &yas5xx_info; |
1471 | indio_dev->available_scan_masks = yas5xx_scan_masks; |
1472 | indio_dev->modes = INDIO_DIRECT_MODE; |
1473 | indio_dev->name = id->name; |
1474 | indio_dev->channels = yas5xx_channels; |
1475 | indio_dev->num_channels = ARRAY_SIZE(yas5xx_channels); |
1476 | |
1477 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
1478 | yas5xx_handle_trigger, |
1479 | NULL); |
1480 | if (ret) { |
1481 | dev_err_probe(dev, err: ret, fmt: "triggered buffer setup failed\n" ); |
1482 | goto assert_reset; |
1483 | } |
1484 | |
1485 | ret = iio_device_register(indio_dev); |
1486 | if (ret) { |
1487 | dev_err_probe(dev, err: ret, fmt: "device register failed\n" ); |
1488 | goto cleanup_buffer; |
1489 | } |
1490 | |
1491 | /* Take runtime PM online */ |
1492 | pm_runtime_get_noresume(dev); |
1493 | pm_runtime_set_active(dev); |
1494 | pm_runtime_enable(dev); |
1495 | |
1496 | pm_runtime_set_autosuspend_delay(dev, YAS5XX_AUTOSUSPEND_DELAY_MS); |
1497 | pm_runtime_use_autosuspend(dev); |
1498 | pm_runtime_put(dev); |
1499 | |
1500 | return 0; |
1501 | |
1502 | cleanup_buffer: |
1503 | iio_triggered_buffer_cleanup(indio_dev); |
1504 | assert_reset: |
1505 | gpiod_set_value_cansleep(desc: yas5xx->reset, value: 1); |
1506 | reg_off: |
1507 | regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), consumers: yas5xx->regs); |
1508 | |
1509 | return ret; |
1510 | } |
1511 | |
1512 | static void yas5xx_remove(struct i2c_client *i2c) |
1513 | { |
1514 | struct iio_dev *indio_dev = i2c_get_clientdata(client: i2c); |
1515 | struct yas5xx *yas5xx = iio_priv(indio_dev); |
1516 | struct device *dev = &i2c->dev; |
1517 | |
1518 | iio_device_unregister(indio_dev); |
1519 | iio_triggered_buffer_cleanup(indio_dev); |
1520 | /* |
1521 | * Now we can't get any more reads from the device, which would |
1522 | * also call pm_runtime* functions and race with our disable |
1523 | * code. Disable PM runtime in orderly fashion and power down. |
1524 | */ |
1525 | pm_runtime_get_sync(dev); |
1526 | pm_runtime_put_noidle(dev); |
1527 | pm_runtime_disable(dev); |
1528 | gpiod_set_value_cansleep(desc: yas5xx->reset, value: 1); |
1529 | regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), consumers: yas5xx->regs); |
1530 | } |
1531 | |
1532 | static int yas5xx_runtime_suspend(struct device *dev) |
1533 | { |
1534 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1535 | struct yas5xx *yas5xx = iio_priv(indio_dev); |
1536 | |
1537 | gpiod_set_value_cansleep(desc: yas5xx->reset, value: 1); |
1538 | regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), consumers: yas5xx->regs); |
1539 | |
1540 | return 0; |
1541 | } |
1542 | |
1543 | static int yas5xx_runtime_resume(struct device *dev) |
1544 | { |
1545 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1546 | struct yas5xx *yas5xx = iio_priv(indio_dev); |
1547 | const struct yas5xx_chip_info *ci = yas5xx->chip_info; |
1548 | int ret; |
1549 | |
1550 | ret = regulator_bulk_enable(ARRAY_SIZE(yas5xx->regs), consumers: yas5xx->regs); |
1551 | if (ret) { |
1552 | dev_err(dev, "cannot enable regulators\n" ); |
1553 | return ret; |
1554 | } |
1555 | |
1556 | /* |
1557 | * The YAS530 datasheet says TVSKW is up to 30 ms, after that 1 ms |
1558 | * for all voltages to settle. The YAS532 is 10ms then 4ms for the |
1559 | * I2C to come online. Let's keep it safe and put this at 31ms. |
1560 | */ |
1561 | usleep_range(min: 31000, max: 40000); |
1562 | gpiod_set_value_cansleep(desc: yas5xx->reset, value: 0); |
1563 | |
1564 | ret = ci->power_on(yas5xx); |
1565 | if (ret) { |
1566 | dev_err(dev, "cannot power on\n" ); |
1567 | goto out_reset; |
1568 | } |
1569 | |
1570 | return 0; |
1571 | |
1572 | out_reset: |
1573 | gpiod_set_value_cansleep(desc: yas5xx->reset, value: 1); |
1574 | regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), consumers: yas5xx->regs); |
1575 | |
1576 | return ret; |
1577 | } |
1578 | |
1579 | static DEFINE_RUNTIME_DEV_PM_OPS(yas5xx_dev_pm_ops, yas5xx_runtime_suspend, |
1580 | yas5xx_runtime_resume, NULL); |
1581 | |
1582 | static const struct i2c_device_id yas5xx_id[] = { |
1583 | {"yas530" , (kernel_ulong_t)&yas5xx_chip_info_tbl[yas530] }, |
1584 | {"yas532" , (kernel_ulong_t)&yas5xx_chip_info_tbl[yas532] }, |
1585 | {"yas533" , (kernel_ulong_t)&yas5xx_chip_info_tbl[yas533] }, |
1586 | {"yas537" , (kernel_ulong_t)&yas5xx_chip_info_tbl[yas537] }, |
1587 | {} |
1588 | }; |
1589 | MODULE_DEVICE_TABLE(i2c, yas5xx_id); |
1590 | |
1591 | static const struct of_device_id yas5xx_of_match[] = { |
1592 | { .compatible = "yamaha,yas530" , &yas5xx_chip_info_tbl[yas530] }, |
1593 | { .compatible = "yamaha,yas532" , &yas5xx_chip_info_tbl[yas532] }, |
1594 | { .compatible = "yamaha,yas533" , &yas5xx_chip_info_tbl[yas533] }, |
1595 | { .compatible = "yamaha,yas537" , &yas5xx_chip_info_tbl[yas537] }, |
1596 | {} |
1597 | }; |
1598 | MODULE_DEVICE_TABLE(of, yas5xx_of_match); |
1599 | |
1600 | static struct i2c_driver yas5xx_driver = { |
1601 | .driver = { |
1602 | .name = "yas5xx" , |
1603 | .of_match_table = yas5xx_of_match, |
1604 | .pm = pm_ptr(&yas5xx_dev_pm_ops), |
1605 | }, |
1606 | .probe = yas5xx_probe, |
1607 | .remove = yas5xx_remove, |
1608 | .id_table = yas5xx_id, |
1609 | }; |
1610 | module_i2c_driver(yas5xx_driver); |
1611 | |
1612 | MODULE_DESCRIPTION("Yamaha YAS53x 3-axis magnetometer driver" ); |
1613 | MODULE_AUTHOR("Linus Walleij" ); |
1614 | MODULE_LICENSE("GPL v2" ); |
1615 | |