1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * 3-axis accelerometer driver for MXC4005XC Memsic sensor
4 *
5 * Copyright (c) 2014, Intel Corporation.
6 */
7
8#include <linux/delay.h>
9#include <linux/module.h>
10#include <linux/i2c.h>
11#include <linux/iio/iio.h>
12#include <linux/mod_devicetable.h>
13#include <linux/regmap.h>
14#include <linux/types.h>
15#include <linux/iio/sysfs.h>
16#include <linux/iio/trigger.h>
17#include <linux/iio/buffer.h>
18#include <linux/iio/triggered_buffer.h>
19#include <linux/iio/trigger_consumer.h>
20
21#define MXC4005_DRV_NAME "mxc4005"
22
23#define MXC4005_REG_XOUT_UPPER 0x03
24#define MXC4005_REG_XOUT_LOWER 0x04
25#define MXC4005_REG_YOUT_UPPER 0x05
26#define MXC4005_REG_YOUT_LOWER 0x06
27#define MXC4005_REG_ZOUT_UPPER 0x07
28#define MXC4005_REG_ZOUT_LOWER 0x08
29
30#define MXC4005_REG_INT_MASK0 0x0A
31
32#define MXC4005_REG_INT_MASK1 0x0B
33#define MXC4005_REG_INT_MASK1_BIT_DRDYE 0x01
34
35#define MXC4005_REG_INT_CLR0 0x00
36
37#define MXC4005_REG_INT_CLR1 0x01
38#define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01
39#define MXC4005_REG_INT_CLR1_SW_RST 0x10
40
41#define MXC4005_REG_CONTROL 0x0D
42#define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5)
43#define MXC4005_CONTROL_FSR_SHIFT 5
44
45#define MXC4005_REG_DEVICE_ID 0x0E
46
47/* Datasheet does not specify a reset time, this is a conservative guess */
48#define MXC4005_RESET_TIME_US 2000
49
50enum mxc4005_axis {
51 AXIS_X,
52 AXIS_Y,
53 AXIS_Z,
54};
55
56enum mxc4005_range {
57 MXC4005_RANGE_2G,
58 MXC4005_RANGE_4G,
59 MXC4005_RANGE_8G,
60};
61
62struct mxc4005_data {
63 struct device *dev;
64 struct mutex mutex;
65 struct regmap *regmap;
66 struct iio_trigger *dready_trig;
67 struct iio_mount_matrix orientation;
68 /* Ensure timestamp is naturally aligned */
69 struct {
70 __be16 chans[3];
71 aligned_s64 timestamp;
72 } scan;
73 bool trigger_enabled;
74 unsigned int control;
75 unsigned int int_mask1;
76};
77
78/*
79 * MXC4005 can operate in the following ranges:
80 * +/- 2G, 4G, 8G (the default +/-2G)
81 *
82 * (2 + 2) * 9.81 / (2^12 - 1) = 0.009582
83 * (4 + 4) * 9.81 / (2^12 - 1) = 0.019164
84 * (8 + 8) * 9.81 / (2^12 - 1) = 0.038329
85 */
86static const struct {
87 u8 range;
88 int scale;
89} mxc4005_scale_table[] = {
90 {MXC4005_RANGE_2G, 9582},
91 {MXC4005_RANGE_4G, 19164},
92 {MXC4005_RANGE_8G, 38329},
93};
94
95
96static IIO_CONST_ATTR(in_accel_scale_available, "0.009582 0.019164 0.038329");
97
98static struct attribute *mxc4005_attributes[] = {
99 &iio_const_attr_in_accel_scale_available.dev_attr.attr,
100 NULL,
101};
102
103static const struct attribute_group mxc4005_attrs_group = {
104 .attrs = mxc4005_attributes,
105};
106
107static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
108{
109 switch (reg) {
110 case MXC4005_REG_XOUT_UPPER:
111 case MXC4005_REG_XOUT_LOWER:
112 case MXC4005_REG_YOUT_UPPER:
113 case MXC4005_REG_YOUT_LOWER:
114 case MXC4005_REG_ZOUT_UPPER:
115 case MXC4005_REG_ZOUT_LOWER:
116 case MXC4005_REG_DEVICE_ID:
117 case MXC4005_REG_CONTROL:
118 return true;
119 default:
120 return false;
121 }
122}
123
124static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
125{
126 switch (reg) {
127 case MXC4005_REG_INT_CLR0:
128 case MXC4005_REG_INT_CLR1:
129 case MXC4005_REG_INT_MASK0:
130 case MXC4005_REG_INT_MASK1:
131 case MXC4005_REG_CONTROL:
132 return true;
133 default:
134 return false;
135 }
136}
137
138static const struct regmap_config mxc4005_regmap_config = {
139 .name = "mxc4005_regmap",
140
141 .reg_bits = 8,
142 .val_bits = 8,
143
144 .max_register = MXC4005_REG_DEVICE_ID,
145
146 .readable_reg = mxc4005_is_readable_reg,
147 .writeable_reg = mxc4005_is_writeable_reg,
148};
149
150static int mxc4005_read_xyz(struct mxc4005_data *data)
151{
152 int ret;
153
154 ret = regmap_bulk_read(map: data->regmap, MXC4005_REG_XOUT_UPPER,
155 val: data->scan.chans, val_count: sizeof(data->scan.chans));
156 if (ret < 0) {
157 dev_err(data->dev, "failed to read axes\n");
158 return ret;
159 }
160
161 return 0;
162}
163
164static int mxc4005_read_axis(struct mxc4005_data *data,
165 unsigned int addr)
166{
167 __be16 reg;
168 int ret;
169
170 ret = regmap_bulk_read(map: data->regmap, reg: addr, val: &reg, val_count: sizeof(reg));
171 if (ret < 0) {
172 dev_err(data->dev, "failed to read reg %02x\n", addr);
173 return ret;
174 }
175
176 return be16_to_cpu(reg);
177}
178
179static int mxc4005_read_scale(struct mxc4005_data *data)
180{
181 unsigned int reg;
182 int ret;
183 int i;
184
185 ret = regmap_read(map: data->regmap, MXC4005_REG_CONTROL, val: &reg);
186 if (ret < 0) {
187 dev_err(data->dev, "failed to read reg_control\n");
188 return ret;
189 }
190
191 i = reg >> MXC4005_CONTROL_FSR_SHIFT;
192
193 if (i < 0 || i >= ARRAY_SIZE(mxc4005_scale_table))
194 return -EINVAL;
195
196 return mxc4005_scale_table[i].scale;
197}
198
199static int mxc4005_set_scale(struct mxc4005_data *data, int val)
200{
201 unsigned int reg;
202 int i;
203 int ret;
204
205 for (i = 0; i < ARRAY_SIZE(mxc4005_scale_table); i++) {
206 if (mxc4005_scale_table[i].scale == val) {
207 reg = i << MXC4005_CONTROL_FSR_SHIFT;
208 ret = regmap_update_bits(map: data->regmap,
209 MXC4005_REG_CONTROL,
210 MXC4005_REG_CONTROL_MASK_FSR,
211 val: reg);
212 if (ret < 0)
213 dev_err(data->dev,
214 "failed to write reg_control\n");
215 return ret;
216 }
217 }
218
219 return -EINVAL;
220}
221
222static int mxc4005_read_raw(struct iio_dev *indio_dev,
223 struct iio_chan_spec const *chan,
224 int *val, int *val2, long mask)
225{
226 struct mxc4005_data *data = iio_priv(indio_dev);
227 int ret;
228
229 switch (mask) {
230 case IIO_CHAN_INFO_RAW:
231 switch (chan->type) {
232 case IIO_ACCEL:
233 if (iio_buffer_enabled(indio_dev))
234 return -EBUSY;
235
236 ret = mxc4005_read_axis(data, addr: chan->address);
237 if (ret < 0)
238 return ret;
239 *val = sign_extend32(value: ret >> chan->scan_type.shift,
240 index: chan->scan_type.realbits - 1);
241 return IIO_VAL_INT;
242 default:
243 return -EINVAL;
244 }
245 case IIO_CHAN_INFO_SCALE:
246 ret = mxc4005_read_scale(data);
247 if (ret < 0)
248 return ret;
249
250 *val = 0;
251 *val2 = ret;
252 return IIO_VAL_INT_PLUS_MICRO;
253 default:
254 return -EINVAL;
255 }
256}
257
258static int mxc4005_write_raw(struct iio_dev *indio_dev,
259 struct iio_chan_spec const *chan,
260 int val, int val2, long mask)
261{
262 struct mxc4005_data *data = iio_priv(indio_dev);
263
264 switch (mask) {
265 case IIO_CHAN_INFO_SCALE:
266 if (val != 0)
267 return -EINVAL;
268
269 return mxc4005_set_scale(data, val: val2);
270 default:
271 return -EINVAL;
272 }
273}
274
275static const struct iio_mount_matrix *
276mxc4005_get_mount_matrix(const struct iio_dev *indio_dev,
277 const struct iio_chan_spec *chan)
278{
279 struct mxc4005_data *data = iio_priv(indio_dev);
280
281 return &data->orientation;
282}
283
284static const struct iio_chan_spec_ext_info mxc4005_ext_info[] = {
285 IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, mxc4005_get_mount_matrix),
286 { }
287};
288
289static const struct iio_info mxc4005_info = {
290 .read_raw = mxc4005_read_raw,
291 .write_raw = mxc4005_write_raw,
292 .attrs = &mxc4005_attrs_group,
293};
294
295static const unsigned long mxc4005_scan_masks[] = {
296 BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
297 0
298};
299
300#define MXC4005_CHANNEL(_axis, _addr) { \
301 .type = IIO_ACCEL, \
302 .modified = 1, \
303 .channel2 = IIO_MOD_##_axis, \
304 .address = _addr, \
305 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
306 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
307 .scan_index = AXIS_##_axis, \
308 .scan_type = { \
309 .sign = 's', \
310 .realbits = 12, \
311 .storagebits = 16, \
312 .shift = 4, \
313 .endianness = IIO_BE, \
314 }, \
315 .ext_info = mxc4005_ext_info, \
316}
317
318static const struct iio_chan_spec mxc4005_channels[] = {
319 MXC4005_CHANNEL(X, MXC4005_REG_XOUT_UPPER),
320 MXC4005_CHANNEL(Y, MXC4005_REG_YOUT_UPPER),
321 MXC4005_CHANNEL(Z, MXC4005_REG_ZOUT_UPPER),
322 IIO_CHAN_SOFT_TIMESTAMP(3),
323};
324
325static irqreturn_t mxc4005_trigger_handler(int irq, void *private)
326{
327 struct iio_poll_func *pf = private;
328 struct iio_dev *indio_dev = pf->indio_dev;
329 struct mxc4005_data *data = iio_priv(indio_dev);
330 int ret;
331
332 ret = mxc4005_read_xyz(data);
333 if (ret < 0)
334 goto err;
335
336 iio_push_to_buffers_with_ts(indio_dev, data: &data->scan, data_total_len: sizeof(data->scan),
337 timestamp: pf->timestamp);
338
339err:
340 iio_trigger_notify_done(trig: indio_dev->trig);
341
342 return IRQ_HANDLED;
343}
344
345static void mxc4005_clr_intr(struct mxc4005_data *data)
346{
347 int ret;
348
349 /* clear interrupt */
350 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_CLR1,
351 MXC4005_REG_INT_CLR1_BIT_DRDYC);
352 if (ret < 0)
353 dev_err(data->dev, "failed to write to reg_int_clr1\n");
354}
355
356static int mxc4005_set_trigger_state(struct iio_trigger *trig,
357 bool state)
358{
359 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
360 struct mxc4005_data *data = iio_priv(indio_dev);
361 unsigned int val;
362 int ret;
363
364 mutex_lock(&data->mutex);
365
366 val = state ? MXC4005_REG_INT_MASK1_BIT_DRDYE : 0;
367 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_MASK1, val);
368 if (ret < 0) {
369 mutex_unlock(lock: &data->mutex);
370 dev_err(data->dev, "failed to update reg_int_mask1");
371 return ret;
372 }
373
374 data->int_mask1 = val;
375 data->trigger_enabled = state;
376 mutex_unlock(lock: &data->mutex);
377
378 return 0;
379}
380
381static void mxc4005_trigger_reen(struct iio_trigger *trig)
382{
383 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
384 struct mxc4005_data *data = iio_priv(indio_dev);
385
386 if (!data->dready_trig)
387 return;
388
389 mxc4005_clr_intr(data);
390}
391
392static const struct iio_trigger_ops mxc4005_trigger_ops = {
393 .set_trigger_state = mxc4005_set_trigger_state,
394 .reenable = mxc4005_trigger_reen,
395};
396
397static int mxc4005_chip_init(struct mxc4005_data *data)
398{
399 int ret;
400 unsigned int reg;
401
402 ret = regmap_read(map: data->regmap, MXC4005_REG_DEVICE_ID, val: &reg);
403 if (ret < 0) {
404 dev_err(data->dev, "failed to read chip id\n");
405 return ret;
406 }
407
408 dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg);
409
410 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_CLR1,
411 MXC4005_REG_INT_CLR1_SW_RST);
412 if (ret < 0)
413 return dev_err_probe(dev: data->dev, err: ret, fmt: "resetting chip\n");
414
415 fsleep(MXC4005_RESET_TIME_US);
416
417 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_MASK0, val: 0);
418 if (ret < 0)
419 return dev_err_probe(dev: data->dev, err: ret, fmt: "writing INT_MASK0\n");
420
421 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_MASK1, val: 0);
422 if (ret < 0)
423 return dev_err_probe(dev: data->dev, err: ret, fmt: "writing INT_MASK1\n");
424
425 return 0;
426}
427
428static int mxc4005_probe(struct i2c_client *client)
429{
430 struct mxc4005_data *data;
431 struct iio_dev *indio_dev;
432 struct regmap *regmap;
433 int ret;
434
435 indio_dev = devm_iio_device_alloc(parent: &client->dev, sizeof_priv: sizeof(*data));
436 if (!indio_dev)
437 return -ENOMEM;
438
439 regmap = devm_regmap_init_i2c(client, &mxc4005_regmap_config);
440 if (IS_ERR(ptr: regmap)) {
441 dev_err(&client->dev, "failed to initialize regmap\n");
442 return PTR_ERR(ptr: regmap);
443 }
444
445 data = iio_priv(indio_dev);
446 i2c_set_clientdata(client, data: indio_dev);
447 data->dev = &client->dev;
448 data->regmap = regmap;
449
450 ret = mxc4005_chip_init(data);
451 if (ret < 0) {
452 dev_err(&client->dev, "failed to initialize chip\n");
453 return ret;
454 }
455
456 mutex_init(&data->mutex);
457
458 if (!iio_read_acpi_mount_matrix(dev: &client->dev, orientation: &data->orientation, acpi_method: "ROTM")) {
459 ret = iio_read_mount_matrix(dev: &client->dev, matrix: &data->orientation);
460 if (ret)
461 return ret;
462 }
463
464 indio_dev->channels = mxc4005_channels;
465 indio_dev->num_channels = ARRAY_SIZE(mxc4005_channels);
466 indio_dev->available_scan_masks = mxc4005_scan_masks;
467 indio_dev->name = MXC4005_DRV_NAME;
468 indio_dev->modes = INDIO_DIRECT_MODE;
469 indio_dev->info = &mxc4005_info;
470
471 ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
472 iio_pollfunc_store_time,
473 mxc4005_trigger_handler,
474 NULL);
475 if (ret < 0) {
476 dev_err(&client->dev,
477 "failed to setup iio triggered buffer\n");
478 return ret;
479 }
480
481 if (client->irq > 0) {
482 data->dready_trig = devm_iio_trigger_alloc(&client->dev,
483 "%s-dev%d",
484 indio_dev->name,
485 iio_device_id(indio_dev));
486 if (!data->dready_trig)
487 return -ENOMEM;
488
489 ret = devm_request_threaded_irq(dev: &client->dev, irq: client->irq,
490 handler: iio_trigger_generic_data_rdy_poll,
491 NULL,
492 IRQF_TRIGGER_FALLING |
493 IRQF_ONESHOT,
494 devname: "mxc4005_event",
495 dev_id: data->dready_trig);
496 if (ret) {
497 dev_err(&client->dev,
498 "failed to init threaded irq\n");
499 return ret;
500 }
501
502 data->dready_trig->ops = &mxc4005_trigger_ops;
503 iio_trigger_set_drvdata(trig: data->dready_trig, data: indio_dev);
504 ret = devm_iio_trigger_register(dev: &client->dev,
505 trig_info: data->dready_trig);
506 if (ret) {
507 dev_err(&client->dev,
508 "failed to register trigger\n");
509 return ret;
510 }
511
512 indio_dev->trig = iio_trigger_get(trig: data->dready_trig);
513 }
514
515 return devm_iio_device_register(&client->dev, indio_dev);
516}
517
518static int mxc4005_suspend(struct device *dev)
519{
520 struct iio_dev *indio_dev = dev_get_drvdata(dev);
521 struct mxc4005_data *data = iio_priv(indio_dev);
522 int ret;
523
524 /* Save control to restore it on resume */
525 ret = regmap_read(map: data->regmap, MXC4005_REG_CONTROL, val: &data->control);
526 if (ret < 0)
527 dev_err(data->dev, "failed to read reg_control\n");
528
529 return ret;
530}
531
532static int mxc4005_resume(struct device *dev)
533{
534 struct iio_dev *indio_dev = dev_get_drvdata(dev);
535 struct mxc4005_data *data = iio_priv(indio_dev);
536 int ret;
537
538 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_CLR1,
539 MXC4005_REG_INT_CLR1_SW_RST);
540 if (ret) {
541 dev_err(data->dev, "failed to reset chip: %d\n", ret);
542 return ret;
543 }
544
545 fsleep(MXC4005_RESET_TIME_US);
546
547 ret = regmap_write(map: data->regmap, MXC4005_REG_CONTROL, val: data->control);
548 if (ret) {
549 dev_err(data->dev, "failed to restore control register\n");
550 return ret;
551 }
552
553 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_MASK0, val: 0);
554 if (ret) {
555 dev_err(data->dev, "failed to restore interrupt 0 mask\n");
556 return ret;
557 }
558
559 ret = regmap_write(map: data->regmap, MXC4005_REG_INT_MASK1, val: data->int_mask1);
560 if (ret) {
561 dev_err(data->dev, "failed to restore interrupt 1 mask\n");
562 return ret;
563 }
564
565 return 0;
566}
567
568static DEFINE_SIMPLE_DEV_PM_OPS(mxc4005_pm_ops, mxc4005_suspend, mxc4005_resume);
569
570static const struct acpi_device_id mxc4005_acpi_match[] = {
571 {"MXC4005", 0},
572 {"MXC6655", 0},
573 {"MDA6655", 0},
574 { }
575};
576MODULE_DEVICE_TABLE(acpi, mxc4005_acpi_match);
577
578static const struct of_device_id mxc4005_of_match[] = {
579 { .compatible = "memsic,mxc4005", },
580 { .compatible = "memsic,mxc6655", },
581 { }
582};
583MODULE_DEVICE_TABLE(of, mxc4005_of_match);
584
585static const struct i2c_device_id mxc4005_id[] = {
586 { "mxc4005" },
587 { "mxc6655" },
588 { }
589};
590MODULE_DEVICE_TABLE(i2c, mxc4005_id);
591
592static struct i2c_driver mxc4005_driver = {
593 .driver = {
594 .name = MXC4005_DRV_NAME,
595 .acpi_match_table = mxc4005_acpi_match,
596 .of_match_table = mxc4005_of_match,
597 .pm = pm_sleep_ptr(&mxc4005_pm_ops),
598 },
599 .probe = mxc4005_probe,
600 .id_table = mxc4005_id,
601};
602
603module_i2c_driver(mxc4005_driver);
604
605MODULE_AUTHOR("Teodora Baluta <teodora.baluta@intel.com>");
606MODULE_LICENSE("GPL v2");
607MODULE_DESCRIPTION("MXC4005 3-axis accelerometer driver");
608

source code of linux/drivers/iio/accel/mxc4005.c