]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/iio/accel/mxc4005.c
Linux 5.6-rc7
[linux.git] / drivers / iio / accel / mxc4005.c
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/module.h>
9 #include <linux/i2c.h>
10 #include <linux/iio/iio.h>
11 #include <linux/acpi.h>
12 #include <linux/regmap.h>
13 #include <linux/iio/sysfs.h>
14 #include <linux/iio/trigger.h>
15 #include <linux/iio/buffer.h>
16 #include <linux/iio/triggered_buffer.h>
17 #include <linux/iio/trigger_consumer.h>
18
19 #define MXC4005_DRV_NAME                "mxc4005"
20 #define MXC4005_IRQ_NAME                "mxc4005_event"
21 #define MXC4005_REGMAP_NAME             "mxc4005_regmap"
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_MASK1           0x0B
31 #define MXC4005_REG_INT_MASK1_BIT_DRDYE 0x01
32
33 #define MXC4005_REG_INT_CLR1            0x01
34 #define MXC4005_REG_INT_CLR1_BIT_DRDYC  0x01
35
36 #define MXC4005_REG_CONTROL             0x0D
37 #define MXC4005_REG_CONTROL_MASK_FSR    GENMASK(6, 5)
38 #define MXC4005_CONTROL_FSR_SHIFT       5
39
40 #define MXC4005_REG_DEVICE_ID           0x0E
41
42 enum mxc4005_axis {
43         AXIS_X,
44         AXIS_Y,
45         AXIS_Z,
46 };
47
48 enum mxc4005_range {
49         MXC4005_RANGE_2G,
50         MXC4005_RANGE_4G,
51         MXC4005_RANGE_8G,
52 };
53
54 struct mxc4005_data {
55         struct device *dev;
56         struct mutex mutex;
57         struct regmap *regmap;
58         struct iio_trigger *dready_trig;
59         __be16 buffer[8];
60         bool trigger_enabled;
61 };
62
63 /*
64  * MXC4005 can operate in the following ranges:
65  * +/- 2G, 4G, 8G (the default +/-2G)
66  *
67  * (2 + 2) * 9.81 / (2^12 - 1) = 0.009582
68  * (4 + 4) * 9.81 / (2^12 - 1) = 0.019164
69  * (8 + 8) * 9.81 / (2^12 - 1) = 0.038329
70  */
71 static const struct {
72         u8 range;
73         int scale;
74 } mxc4005_scale_table[] = {
75         {MXC4005_RANGE_2G, 9582},
76         {MXC4005_RANGE_4G, 19164},
77         {MXC4005_RANGE_8G, 38329},
78 };
79
80
81 static IIO_CONST_ATTR(in_accel_scale_available, "0.009582 0.019164 0.038329");
82
83 static struct attribute *mxc4005_attributes[] = {
84         &iio_const_attr_in_accel_scale_available.dev_attr.attr,
85         NULL,
86 };
87
88 static const struct attribute_group mxc4005_attrs_group = {
89         .attrs = mxc4005_attributes,
90 };
91
92 static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
93 {
94         switch (reg) {
95         case MXC4005_REG_XOUT_UPPER:
96         case MXC4005_REG_XOUT_LOWER:
97         case MXC4005_REG_YOUT_UPPER:
98         case MXC4005_REG_YOUT_LOWER:
99         case MXC4005_REG_ZOUT_UPPER:
100         case MXC4005_REG_ZOUT_LOWER:
101         case MXC4005_REG_DEVICE_ID:
102         case MXC4005_REG_CONTROL:
103                 return true;
104         default:
105                 return false;
106         }
107 }
108
109 static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
110 {
111         switch (reg) {
112         case MXC4005_REG_INT_CLR1:
113         case MXC4005_REG_INT_MASK1:
114         case MXC4005_REG_CONTROL:
115                 return true;
116         default:
117                 return false;
118         }
119 }
120
121 static const struct regmap_config mxc4005_regmap_config = {
122         .name = MXC4005_REGMAP_NAME,
123
124         .reg_bits = 8,
125         .val_bits = 8,
126
127         .max_register = MXC4005_REG_DEVICE_ID,
128
129         .readable_reg = mxc4005_is_readable_reg,
130         .writeable_reg = mxc4005_is_writeable_reg,
131 };
132
133 static int mxc4005_read_xyz(struct mxc4005_data *data)
134 {
135         int ret;
136
137         ret = regmap_bulk_read(data->regmap, MXC4005_REG_XOUT_UPPER,
138                                (u8 *) data->buffer, sizeof(data->buffer));
139         if (ret < 0) {
140                 dev_err(data->dev, "failed to read axes\n");
141                 return ret;
142         }
143
144         return 0;
145 }
146
147 static int mxc4005_read_axis(struct mxc4005_data *data,
148                              unsigned int addr)
149 {
150         __be16 reg;
151         int ret;
152
153         ret = regmap_bulk_read(data->regmap, addr, (u8 *) &reg, sizeof(reg));
154         if (ret < 0) {
155                 dev_err(data->dev, "failed to read reg %02x\n", addr);
156                 return ret;
157         }
158
159         return be16_to_cpu(reg);
160 }
161
162 static int mxc4005_read_scale(struct mxc4005_data *data)
163 {
164         unsigned int reg;
165         int ret;
166         int i;
167
168         ret = regmap_read(data->regmap, MXC4005_REG_CONTROL, &reg);
169         if (ret < 0) {
170                 dev_err(data->dev, "failed to read reg_control\n");
171                 return ret;
172         }
173
174         i = reg >> MXC4005_CONTROL_FSR_SHIFT;
175
176         if (i < 0 || i >= ARRAY_SIZE(mxc4005_scale_table))
177                 return -EINVAL;
178
179         return mxc4005_scale_table[i].scale;
180 }
181
182 static int mxc4005_set_scale(struct mxc4005_data *data, int val)
183 {
184         unsigned int reg;
185         int i;
186         int ret;
187
188         for (i = 0; i < ARRAY_SIZE(mxc4005_scale_table); i++) {
189                 if (mxc4005_scale_table[i].scale == val) {
190                         reg = i << MXC4005_CONTROL_FSR_SHIFT;
191                         ret = regmap_update_bits(data->regmap,
192                                                  MXC4005_REG_CONTROL,
193                                                  MXC4005_REG_CONTROL_MASK_FSR,
194                                                  reg);
195                         if (ret < 0)
196                                 dev_err(data->dev,
197                                         "failed to write reg_control\n");
198                         return ret;
199                 }
200         }
201
202         return -EINVAL;
203 }
204
205 static int mxc4005_read_raw(struct iio_dev *indio_dev,
206                             struct iio_chan_spec const *chan,
207                             int *val, int *val2, long mask)
208 {
209         struct mxc4005_data *data = iio_priv(indio_dev);
210         int ret;
211
212         switch (mask) {
213         case IIO_CHAN_INFO_RAW:
214                 switch (chan->type) {
215                 case IIO_ACCEL:
216                         if (iio_buffer_enabled(indio_dev))
217                                 return -EBUSY;
218
219                         ret = mxc4005_read_axis(data, chan->address);
220                         if (ret < 0)
221                                 return ret;
222                         *val = sign_extend32(ret >> chan->scan_type.shift,
223                                              chan->scan_type.realbits - 1);
224                         return IIO_VAL_INT;
225                 default:
226                         return -EINVAL;
227                 }
228         case IIO_CHAN_INFO_SCALE:
229                 ret = mxc4005_read_scale(data);
230                 if (ret < 0)
231                         return ret;
232
233                 *val = 0;
234                 *val2 = ret;
235                 return IIO_VAL_INT_PLUS_MICRO;
236         default:
237                 return -EINVAL;
238         }
239 }
240
241 static int mxc4005_write_raw(struct iio_dev *indio_dev,
242                              struct iio_chan_spec const *chan,
243                              int val, int val2, long mask)
244 {
245         struct mxc4005_data *data = iio_priv(indio_dev);
246
247         switch (mask) {
248         case IIO_CHAN_INFO_SCALE:
249                 if (val != 0)
250                         return -EINVAL;
251
252                 return mxc4005_set_scale(data, val2);
253         default:
254                 return -EINVAL;
255         }
256 }
257
258 static const struct iio_info mxc4005_info = {
259         .read_raw       = mxc4005_read_raw,
260         .write_raw      = mxc4005_write_raw,
261         .attrs          = &mxc4005_attrs_group,
262 };
263
264 static const unsigned long mxc4005_scan_masks[] = {
265         BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
266         0
267 };
268
269 #define MXC4005_CHANNEL(_axis, _addr) {                         \
270         .type = IIO_ACCEL,                                      \
271         .modified = 1,                                          \
272         .channel2 = IIO_MOD_##_axis,                            \
273         .address = _addr,                                       \
274         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
275         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
276         .scan_index = AXIS_##_axis,                             \
277         .scan_type = {                                          \
278                 .sign = 's',                                    \
279                 .realbits = 12,                                 \
280                 .storagebits = 16,                              \
281                 .shift = 4,                                     \
282                 .endianness = IIO_BE,                           \
283         },                                                      \
284 }
285
286 static const struct iio_chan_spec mxc4005_channels[] = {
287         MXC4005_CHANNEL(X, MXC4005_REG_XOUT_UPPER),
288         MXC4005_CHANNEL(Y, MXC4005_REG_YOUT_UPPER),
289         MXC4005_CHANNEL(Z, MXC4005_REG_ZOUT_UPPER),
290         IIO_CHAN_SOFT_TIMESTAMP(3),
291 };
292
293 static irqreturn_t mxc4005_trigger_handler(int irq, void *private)
294 {
295         struct iio_poll_func *pf = private;
296         struct iio_dev *indio_dev = pf->indio_dev;
297         struct mxc4005_data *data = iio_priv(indio_dev);
298         int ret;
299
300         ret = mxc4005_read_xyz(data);
301         if (ret < 0)
302                 goto err;
303
304         iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
305                                            pf->timestamp);
306
307 err:
308         iio_trigger_notify_done(indio_dev->trig);
309
310         return IRQ_HANDLED;
311 }
312
313 static int mxc4005_clr_intr(struct mxc4005_data *data)
314 {
315         int ret;
316
317         /* clear interrupt */
318         ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
319                            MXC4005_REG_INT_CLR1_BIT_DRDYC);
320         if (ret < 0) {
321                 dev_err(data->dev, "failed to write to reg_int_clr1\n");
322                 return ret;
323         }
324
325         return 0;
326 }
327
328 static int mxc4005_set_trigger_state(struct iio_trigger *trig,
329                                      bool state)
330 {
331         struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
332         struct mxc4005_data *data = iio_priv(indio_dev);
333         int ret;
334
335         mutex_lock(&data->mutex);
336         if (state) {
337                 ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
338                                    MXC4005_REG_INT_MASK1_BIT_DRDYE);
339         } else {
340                 ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
341                                    ~MXC4005_REG_INT_MASK1_BIT_DRDYE);
342         }
343
344         if (ret < 0) {
345                 mutex_unlock(&data->mutex);
346                 dev_err(data->dev, "failed to update reg_int_mask1");
347                 return ret;
348         }
349
350         data->trigger_enabled = state;
351         mutex_unlock(&data->mutex);
352
353         return 0;
354 }
355
356 static int mxc4005_trigger_try_reen(struct iio_trigger *trig)
357 {
358         struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
359         struct mxc4005_data *data = iio_priv(indio_dev);
360
361         if (!data->dready_trig)
362                 return 0;
363
364         return mxc4005_clr_intr(data);
365 }
366
367 static const struct iio_trigger_ops mxc4005_trigger_ops = {
368         .set_trigger_state = mxc4005_set_trigger_state,
369         .try_reenable = mxc4005_trigger_try_reen,
370 };
371
372 static int mxc4005_chip_init(struct mxc4005_data *data)
373 {
374         int ret;
375         unsigned int reg;
376
377         ret = regmap_read(data->regmap, MXC4005_REG_DEVICE_ID, &reg);
378         if (ret < 0) {
379                 dev_err(data->dev, "failed to read chip id\n");
380                 return ret;
381         }
382
383         dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg);
384
385         return 0;
386 }
387
388 static int mxc4005_probe(struct i2c_client *client,
389                          const struct i2c_device_id *id)
390 {
391         struct mxc4005_data *data;
392         struct iio_dev *indio_dev;
393         struct regmap *regmap;
394         int ret;
395
396         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
397         if (!indio_dev)
398                 return -ENOMEM;
399
400         regmap = devm_regmap_init_i2c(client, &mxc4005_regmap_config);
401         if (IS_ERR(regmap)) {
402                 dev_err(&client->dev, "failed to initialize regmap\n");
403                 return PTR_ERR(regmap);
404         }
405
406         data = iio_priv(indio_dev);
407         i2c_set_clientdata(client, indio_dev);
408         data->dev = &client->dev;
409         data->regmap = regmap;
410
411         ret = mxc4005_chip_init(data);
412         if (ret < 0) {
413                 dev_err(&client->dev, "failed to initialize chip\n");
414                 return ret;
415         }
416
417         mutex_init(&data->mutex);
418
419         indio_dev->dev.parent = &client->dev;
420         indio_dev->channels = mxc4005_channels;
421         indio_dev->num_channels = ARRAY_SIZE(mxc4005_channels);
422         indio_dev->available_scan_masks = mxc4005_scan_masks;
423         indio_dev->name = MXC4005_DRV_NAME;
424         indio_dev->modes = INDIO_DIRECT_MODE;
425         indio_dev->info = &mxc4005_info;
426
427         ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
428                                          iio_pollfunc_store_time,
429                                          mxc4005_trigger_handler,
430                                          NULL);
431         if (ret < 0) {
432                 dev_err(&client->dev,
433                         "failed to setup iio triggered buffer\n");
434                 return ret;
435         }
436
437         if (client->irq > 0) {
438                 data->dready_trig = devm_iio_trigger_alloc(&client->dev,
439                                                            "%s-dev%d",
440                                                            indio_dev->name,
441                                                            indio_dev->id);
442                 if (!data->dready_trig)
443                         return -ENOMEM;
444
445                 ret = devm_request_threaded_irq(&client->dev, client->irq,
446                                                 iio_trigger_generic_data_rdy_poll,
447                                                 NULL,
448                                                 IRQF_TRIGGER_FALLING |
449                                                 IRQF_ONESHOT,
450                                                 MXC4005_IRQ_NAME,
451                                                 data->dready_trig);
452                 if (ret) {
453                         dev_err(&client->dev,
454                                 "failed to init threaded irq\n");
455                         return ret;
456                 }
457
458                 data->dready_trig->dev.parent = &client->dev;
459                 data->dready_trig->ops = &mxc4005_trigger_ops;
460                 iio_trigger_set_drvdata(data->dready_trig, indio_dev);
461                 indio_dev->trig = data->dready_trig;
462                 iio_trigger_get(indio_dev->trig);
463                 ret = devm_iio_trigger_register(&client->dev,
464                                                 data->dready_trig);
465                 if (ret) {
466                         dev_err(&client->dev,
467                                 "failed to register trigger\n");
468                         return ret;
469                 }
470         }
471
472         return devm_iio_device_register(&client->dev, indio_dev);
473 }
474
475 static const struct acpi_device_id mxc4005_acpi_match[] = {
476         {"MXC4005",     0},
477         { },
478 };
479 MODULE_DEVICE_TABLE(acpi, mxc4005_acpi_match);
480
481 static const struct i2c_device_id mxc4005_id[] = {
482         {"mxc4005",     0},
483         { },
484 };
485 MODULE_DEVICE_TABLE(i2c, mxc4005_id);
486
487 static struct i2c_driver mxc4005_driver = {
488         .driver = {
489                 .name = MXC4005_DRV_NAME,
490                 .acpi_match_table = ACPI_PTR(mxc4005_acpi_match),
491         },
492         .probe          = mxc4005_probe,
493         .id_table       = mxc4005_id,
494 };
495
496 module_i2c_driver(mxc4005_driver);
497
498 MODULE_AUTHOR("Teodora Baluta <teodora.baluta@intel.com>");
499 MODULE_LICENSE("GPL v2");
500 MODULE_DESCRIPTION("MXC4005 3-axis accelerometer driver");