]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/iio/common/st_sensors/st_sensors_core.c
Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi...
[karo-tx-linux.git] / drivers / iio / common / st_sensors / st_sensors_core.c
1 /*
2  * STMicroelectronics sensors core library driver
3  *
4  * Copyright 2012-2013 STMicroelectronics Inc.
5  *
6  * Denis Ciocca <denis.ciocca@st.com>
7  *
8  * Licensed under the GPL-2.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/delay.h>
15 #include <linux/iio/iio.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/of.h>
18 #include <asm/unaligned.h>
19 #include <linux/iio/common/st_sensors.h>
20
21
22 #define ST_SENSORS_WAI_ADDRESS          0x0f
23
24 static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
25 {
26         return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8;
27 }
28
29 static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
30                                                 u8 reg_addr, u8 mask, u8 data)
31 {
32         int err;
33         u8 new_data;
34         struct st_sensor_data *sdata = iio_priv(indio_dev);
35
36         err = sdata->tf->read_byte(&sdata->tb, sdata->dev, reg_addr, &new_data);
37         if (err < 0)
38                 goto st_sensors_write_data_with_mask_error;
39
40         new_data = ((new_data & (~mask)) | ((data << __ffs(mask)) & mask));
41         err = sdata->tf->write_byte(&sdata->tb, sdata->dev, reg_addr, new_data);
42
43 st_sensors_write_data_with_mask_error:
44         return err;
45 }
46
47 static int st_sensors_match_odr(struct st_sensor_settings *sensor_settings,
48                         unsigned int odr, struct st_sensor_odr_avl *odr_out)
49 {
50         int i, ret = -EINVAL;
51
52         for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
53                 if (sensor_settings->odr.odr_avl[i].hz == 0)
54                         goto st_sensors_match_odr_error;
55
56                 if (sensor_settings->odr.odr_avl[i].hz == odr) {
57                         odr_out->hz = sensor_settings->odr.odr_avl[i].hz;
58                         odr_out->value = sensor_settings->odr.odr_avl[i].value;
59                         ret = 0;
60                         break;
61                 }
62         }
63
64 st_sensors_match_odr_error:
65         return ret;
66 }
67
68 int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
69 {
70         int err;
71         struct st_sensor_odr_avl odr_out = {0, 0};
72         struct st_sensor_data *sdata = iio_priv(indio_dev);
73
74         err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out);
75         if (err < 0)
76                 goto st_sensors_match_odr_error;
77
78         if ((sdata->sensor_settings->odr.addr ==
79                                         sdata->sensor_settings->pw.addr) &&
80                                 (sdata->sensor_settings->odr.mask ==
81                                         sdata->sensor_settings->pw.mask)) {
82                 if (sdata->enabled == true) {
83                         err = st_sensors_write_data_with_mask(indio_dev,
84                                 sdata->sensor_settings->odr.addr,
85                                 sdata->sensor_settings->odr.mask,
86                                 odr_out.value);
87                 } else {
88                         err = 0;
89                 }
90         } else {
91                 err = st_sensors_write_data_with_mask(indio_dev,
92                         sdata->sensor_settings->odr.addr,
93                         sdata->sensor_settings->odr.mask,
94                         odr_out.value);
95         }
96         if (err >= 0)
97                 sdata->odr = odr_out.hz;
98
99 st_sensors_match_odr_error:
100         return err;
101 }
102 EXPORT_SYMBOL(st_sensors_set_odr);
103
104 static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings,
105                                         unsigned int fs, int *index_fs_avl)
106 {
107         int i, ret = -EINVAL;
108
109         for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
110                 if (sensor_settings->fs.fs_avl[i].num == 0)
111                         goto st_sensors_match_odr_error;
112
113                 if (sensor_settings->fs.fs_avl[i].num == fs) {
114                         *index_fs_avl = i;
115                         ret = 0;
116                         break;
117                 }
118         }
119
120 st_sensors_match_odr_error:
121         return ret;
122 }
123
124 static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
125 {
126         int err, i = 0;
127         struct st_sensor_data *sdata = iio_priv(indio_dev);
128
129         if (sdata->sensor_settings->fs.addr == 0)
130                 return 0;
131
132         err = st_sensors_match_fs(sdata->sensor_settings, fs, &i);
133         if (err < 0)
134                 goto st_accel_set_fullscale_error;
135
136         err = st_sensors_write_data_with_mask(indio_dev,
137                                 sdata->sensor_settings->fs.addr,
138                                 sdata->sensor_settings->fs.mask,
139                                 sdata->sensor_settings->fs.fs_avl[i].value);
140         if (err < 0)
141                 goto st_accel_set_fullscale_error;
142
143         sdata->current_fullscale = (struct st_sensor_fullscale_avl *)
144                                         &sdata->sensor_settings->fs.fs_avl[i];
145         return err;
146
147 st_accel_set_fullscale_error:
148         dev_err(&indio_dev->dev, "failed to set new fullscale.\n");
149         return err;
150 }
151
152 int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable)
153 {
154         u8 tmp_value;
155         int err = -EINVAL;
156         bool found = false;
157         struct st_sensor_odr_avl odr_out = {0, 0};
158         struct st_sensor_data *sdata = iio_priv(indio_dev);
159
160         if (enable) {
161                 tmp_value = sdata->sensor_settings->pw.value_on;
162                 if ((sdata->sensor_settings->odr.addr ==
163                                         sdata->sensor_settings->pw.addr) &&
164                                 (sdata->sensor_settings->odr.mask ==
165                                         sdata->sensor_settings->pw.mask)) {
166                         err = st_sensors_match_odr(sdata->sensor_settings,
167                                                         sdata->odr, &odr_out);
168                         if (err < 0)
169                                 goto set_enable_error;
170                         tmp_value = odr_out.value;
171                         found = true;
172                 }
173                 err = st_sensors_write_data_with_mask(indio_dev,
174                                 sdata->sensor_settings->pw.addr,
175                                 sdata->sensor_settings->pw.mask, tmp_value);
176                 if (err < 0)
177                         goto set_enable_error;
178
179                 sdata->enabled = true;
180
181                 if (found)
182                         sdata->odr = odr_out.hz;
183         } else {
184                 err = st_sensors_write_data_with_mask(indio_dev,
185                                 sdata->sensor_settings->pw.addr,
186                                 sdata->sensor_settings->pw.mask,
187                                 sdata->sensor_settings->pw.value_off);
188                 if (err < 0)
189                         goto set_enable_error;
190
191                 sdata->enabled = false;
192         }
193
194 set_enable_error:
195         return err;
196 }
197 EXPORT_SYMBOL(st_sensors_set_enable);
198
199 int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
200 {
201         struct st_sensor_data *sdata = iio_priv(indio_dev);
202
203         return st_sensors_write_data_with_mask(indio_dev,
204                                 sdata->sensor_settings->enable_axis.addr,
205                                 sdata->sensor_settings->enable_axis.mask,
206                                 axis_enable);
207 }
208 EXPORT_SYMBOL(st_sensors_set_axis_enable);
209
210 void st_sensors_power_enable(struct iio_dev *indio_dev)
211 {
212         struct st_sensor_data *pdata = iio_priv(indio_dev);
213         int err;
214
215         /* Regulators not mandatory, but if requested we should enable them. */
216         pdata->vdd = devm_regulator_get_optional(indio_dev->dev.parent, "vdd");
217         if (!IS_ERR(pdata->vdd)) {
218                 err = regulator_enable(pdata->vdd);
219                 if (err != 0)
220                         dev_warn(&indio_dev->dev,
221                                  "Failed to enable specified Vdd supply\n");
222         }
223
224         pdata->vdd_io = devm_regulator_get_optional(indio_dev->dev.parent, "vddio");
225         if (!IS_ERR(pdata->vdd_io)) {
226                 err = regulator_enable(pdata->vdd_io);
227                 if (err != 0)
228                         dev_warn(&indio_dev->dev,
229                                  "Failed to enable specified Vdd_IO supply\n");
230         }
231 }
232 EXPORT_SYMBOL(st_sensors_power_enable);
233
234 void st_sensors_power_disable(struct iio_dev *indio_dev)
235 {
236         struct st_sensor_data *pdata = iio_priv(indio_dev);
237
238         if (!IS_ERR(pdata->vdd))
239                 regulator_disable(pdata->vdd);
240
241         if (!IS_ERR(pdata->vdd_io))
242                 regulator_disable(pdata->vdd_io);
243 }
244 EXPORT_SYMBOL(st_sensors_power_disable);
245
246 static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
247                                         struct st_sensors_platform_data *pdata)
248 {
249         struct st_sensor_data *sdata = iio_priv(indio_dev);
250
251         /* Sensor does not support interrupts */
252         if (sdata->sensor_settings->drdy_irq.addr == 0) {
253                 if (pdata->drdy_int_pin)
254                         dev_info(&indio_dev->dev,
255                                  "DRDY on pin INT%d specified, but sensor "
256                                  "does not support interrupts\n",
257                                  pdata->drdy_int_pin);
258                 return 0;
259         }
260
261         switch (pdata->drdy_int_pin) {
262         case 1:
263                 if (sdata->sensor_settings->drdy_irq.mask_int1 == 0) {
264                         dev_err(&indio_dev->dev,
265                                         "DRDY on INT1 not available.\n");
266                         return -EINVAL;
267                 }
268                 sdata->drdy_int_pin = 1;
269                 break;
270         case 2:
271                 if (sdata->sensor_settings->drdy_irq.mask_int2 == 0) {
272                         dev_err(&indio_dev->dev,
273                                         "DRDY on INT2 not available.\n");
274                         return -EINVAL;
275                 }
276                 sdata->drdy_int_pin = 2;
277                 break;
278         default:
279                 dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
280                 return -EINVAL;
281         }
282
283         return 0;
284 }
285
286 #ifdef CONFIG_OF
287 static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
288                 struct st_sensors_platform_data *defdata)
289 {
290         struct st_sensors_platform_data *pdata;
291         struct device_node *np = dev->of_node;
292         u32 val;
293
294         if (!np)
295                 return NULL;
296
297         pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
298         if (!of_property_read_u32(np, "st,drdy-int-pin", &val) && (val <= 2))
299                 pdata->drdy_int_pin = (u8) val;
300         else
301                 pdata->drdy_int_pin = defdata ? defdata->drdy_int_pin : 0;
302
303         return pdata;
304 }
305 #else
306 static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
307                 struct st_sensors_platform_data *defdata)
308 {
309         return NULL;
310 }
311 #endif
312
313 int st_sensors_init_sensor(struct iio_dev *indio_dev,
314                                         struct st_sensors_platform_data *pdata)
315 {
316         struct st_sensor_data *sdata = iio_priv(indio_dev);
317         struct st_sensors_platform_data *of_pdata;
318         int err = 0;
319
320         /* If OF/DT pdata exists, it will take precedence of anything else */
321         of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata);
322         if (of_pdata)
323                 pdata = of_pdata;
324
325         if (pdata) {
326                 err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
327                 if (err < 0)
328                         return err;
329         }
330
331         err = st_sensors_set_enable(indio_dev, false);
332         if (err < 0)
333                 return err;
334
335         if (sdata->current_fullscale) {
336                 err = st_sensors_set_fullscale(indio_dev,
337                                                 sdata->current_fullscale->num);
338                 if (err < 0)
339                         return err;
340         } else
341                 dev_info(&indio_dev->dev, "Full-scale not possible\n");
342
343         err = st_sensors_set_odr(indio_dev, sdata->odr);
344         if (err < 0)
345                 return err;
346
347         /* set BDU */
348         if (sdata->sensor_settings->bdu.addr) {
349                 err = st_sensors_write_data_with_mask(indio_dev,
350                                         sdata->sensor_settings->bdu.addr,
351                                         sdata->sensor_settings->bdu.mask, true);
352                 if (err < 0)
353                         return err;
354         }
355
356         err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
357
358         return err;
359 }
360 EXPORT_SYMBOL(st_sensors_init_sensor);
361
362 int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
363 {
364         int err;
365         u8 drdy_mask;
366         struct st_sensor_data *sdata = iio_priv(indio_dev);
367
368         if (!sdata->sensor_settings->drdy_irq.addr)
369                 return 0;
370
371         /* Enable/Disable the interrupt generator 1. */
372         if (sdata->sensor_settings->drdy_irq.ig1.en_addr > 0) {
373                 err = st_sensors_write_data_with_mask(indio_dev,
374                                 sdata->sensor_settings->drdy_irq.ig1.en_addr,
375                                 sdata->sensor_settings->drdy_irq.ig1.en_mask,
376                                 (int)enable);
377                 if (err < 0)
378                         goto st_accel_set_dataready_irq_error;
379         }
380
381         if (sdata->drdy_int_pin == 1)
382                 drdy_mask = sdata->sensor_settings->drdy_irq.mask_int1;
383         else
384                 drdy_mask = sdata->sensor_settings->drdy_irq.mask_int2;
385
386         /* Enable/Disable the interrupt generator for data ready. */
387         err = st_sensors_write_data_with_mask(indio_dev,
388                                         sdata->sensor_settings->drdy_irq.addr,
389                                         drdy_mask, (int)enable);
390
391 st_accel_set_dataready_irq_error:
392         return err;
393 }
394 EXPORT_SYMBOL(st_sensors_set_dataready_irq);
395
396 int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale)
397 {
398         int err = -EINVAL, i;
399         struct st_sensor_data *sdata = iio_priv(indio_dev);
400
401         for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
402                 if ((sdata->sensor_settings->fs.fs_avl[i].gain == scale) &&
403                                 (sdata->sensor_settings->fs.fs_avl[i].gain != 0)) {
404                         err = 0;
405                         break;
406                 }
407         }
408         if (err < 0)
409                 goto st_sensors_match_scale_error;
410
411         err = st_sensors_set_fullscale(indio_dev,
412                                 sdata->sensor_settings->fs.fs_avl[i].num);
413
414 st_sensors_match_scale_error:
415         return err;
416 }
417 EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain);
418
419 static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
420                                 struct iio_chan_spec const *ch, int *data)
421 {
422         int err;
423         u8 *outdata;
424         struct st_sensor_data *sdata = iio_priv(indio_dev);
425         unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;
426
427         outdata = kmalloc(byte_for_channel, GFP_KERNEL);
428         if (!outdata)
429                 return -ENOMEM;
430
431         err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
432                                 ch->address, byte_for_channel,
433                                 outdata, sdata->multiread_bit);
434         if (err < 0)
435                 goto st_sensors_free_memory;
436
437         if (byte_for_channel == 1)
438                 *data = (s8)*outdata;
439         else if (byte_for_channel == 2)
440                 *data = (s16)get_unaligned_le16(outdata);
441         else if (byte_for_channel == 3)
442                 *data = (s32)st_sensors_get_unaligned_le24(outdata);
443
444 st_sensors_free_memory:
445         kfree(outdata);
446
447         return err;
448 }
449
450 int st_sensors_read_info_raw(struct iio_dev *indio_dev,
451                                 struct iio_chan_spec const *ch, int *val)
452 {
453         int err;
454         struct st_sensor_data *sdata = iio_priv(indio_dev);
455
456         mutex_lock(&indio_dev->mlock);
457         if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
458                 err = -EBUSY;
459                 goto out;
460         } else {
461                 err = st_sensors_set_enable(indio_dev, true);
462                 if (err < 0)
463                         goto out;
464
465                 msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr);
466                 err = st_sensors_read_axis_data(indio_dev, ch, val);
467                 if (err < 0)
468                         goto out;
469
470                 *val = *val >> ch->scan_type.shift;
471
472                 err = st_sensors_set_enable(indio_dev, false);
473         }
474 out:
475         mutex_unlock(&indio_dev->mlock);
476
477         return err;
478 }
479 EXPORT_SYMBOL(st_sensors_read_info_raw);
480
481 int st_sensors_check_device_support(struct iio_dev *indio_dev,
482                         int num_sensors_list,
483                         const struct st_sensor_settings *sensor_settings)
484 {
485         int i, n, err;
486         u8 wai;
487         struct st_sensor_data *sdata = iio_priv(indio_dev);
488
489         for (i = 0; i < num_sensors_list; i++) {
490                 for (n = 0; n < ST_SENSORS_MAX_4WAI; n++) {
491                         if (strcmp(indio_dev->name,
492                                 sensor_settings[i].sensors_supported[n]) == 0) {
493                                 break;
494                         }
495                 }
496                 if (n < ST_SENSORS_MAX_4WAI)
497                         break;
498         }
499         if (i == num_sensors_list) {
500                 dev_err(&indio_dev->dev, "device name %s not recognized.\n",
501                                                         indio_dev->name);
502                 return -ENODEV;
503         }
504
505         err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
506                                         sensor_settings[i].wai_addr, &wai);
507         if (err < 0) {
508                 dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
509                 return err;
510         }
511
512         if (sensor_settings[i].wai != wai) {
513                 dev_err(&indio_dev->dev, "%s: WhoAmI mismatch (0x%x).\n",
514                                                 indio_dev->name, wai);
515                 return -EINVAL;
516         }
517
518         sdata->sensor_settings =
519                         (struct st_sensor_settings *)&sensor_settings[i];
520
521         return i;
522 }
523 EXPORT_SYMBOL(st_sensors_check_device_support);
524
525 ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
526                                 struct device_attribute *attr, char *buf)
527 {
528         int i, len = 0;
529         struct iio_dev *indio_dev = dev_get_drvdata(dev);
530         struct st_sensor_data *sdata = iio_priv(indio_dev);
531
532         mutex_lock(&indio_dev->mlock);
533         for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
534                 if (sdata->sensor_settings->odr.odr_avl[i].hz == 0)
535                         break;
536
537                 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
538                                 sdata->sensor_settings->odr.odr_avl[i].hz);
539         }
540         mutex_unlock(&indio_dev->mlock);
541         buf[len - 1] = '\n';
542
543         return len;
544 }
545 EXPORT_SYMBOL(st_sensors_sysfs_sampling_frequency_avail);
546
547 ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
548                                 struct device_attribute *attr, char *buf)
549 {
550         int i, len = 0;
551         struct iio_dev *indio_dev = dev_get_drvdata(dev);
552         struct st_sensor_data *sdata = iio_priv(indio_dev);
553
554         mutex_lock(&indio_dev->mlock);
555         for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
556                 if (sdata->sensor_settings->fs.fs_avl[i].num == 0)
557                         break;
558
559                 len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
560                                 sdata->sensor_settings->fs.fs_avl[i].gain);
561         }
562         mutex_unlock(&indio_dev->mlock);
563         buf[len - 1] = '\n';
564
565         return len;
566 }
567 EXPORT_SYMBOL(st_sensors_sysfs_scale_avail);
568
569 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
570 MODULE_DESCRIPTION("STMicroelectronics ST-sensors core");
571 MODULE_LICENSE("GPL v2");