1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * kxsd9.c simple support for the Kionix KXSD9 3D |
4 | * accelerometer. |
5 | * |
6 | * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org> |
7 | * |
8 | * The i2c interface is very similar, so shouldn't be a problem once |
9 | * I have a suitable wire made up. |
10 | * |
11 | * TODO: Support the motion detector |
12 | */ |
13 | |
14 | #include <linux/device.h> |
15 | #include <linux/kernel.h> |
16 | #include <linux/sysfs.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/module.h> |
19 | #include <linux/regmap.h> |
20 | #include <linux/bitops.h> |
21 | #include <linux/delay.h> |
22 | #include <linux/regulator/consumer.h> |
23 | #include <linux/pm_runtime.h> |
24 | #include <linux/iio/iio.h> |
25 | #include <linux/iio/sysfs.h> |
26 | #include <linux/iio/buffer.h> |
27 | #include <linux/iio/triggered_buffer.h> |
28 | #include <linux/iio/trigger_consumer.h> |
29 | |
30 | #include "kxsd9.h" |
31 | |
32 | #define KXSD9_REG_X 0x00 |
33 | #define KXSD9_REG_Y 0x02 |
34 | #define KXSD9_REG_Z 0x04 |
35 | #define KXSD9_REG_AUX 0x06 |
36 | #define KXSD9_REG_RESET 0x0a |
37 | #define KXSD9_REG_CTRL_C 0x0c |
38 | |
39 | #define KXSD9_CTRL_C_FS_MASK 0x03 |
40 | #define KXSD9_CTRL_C_FS_8G 0x00 |
41 | #define KXSD9_CTRL_C_FS_6G 0x01 |
42 | #define KXSD9_CTRL_C_FS_4G 0x02 |
43 | #define KXSD9_CTRL_C_FS_2G 0x03 |
44 | #define KXSD9_CTRL_C_MOT_LAT BIT(3) |
45 | #define KXSD9_CTRL_C_MOT_LEV BIT(4) |
46 | #define KXSD9_CTRL_C_LP_MASK 0xe0 |
47 | #define KXSD9_CTRL_C_LP_NONE 0x00 |
48 | #define KXSD9_CTRL_C_LP_2000HZC BIT(5) |
49 | #define KXSD9_CTRL_C_LP_2000HZB BIT(6) |
50 | #define KXSD9_CTRL_C_LP_2000HZA (BIT(5)|BIT(6)) |
51 | #define KXSD9_CTRL_C_LP_1000HZ BIT(7) |
52 | #define KXSD9_CTRL_C_LP_500HZ (BIT(7)|BIT(5)) |
53 | #define KXSD9_CTRL_C_LP_100HZ (BIT(7)|BIT(6)) |
54 | #define KXSD9_CTRL_C_LP_50HZ (BIT(7)|BIT(6)|BIT(5)) |
55 | |
56 | #define KXSD9_REG_CTRL_B 0x0d |
57 | |
58 | #define KXSD9_CTRL_B_CLK_HLD BIT(7) |
59 | #define KXSD9_CTRL_B_ENABLE BIT(6) |
60 | #define KXSD9_CTRL_B_ST BIT(5) /* Self-test */ |
61 | |
62 | #define KXSD9_REG_CTRL_A 0x0e |
63 | |
64 | /** |
65 | * struct kxsd9_state - device related storage |
66 | * @dev: pointer to the parent device |
67 | * @map: regmap to the device |
68 | * @orientation: mounting matrix, flipped axis etc |
69 | * @regs: regulators for this device, VDD and IOVDD |
70 | * @scale: the current scaling setting |
71 | */ |
72 | struct kxsd9_state { |
73 | struct device *dev; |
74 | struct regmap *map; |
75 | struct iio_mount_matrix orientation; |
76 | struct regulator_bulk_data regs[2]; |
77 | u8 scale; |
78 | }; |
79 | |
80 | #define KXSD9_SCALE_2G "0.011978" |
81 | #define KXSD9_SCALE_4G "0.023927" |
82 | #define KXSD9_SCALE_6G "0.035934" |
83 | #define KXSD9_SCALE_8G "0.047853" |
84 | |
85 | /* reverse order */ |
86 | static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 }; |
87 | |
88 | #define KXSD9_ZERO_G_OFFSET -2048 |
89 | |
90 | /* |
91 | * Regulator names |
92 | */ |
93 | static const char kxsd9_reg_vdd[] = "vdd" ; |
94 | static const char kxsd9_reg_iovdd[] = "iovdd" ; |
95 | |
96 | static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro) |
97 | { |
98 | int ret, i; |
99 | struct kxsd9_state *st = iio_priv(indio_dev); |
100 | bool foundit = false; |
101 | |
102 | for (i = 0; i < 4; i++) |
103 | if (micro == kxsd9_micro_scales[i]) { |
104 | foundit = true; |
105 | break; |
106 | } |
107 | if (!foundit) |
108 | return -EINVAL; |
109 | |
110 | ret = regmap_update_bits(map: st->map, |
111 | KXSD9_REG_CTRL_C, |
112 | KXSD9_CTRL_C_FS_MASK, |
113 | val: i); |
114 | if (ret < 0) |
115 | goto error_ret; |
116 | |
117 | /* Cached scale when the sensor is powered down */ |
118 | st->scale = i; |
119 | |
120 | error_ret: |
121 | return ret; |
122 | } |
123 | |
124 | static IIO_CONST_ATTR(accel_scale_available, |
125 | KXSD9_SCALE_2G " " |
126 | KXSD9_SCALE_4G " " |
127 | KXSD9_SCALE_6G " " |
128 | KXSD9_SCALE_8G); |
129 | |
130 | static struct attribute *kxsd9_attributes[] = { |
131 | &iio_const_attr_accel_scale_available.dev_attr.attr, |
132 | NULL, |
133 | }; |
134 | |
135 | static int kxsd9_write_raw(struct iio_dev *indio_dev, |
136 | struct iio_chan_spec const *chan, |
137 | int val, |
138 | int val2, |
139 | long mask) |
140 | { |
141 | int ret = -EINVAL; |
142 | struct kxsd9_state *st = iio_priv(indio_dev); |
143 | |
144 | pm_runtime_get_sync(dev: st->dev); |
145 | |
146 | if (mask == IIO_CHAN_INFO_SCALE) { |
147 | /* Check no integer component */ |
148 | if (val) |
149 | return -EINVAL; |
150 | ret = kxsd9_write_scale(indio_dev, micro: val2); |
151 | } |
152 | |
153 | pm_runtime_mark_last_busy(dev: st->dev); |
154 | pm_runtime_put_autosuspend(dev: st->dev); |
155 | |
156 | return ret; |
157 | } |
158 | |
159 | static int kxsd9_read_raw(struct iio_dev *indio_dev, |
160 | struct iio_chan_spec const *chan, |
161 | int *val, int *val2, long mask) |
162 | { |
163 | int ret = -EINVAL; |
164 | struct kxsd9_state *st = iio_priv(indio_dev); |
165 | unsigned int regval; |
166 | __be16 raw_val; |
167 | u16 nval; |
168 | |
169 | pm_runtime_get_sync(dev: st->dev); |
170 | |
171 | switch (mask) { |
172 | case IIO_CHAN_INFO_RAW: |
173 | ret = regmap_bulk_read(map: st->map, reg: chan->address, val: &raw_val, |
174 | val_count: sizeof(raw_val)); |
175 | if (ret) |
176 | goto error_ret; |
177 | nval = be16_to_cpu(raw_val); |
178 | /* Only 12 bits are valid */ |
179 | nval >>= 4; |
180 | *val = nval; |
181 | ret = IIO_VAL_INT; |
182 | break; |
183 | case IIO_CHAN_INFO_OFFSET: |
184 | /* This has a bias of -2048 */ |
185 | *val = KXSD9_ZERO_G_OFFSET; |
186 | ret = IIO_VAL_INT; |
187 | break; |
188 | case IIO_CHAN_INFO_SCALE: |
189 | ret = regmap_read(map: st->map, |
190 | KXSD9_REG_CTRL_C, |
191 | val: ®val); |
192 | if (ret < 0) |
193 | goto error_ret; |
194 | *val = 0; |
195 | *val2 = kxsd9_micro_scales[regval & KXSD9_CTRL_C_FS_MASK]; |
196 | ret = IIO_VAL_INT_PLUS_MICRO; |
197 | break; |
198 | } |
199 | |
200 | error_ret: |
201 | pm_runtime_mark_last_busy(dev: st->dev); |
202 | pm_runtime_put_autosuspend(dev: st->dev); |
203 | |
204 | return ret; |
205 | }; |
206 | |
207 | static irqreturn_t kxsd9_trigger_handler(int irq, void *p) |
208 | { |
209 | const struct iio_poll_func *pf = p; |
210 | struct iio_dev *indio_dev = pf->indio_dev; |
211 | struct kxsd9_state *st = iio_priv(indio_dev); |
212 | /* |
213 | * Ensure correct positioning and alignment of timestamp. |
214 | * No need to zero initialize as all elements written. |
215 | */ |
216 | struct { |
217 | __be16 chan[4]; |
218 | s64 ts __aligned(8); |
219 | } hw_values; |
220 | int ret; |
221 | |
222 | ret = regmap_bulk_read(map: st->map, |
223 | KXSD9_REG_X, |
224 | val: hw_values.chan, |
225 | val_count: sizeof(hw_values.chan)); |
226 | if (ret) { |
227 | dev_err(st->dev, "error reading data: %d\n" , ret); |
228 | goto out; |
229 | } |
230 | |
231 | iio_push_to_buffers_with_timestamp(indio_dev, |
232 | data: &hw_values, |
233 | timestamp: iio_get_time_ns(indio_dev)); |
234 | out: |
235 | iio_trigger_notify_done(trig: indio_dev->trig); |
236 | |
237 | return IRQ_HANDLED; |
238 | } |
239 | |
240 | static int kxsd9_buffer_preenable(struct iio_dev *indio_dev) |
241 | { |
242 | struct kxsd9_state *st = iio_priv(indio_dev); |
243 | |
244 | pm_runtime_get_sync(dev: st->dev); |
245 | |
246 | return 0; |
247 | } |
248 | |
249 | static int kxsd9_buffer_postdisable(struct iio_dev *indio_dev) |
250 | { |
251 | struct kxsd9_state *st = iio_priv(indio_dev); |
252 | |
253 | pm_runtime_mark_last_busy(dev: st->dev); |
254 | pm_runtime_put_autosuspend(dev: st->dev); |
255 | |
256 | return 0; |
257 | } |
258 | |
259 | static const struct iio_buffer_setup_ops kxsd9_buffer_setup_ops = { |
260 | .preenable = kxsd9_buffer_preenable, |
261 | .postdisable = kxsd9_buffer_postdisable, |
262 | }; |
263 | |
264 | static const struct iio_mount_matrix * |
265 | kxsd9_get_mount_matrix(const struct iio_dev *indio_dev, |
266 | const struct iio_chan_spec *chan) |
267 | { |
268 | struct kxsd9_state *st = iio_priv(indio_dev); |
269 | |
270 | return &st->orientation; |
271 | } |
272 | |
273 | static const struct iio_chan_spec_ext_info kxsd9_ext_info[] = { |
274 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kxsd9_get_mount_matrix), |
275 | { }, |
276 | }; |
277 | |
278 | #define KXSD9_ACCEL_CHAN(axis, index) \ |
279 | { \ |
280 | .type = IIO_ACCEL, \ |
281 | .modified = 1, \ |
282 | .channel2 = IIO_MOD_##axis, \ |
283 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
284 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ |
285 | BIT(IIO_CHAN_INFO_OFFSET), \ |
286 | .ext_info = kxsd9_ext_info, \ |
287 | .address = KXSD9_REG_##axis, \ |
288 | .scan_index = index, \ |
289 | .scan_type = { \ |
290 | .sign = 'u', \ |
291 | .realbits = 12, \ |
292 | .storagebits = 16, \ |
293 | .shift = 4, \ |
294 | .endianness = IIO_BE, \ |
295 | }, \ |
296 | } |
297 | |
298 | static const struct iio_chan_spec kxsd9_channels[] = { |
299 | KXSD9_ACCEL_CHAN(X, 0), |
300 | KXSD9_ACCEL_CHAN(Y, 1), |
301 | KXSD9_ACCEL_CHAN(Z, 2), |
302 | { |
303 | .type = IIO_VOLTAGE, |
304 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
305 | .indexed = 1, |
306 | .address = KXSD9_REG_AUX, |
307 | .scan_index = 3, |
308 | .scan_type = { |
309 | .sign = 'u', |
310 | .realbits = 12, |
311 | .storagebits = 16, |
312 | .shift = 4, |
313 | .endianness = IIO_BE, |
314 | }, |
315 | }, |
316 | IIO_CHAN_SOFT_TIMESTAMP(4), |
317 | }; |
318 | |
319 | static const struct attribute_group kxsd9_attribute_group = { |
320 | .attrs = kxsd9_attributes, |
321 | }; |
322 | |
323 | static int kxsd9_power_up(struct kxsd9_state *st) |
324 | { |
325 | int ret; |
326 | |
327 | /* Enable the regulators */ |
328 | ret = regulator_bulk_enable(ARRAY_SIZE(st->regs), consumers: st->regs); |
329 | if (ret) { |
330 | dev_err(st->dev, "Cannot enable regulators\n" ); |
331 | return ret; |
332 | } |
333 | |
334 | /* Power up */ |
335 | ret = regmap_write(map: st->map, |
336 | KXSD9_REG_CTRL_B, |
337 | KXSD9_CTRL_B_ENABLE); |
338 | if (ret) |
339 | return ret; |
340 | |
341 | /* |
342 | * Set 1000Hz LPF, 2g fullscale, motion wakeup threshold 1g, |
343 | * latched wakeup |
344 | */ |
345 | ret = regmap_write(map: st->map, |
346 | KXSD9_REG_CTRL_C, |
347 | KXSD9_CTRL_C_LP_1000HZ | |
348 | KXSD9_CTRL_C_MOT_LEV | |
349 | KXSD9_CTRL_C_MOT_LAT | |
350 | st->scale); |
351 | if (ret) |
352 | return ret; |
353 | |
354 | /* |
355 | * Power-up time depends on the LPF setting, but typ 15.9 ms, let's |
356 | * set 20 ms to allow for some slack. |
357 | */ |
358 | msleep(msecs: 20); |
359 | |
360 | return 0; |
361 | }; |
362 | |
363 | static int kxsd9_power_down(struct kxsd9_state *st) |
364 | { |
365 | int ret; |
366 | |
367 | /* |
368 | * Set into low power mode - since there may be more users of the |
369 | * regulators this is the first step of the power saving: it will |
370 | * make sure we conserve power even if there are others users on the |
371 | * regulators. |
372 | */ |
373 | ret = regmap_update_bits(map: st->map, |
374 | KXSD9_REG_CTRL_B, |
375 | KXSD9_CTRL_B_ENABLE, |
376 | val: 0); |
377 | if (ret) |
378 | return ret; |
379 | |
380 | /* Disable the regulators */ |
381 | ret = regulator_bulk_disable(ARRAY_SIZE(st->regs), consumers: st->regs); |
382 | if (ret) { |
383 | dev_err(st->dev, "Cannot disable regulators\n" ); |
384 | return ret; |
385 | } |
386 | |
387 | return 0; |
388 | } |
389 | |
390 | static const struct iio_info kxsd9_info = { |
391 | .read_raw = &kxsd9_read_raw, |
392 | .write_raw = &kxsd9_write_raw, |
393 | .attrs = &kxsd9_attribute_group, |
394 | }; |
395 | |
396 | /* Four channels apart from timestamp, scan mask = 0x0f */ |
397 | static const unsigned long kxsd9_scan_masks[] = { 0xf, 0 }; |
398 | |
399 | int kxsd9_common_probe(struct device *dev, |
400 | struct regmap *map, |
401 | const char *name) |
402 | { |
403 | struct iio_dev *indio_dev; |
404 | struct kxsd9_state *st; |
405 | int ret; |
406 | |
407 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*st)); |
408 | if (!indio_dev) |
409 | return -ENOMEM; |
410 | |
411 | st = iio_priv(indio_dev); |
412 | st->dev = dev; |
413 | st->map = map; |
414 | |
415 | indio_dev->channels = kxsd9_channels; |
416 | indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels); |
417 | indio_dev->name = name; |
418 | indio_dev->info = &kxsd9_info; |
419 | indio_dev->modes = INDIO_DIRECT_MODE; |
420 | indio_dev->available_scan_masks = kxsd9_scan_masks; |
421 | |
422 | /* Read the mounting matrix, if present */ |
423 | ret = iio_read_mount_matrix(dev, matrix: &st->orientation); |
424 | if (ret) |
425 | return ret; |
426 | |
427 | /* Fetch and turn on regulators */ |
428 | st->regs[0].supply = kxsd9_reg_vdd; |
429 | st->regs[1].supply = kxsd9_reg_iovdd; |
430 | ret = devm_regulator_bulk_get(dev, |
431 | ARRAY_SIZE(st->regs), |
432 | consumers: st->regs); |
433 | if (ret) { |
434 | dev_err(dev, "Cannot get regulators\n" ); |
435 | return ret; |
436 | } |
437 | /* Default scaling */ |
438 | st->scale = KXSD9_CTRL_C_FS_2G; |
439 | |
440 | kxsd9_power_up(st); |
441 | |
442 | ret = iio_triggered_buffer_setup(indio_dev, |
443 | iio_pollfunc_store_time, |
444 | kxsd9_trigger_handler, |
445 | &kxsd9_buffer_setup_ops); |
446 | if (ret) { |
447 | dev_err(dev, "triggered buffer setup failed\n" ); |
448 | goto err_power_down; |
449 | } |
450 | |
451 | ret = iio_device_register(indio_dev); |
452 | if (ret) |
453 | goto err_cleanup_buffer; |
454 | |
455 | dev_set_drvdata(dev, data: indio_dev); |
456 | |
457 | /* Enable runtime PM */ |
458 | pm_runtime_get_noresume(dev); |
459 | pm_runtime_set_active(dev); |
460 | pm_runtime_enable(dev); |
461 | /* |
462 | * Set autosuspend to two orders of magnitude larger than the |
463 | * start-up time. 20ms start-up time means 2000ms autosuspend, |
464 | * i.e. 2 seconds. |
465 | */ |
466 | pm_runtime_set_autosuspend_delay(dev, delay: 2000); |
467 | pm_runtime_use_autosuspend(dev); |
468 | pm_runtime_put(dev); |
469 | |
470 | return 0; |
471 | |
472 | err_cleanup_buffer: |
473 | iio_triggered_buffer_cleanup(indio_dev); |
474 | err_power_down: |
475 | kxsd9_power_down(st); |
476 | |
477 | return ret; |
478 | } |
479 | EXPORT_SYMBOL_NS(kxsd9_common_probe, IIO_KXSD9); |
480 | |
481 | void kxsd9_common_remove(struct device *dev) |
482 | { |
483 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
484 | struct kxsd9_state *st = iio_priv(indio_dev); |
485 | |
486 | iio_triggered_buffer_cleanup(indio_dev); |
487 | iio_device_unregister(indio_dev); |
488 | pm_runtime_get_sync(dev); |
489 | pm_runtime_put_noidle(dev); |
490 | pm_runtime_disable(dev); |
491 | kxsd9_power_down(st); |
492 | } |
493 | EXPORT_SYMBOL_NS(kxsd9_common_remove, IIO_KXSD9); |
494 | |
495 | static int kxsd9_runtime_suspend(struct device *dev) |
496 | { |
497 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
498 | struct kxsd9_state *st = iio_priv(indio_dev); |
499 | |
500 | return kxsd9_power_down(st); |
501 | } |
502 | |
503 | static int kxsd9_runtime_resume(struct device *dev) |
504 | { |
505 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
506 | struct kxsd9_state *st = iio_priv(indio_dev); |
507 | |
508 | return kxsd9_power_up(st); |
509 | } |
510 | |
511 | EXPORT_NS_RUNTIME_DEV_PM_OPS(kxsd9_dev_pm_ops, kxsd9_runtime_suspend, |
512 | kxsd9_runtime_resume, NULL, IIO_KXSD9); |
513 | |
514 | MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>" ); |
515 | MODULE_DESCRIPTION("Kionix KXSD9 driver" ); |
516 | MODULE_LICENSE("GPL v2" ); |
517 | |