]> Git Repo - J-linux.git/blob - drivers/iio/light/veml6030.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / iio / light / veml6030.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * VEML6030, VMEL6035 and VEML7700 Ambient Light Sensors
4  *
5  * Copyright (c) 2019, Rishi Gupta <[email protected]>
6  *
7  * VEML6030:
8  * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf
9  * Appnote-84367: https://www.vishay.com/docs/84367/designingveml6030.pdf
10  *
11  * VEML6035:
12  * Datasheet: https://www.vishay.com/docs/84889/veml6035.pdf
13  * Appnote-84944: https://www.vishay.com/docs/84944/designingveml6035.pdf
14  *
15  * VEML7700:
16  * Datasheet: https://www.vishay.com/docs/84286/veml7700.pdf
17  * Appnote-84323: https://www.vishay.com/docs/84323/designingveml7700.pdf
18  */
19
20 #include <linux/bitfield.h>
21 #include <linux/module.h>
22 #include <linux/i2c.h>
23 #include <linux/err.h>
24 #include <linux/regmap.h>
25 #include <linux/interrupt.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/regulator/consumer.h>
28 #include <linux/iio/iio.h>
29 #include <linux/iio/sysfs.h>
30 #include <linux/iio/events.h>
31
32 /* Device registers */
33 #define VEML6030_REG_ALS_CONF   0x00
34 #define VEML6030_REG_ALS_WH     0x01
35 #define VEML6030_REG_ALS_WL     0x02
36 #define VEML6030_REG_ALS_PSM    0x03
37 #define VEML6030_REG_ALS_DATA   0x04
38 #define VEML6030_REG_WH_DATA    0x05
39 #define VEML6030_REG_ALS_INT    0x06
40
41 /* Bit masks for specific functionality */
42 #define VEML6030_ALS_IT       GENMASK(9, 6)
43 #define VEML6030_PSM          GENMASK(2, 1)
44 #define VEML6030_ALS_PERS     GENMASK(5, 4)
45 #define VEML6030_ALS_GAIN     GENMASK(12, 11)
46 #define VEML6030_PSM_EN       BIT(0)
47 #define VEML6030_INT_TH_LOW   BIT(15)
48 #define VEML6030_INT_TH_HIGH  BIT(14)
49 #define VEML6030_ALS_INT_EN   BIT(1)
50 #define VEML6030_ALS_SD       BIT(0)
51
52 #define VEML6035_GAIN_M       GENMASK(12, 10)
53 #define VEML6035_GAIN         BIT(10)
54 #define VEML6035_DG           BIT(11)
55 #define VEML6035_SENS         BIT(12)
56 #define VEML6035_INT_CHAN     BIT(3)
57 #define VEML6035_CHAN_EN      BIT(2)
58
59 struct veml603x_chip {
60         const char *name;
61         const int(*scale_vals)[][2];
62         const int num_scale_vals;
63         const struct iio_chan_spec *channels;
64         const int num_channels;
65         int (*hw_init)(struct iio_dev *indio_dev, struct device *dev);
66         int (*set_info)(struct iio_dev *indio_dev);
67         int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2);
68         int (*get_als_gain)(struct iio_dev *indio_dev, int *val, int *val2);
69 };
70
71 /*
72  * The resolution depends on both gain and integration time. The
73  * cur_resolution stores one of the resolution mentioned in the
74  * table during startup and gets updated whenever integration time
75  * or gain is changed.
76  *
77  * Table 'resolution and maximum detection range' in the appnotes
78  * is visualized as a 2D array. The cur_gain stores index of gain
79  * in this table (0-3 for VEML6030, 0-5 for VEML6035) while the
80  * cur_integration_time holds index of integration time (0-5).
81  */
82 struct veml6030_data {
83         struct i2c_client *client;
84         struct regmap *regmap;
85         int cur_resolution;
86         int cur_gain;
87         int cur_integration_time;
88         const struct veml603x_chip *chip;
89 };
90
91 static const int veml6030_it_times[][2] = {
92         { 0, 25000 },
93         { 0, 50000 },
94         { 0, 100000 },
95         { 0, 200000 },
96         { 0, 400000 },
97         { 0, 800000 },
98 };
99
100 /*
101  * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is
102  * ALS gain x (1/4), 0.5 is ALS gain x (1/2), 1.0 is ALS gain x 1,
103  * 2.0 is ALS gain x2, and 4.0 is ALS gain x 4.
104  */
105 static const int veml6030_scale_vals[][2] = {
106         { 0, 125000 },
107         { 0, 250000 },
108         { 1, 0 },
109         { 2, 0 },
110 };
111
112 static const int veml6035_scale_vals[][2] = {
113         { 0, 125000 },
114         { 0, 250000 },
115         { 0, 500000 },
116         { 1, 0 },
117         { 2, 0 },
118         { 4, 0 },
119 };
120
121 /*
122  * Persistence = 1/2/4/8 x integration time
123  * Minimum time for which light readings must stay above configured
124  * threshold to assert the interrupt.
125  */
126 static const char * const period_values[] = {
127                 "0.1 0.2 0.4 0.8",
128                 "0.2 0.4 0.8 1.6",
129                 "0.4 0.8 1.6 3.2",
130                 "0.8 1.6 3.2 6.4",
131                 "0.05 0.1 0.2 0.4",
132                 "0.025 0.050 0.1 0.2"
133 };
134
135 /*
136  * Return list of valid period values in seconds corresponding to
137  * the currently active integration time.
138  */
139 static ssize_t in_illuminance_period_available_show(struct device *dev,
140                                 struct device_attribute *attr, char *buf)
141 {
142         struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev));
143         int ret, reg, x;
144
145         ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
146         if (ret) {
147                 dev_err(&data->client->dev,
148                                 "can't read als conf register %d\n", ret);
149                 return ret;
150         }
151
152         ret = ((reg >> 6) & 0xF);
153         switch (ret) {
154         case 0:
155         case 1:
156         case 2:
157         case 3:
158                 x = ret;
159                 break;
160         case 8:
161                 x = 4;
162                 break;
163         case 12:
164                 x = 5;
165                 break;
166         default:
167                 return -EINVAL;
168         }
169
170         return sysfs_emit(buf, "%s\n", period_values[x]);
171 }
172
173 static IIO_DEVICE_ATTR_RO(in_illuminance_period_available, 0);
174
175 static struct attribute *veml6030_event_attributes[] = {
176         &iio_dev_attr_in_illuminance_period_available.dev_attr.attr,
177         NULL
178 };
179
180 static const struct attribute_group veml6030_event_attr_group = {
181         .attrs = veml6030_event_attributes,
182 };
183
184 static int veml6030_als_pwr_on(struct veml6030_data *data)
185 {
186         int ret;
187
188         ret = regmap_clear_bits(data->regmap, VEML6030_REG_ALS_CONF,
189                                 VEML6030_ALS_SD);
190         if (ret)
191                 return ret;
192
193         /* Wait 4 ms to let processor & oscillator start correctly */
194         fsleep(4000);
195
196         return 0;
197 }
198
199 static int veml6030_als_shut_down(struct veml6030_data *data)
200 {
201         return regmap_set_bits(data->regmap, VEML6030_REG_ALS_CONF,
202                                  VEML6030_ALS_SD);
203 }
204
205 static void veml6030_als_shut_down_action(void *data)
206 {
207         veml6030_als_shut_down(data);
208 }
209
210 static const struct iio_event_spec veml6030_event_spec[] = {
211         {
212                 .type = IIO_EV_TYPE_THRESH,
213                 .dir = IIO_EV_DIR_RISING,
214                 .mask_separate = BIT(IIO_EV_INFO_VALUE),
215         }, {
216                 .type = IIO_EV_TYPE_THRESH,
217                 .dir = IIO_EV_DIR_FALLING,
218                 .mask_separate = BIT(IIO_EV_INFO_VALUE),
219         }, {
220                 .type = IIO_EV_TYPE_THRESH,
221                 .dir = IIO_EV_DIR_EITHER,
222                 .mask_separate = BIT(IIO_EV_INFO_PERIOD) |
223                 BIT(IIO_EV_INFO_ENABLE),
224         },
225 };
226
227 /* Channel number */
228 enum veml6030_chan {
229         CH_ALS,
230         CH_WHITE,
231 };
232
233 static const struct iio_chan_spec veml6030_channels[] = {
234         {
235                 .type = IIO_LIGHT,
236                 .channel = CH_ALS,
237                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
238                                 BIT(IIO_CHAN_INFO_PROCESSED) |
239                                 BIT(IIO_CHAN_INFO_INT_TIME) |
240                                 BIT(IIO_CHAN_INFO_SCALE),
241                 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
242                                                      BIT(IIO_CHAN_INFO_SCALE),
243                 .event_spec = veml6030_event_spec,
244                 .num_event_specs = ARRAY_SIZE(veml6030_event_spec),
245         },
246         {
247                 .type = IIO_INTENSITY,
248                 .channel = CH_WHITE,
249                 .modified = 1,
250                 .channel2 = IIO_MOD_LIGHT_BOTH,
251                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
252                                 BIT(IIO_CHAN_INFO_INT_TIME) |
253                                 BIT(IIO_CHAN_INFO_SCALE),
254                 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
255                                                      BIT(IIO_CHAN_INFO_SCALE),
256         },
257 };
258
259 static const struct iio_chan_spec veml7700_channels[] = {
260         {
261                 .type = IIO_LIGHT,
262                 .channel = CH_ALS,
263                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
264                                 BIT(IIO_CHAN_INFO_PROCESSED) |
265                                 BIT(IIO_CHAN_INFO_INT_TIME) |
266                                 BIT(IIO_CHAN_INFO_SCALE),
267                 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
268                                                      BIT(IIO_CHAN_INFO_SCALE),
269         },
270         {
271                 .type = IIO_INTENSITY,
272                 .channel = CH_WHITE,
273                 .modified = 1,
274                 .channel2 = IIO_MOD_LIGHT_BOTH,
275                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
276                                 BIT(IIO_CHAN_INFO_INT_TIME) |
277                                 BIT(IIO_CHAN_INFO_SCALE),
278                 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
279                                                      BIT(IIO_CHAN_INFO_SCALE),
280         },
281 };
282
283 static const struct regmap_config veml6030_regmap_config = {
284         .name = "veml6030_regmap",
285         .reg_bits = 8,
286         .val_bits = 16,
287         .max_register = VEML6030_REG_ALS_INT,
288         .val_format_endian = REGMAP_ENDIAN_LITTLE,
289 };
290
291 static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
292                                                 int *val, int *val2)
293 {
294         int ret, reg;
295         struct veml6030_data *data = iio_priv(indio_dev);
296
297         ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
298         if (ret) {
299                 dev_err(&data->client->dev,
300                                 "can't read als conf register %d\n", ret);
301                 return ret;
302         }
303
304         switch ((reg >> 6) & 0xF) {
305         case 0:
306                 *val2 = 100000;
307                 break;
308         case 1:
309                 *val2 = 200000;
310                 break;
311         case 2:
312                 *val2 = 400000;
313                 break;
314         case 3:
315                 *val2 = 800000;
316                 break;
317         case 8:
318                 *val2 = 50000;
319                 break;
320         case 12:
321                 *val2 = 25000;
322                 break;
323         default:
324                 return -EINVAL;
325         }
326
327         *val = 0;
328         return IIO_VAL_INT_PLUS_MICRO;
329 }
330
331 static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
332                                                 int val, int val2)
333 {
334         int ret, new_int_time, int_idx;
335         struct veml6030_data *data = iio_priv(indio_dev);
336
337         if (val)
338                 return -EINVAL;
339
340         switch (val2) {
341         case 25000:
342                 new_int_time = 0x300;
343                 int_idx = 5;
344                 break;
345         case 50000:
346                 new_int_time = 0x200;
347                 int_idx = 4;
348                 break;
349         case 100000:
350                 new_int_time = 0x00;
351                 int_idx = 3;
352                 break;
353         case 200000:
354                 new_int_time = 0x40;
355                 int_idx = 2;
356                 break;
357         case 400000:
358                 new_int_time = 0x80;
359                 int_idx = 1;
360                 break;
361         case 800000:
362                 new_int_time = 0xC0;
363                 int_idx = 0;
364                 break;
365         default:
366                 return -EINVAL;
367         }
368
369         ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
370                                         VEML6030_ALS_IT, new_int_time);
371         if (ret) {
372                 dev_err(&data->client->dev,
373                                 "can't update als integration time %d\n", ret);
374                 return ret;
375         }
376
377         /*
378          * Cache current integration time and update resolution. For every
379          * increase in integration time to next level, resolution is halved
380          * and vice-versa.
381          */
382         if (data->cur_integration_time < int_idx)
383                 data->cur_resolution <<= int_idx - data->cur_integration_time;
384         else if (data->cur_integration_time > int_idx)
385                 data->cur_resolution >>= data->cur_integration_time - int_idx;
386
387         data->cur_integration_time = int_idx;
388
389         return ret;
390 }
391
392 static int veml6030_read_persistence(struct iio_dev *indio_dev,
393                                                 int *val, int *val2)
394 {
395         int ret, reg, period, x, y;
396         struct veml6030_data *data = iio_priv(indio_dev);
397
398         ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
399         if (ret < 0)
400                 return ret;
401
402         ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
403         if (ret) {
404                 dev_err(&data->client->dev,
405                                 "can't read als conf register %d\n", ret);
406         }
407
408         /* integration time multiplied by 1/2/4/8 */
409         period = y * (1 << ((reg >> 4) & 0x03));
410
411         *val = period / 1000000;
412         *val2 = period % 1000000;
413
414         return IIO_VAL_INT_PLUS_MICRO;
415 }
416
417 static int veml6030_write_persistence(struct iio_dev *indio_dev,
418                                                 int val, int val2)
419 {
420         int ret, period, x, y;
421         struct veml6030_data *data = iio_priv(indio_dev);
422
423         ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
424         if (ret < 0)
425                 return ret;
426
427         if (!val) {
428                 period = val2 / y;
429         } else {
430                 if ((val == 1) && (val2 == 600000))
431                         period = 1600000 / y;
432                 else if ((val == 3) && (val2 == 200000))
433                         period = 3200000 / y;
434                 else if ((val == 6) && (val2 == 400000))
435                         period = 6400000 / y;
436                 else
437                         period = -1;
438         }
439
440         if (period <= 0 || period > 8 || hweight8(period) != 1)
441                 return -EINVAL;
442
443         ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
444                                 VEML6030_ALS_PERS, (ffs(period) - 1) << 4);
445         if (ret)
446                 dev_err(&data->client->dev,
447                                 "can't set persistence value %d\n", ret);
448
449         return ret;
450 }
451
452 /*
453  * Cache currently set gain & update resolution. For every
454  * increase in the gain to next level, resolution is halved
455  * and vice-versa.
456  */
457 static void veml6030_update_gain_res(struct veml6030_data *data, int gain_idx)
458 {
459         if (data->cur_gain < gain_idx)
460                 data->cur_resolution <<= gain_idx - data->cur_gain;
461         else if (data->cur_gain > gain_idx)
462                 data->cur_resolution >>= data->cur_gain - gain_idx;
463
464         data->cur_gain = gain_idx;
465 }
466
467 static int veml6030_set_als_gain(struct iio_dev *indio_dev,
468                                                 int val, int val2)
469 {
470         int ret, new_gain, gain_idx;
471         struct veml6030_data *data = iio_priv(indio_dev);
472
473         if (val == 0 && val2 == 125000) {
474                 new_gain = 0x1000; /* 0x02 << 11 */
475                 gain_idx = 3;
476         } else if (val == 0 && val2 == 250000) {
477                 new_gain = 0x1800;
478                 gain_idx = 2;
479         } else if (val == 1 && val2 == 0) {
480                 new_gain = 0x00;
481                 gain_idx = 1;
482         } else if (val == 2 && val2 == 0) {
483                 new_gain = 0x800;
484                 gain_idx = 0;
485         } else {
486                 return -EINVAL;
487         }
488
489         ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
490                                         VEML6030_ALS_GAIN, new_gain);
491         if (ret) {
492                 dev_err(&data->client->dev,
493                                 "can't set als gain %d\n", ret);
494                 return ret;
495         }
496
497         veml6030_update_gain_res(data, gain_idx);
498
499         return 0;
500 }
501
502 static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
503 {
504         int ret, new_gain, gain_idx;
505         struct veml6030_data *data = iio_priv(indio_dev);
506
507         if (val == 0 && val2 == 125000) {
508                 new_gain = VEML6035_SENS;
509                 gain_idx = 5;
510         } else if (val == 0 && val2 == 250000) {
511                 new_gain = VEML6035_SENS | VEML6035_GAIN;
512                 gain_idx = 4;
513         } else if (val == 0 && val2 == 500000) {
514                 new_gain = VEML6035_SENS | VEML6035_GAIN |
515                         VEML6035_DG;
516                 gain_idx = 3;
517         } else if (val == 1 && val2 == 0) {
518                 new_gain = 0x0000;
519                 gain_idx = 2;
520         } else if (val == 2 && val2 == 0) {
521                 new_gain = VEML6035_GAIN;
522                 gain_idx = 1;
523         } else if (val == 4 && val2 == 0) {
524                 new_gain = VEML6035_GAIN | VEML6035_DG;
525                 gain_idx = 0;
526         } else {
527                 return -EINVAL;
528         }
529
530         ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
531                                  VEML6035_GAIN_M, new_gain);
532         if (ret) {
533                 dev_err(&data->client->dev, "can't set als gain %d\n", ret);
534                 return ret;
535         }
536
537         veml6030_update_gain_res(data, gain_idx);
538
539         return 0;
540 }
541
542 static int veml6030_get_als_gain(struct iio_dev *indio_dev,
543                                                 int *val, int *val2)
544 {
545         int ret, reg;
546         struct veml6030_data *data = iio_priv(indio_dev);
547
548         ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
549         if (ret) {
550                 dev_err(&data->client->dev,
551                                 "can't read als conf register %d\n", ret);
552                 return ret;
553         }
554
555         switch ((reg >> 11) & 0x03) {
556         case 0:
557                 *val = 1;
558                 *val2 = 0;
559                 break;
560         case 1:
561                 *val = 2;
562                 *val2 = 0;
563                 break;
564         case 2:
565                 *val = 0;
566                 *val2 = 125000;
567                 break;
568         case 3:
569                 *val = 0;
570                 *val2 = 250000;
571                 break;
572         default:
573                 return -EINVAL;
574         }
575
576         return IIO_VAL_INT_PLUS_MICRO;
577 }
578
579 static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2)
580 {
581         int ret, reg;
582         struct veml6030_data *data = iio_priv(indio_dev);
583
584         ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
585         if (ret) {
586                 dev_err(&data->client->dev,
587                         "can't read als conf register %d\n", ret);
588                 return ret;
589         }
590
591         switch (FIELD_GET(VEML6035_GAIN_M, reg)) {
592         case 0:
593                 *val = 1;
594                 *val2 = 0;
595                 break;
596         case 1:
597         case 2:
598                 *val = 2;
599                 *val2 = 0;
600                 break;
601         case 3:
602                 *val = 4;
603                 *val2 = 0;
604                 break;
605         case 4:
606                 *val = 0;
607                 *val2 = 125000;
608                 break;
609         case 5:
610         case 6:
611                 *val = 0;
612                 *val2 = 250000;
613                 break;
614         case 7:
615                 *val = 0;
616                 *val2 = 500000;
617                 break;
618         default:
619                 return -EINVAL;
620         }
621
622         return IIO_VAL_INT_PLUS_MICRO;
623 }
624
625 static int veml6030_read_thresh(struct iio_dev *indio_dev,
626                                                 int *val, int *val2, int dir)
627 {
628         int ret, reg;
629         struct veml6030_data *data = iio_priv(indio_dev);
630
631         if (dir == IIO_EV_DIR_RISING)
632                 ret = regmap_read(data->regmap, VEML6030_REG_ALS_WH, &reg);
633         else
634                 ret = regmap_read(data->regmap, VEML6030_REG_ALS_WL, &reg);
635         if (ret) {
636                 dev_err(&data->client->dev,
637                                 "can't read als threshold value %d\n", ret);
638                 return ret;
639         }
640
641         *val = reg & 0xffff;
642         return IIO_VAL_INT;
643 }
644
645 static int veml6030_write_thresh(struct iio_dev *indio_dev,
646                                                 int val, int val2, int dir)
647 {
648         int ret;
649         struct veml6030_data *data = iio_priv(indio_dev);
650
651         if (val > 0xFFFF || val < 0 || val2)
652                 return -EINVAL;
653
654         if (dir == IIO_EV_DIR_RISING) {
655                 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, val);
656                 if (ret)
657                         dev_err(&data->client->dev,
658                                         "can't set high threshold %d\n", ret);
659         } else {
660                 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, val);
661                 if (ret)
662                         dev_err(&data->client->dev,
663                                         "can't set low threshold %d\n", ret);
664         }
665
666         return ret;
667 }
668
669 /*
670  * Provide both raw as well as light reading in lux.
671  * light (in lux) = resolution * raw reading
672  */
673 static int veml6030_read_raw(struct iio_dev *indio_dev,
674                             struct iio_chan_spec const *chan, int *val,
675                             int *val2, long mask)
676 {
677         int ret, reg;
678         struct veml6030_data *data = iio_priv(indio_dev);
679         struct regmap *regmap = data->regmap;
680         struct device *dev = &data->client->dev;
681
682         switch (mask) {
683         case IIO_CHAN_INFO_RAW:
684         case IIO_CHAN_INFO_PROCESSED:
685                 switch (chan->type) {
686                 case IIO_LIGHT:
687                         ret = regmap_read(regmap, VEML6030_REG_ALS_DATA, &reg);
688                         if (ret < 0) {
689                                 dev_err(dev, "can't read als data %d\n", ret);
690                                 return ret;
691                         }
692                         if (mask == IIO_CHAN_INFO_PROCESSED) {
693                                 *val = (reg * data->cur_resolution) / 10000;
694                                 *val2 = (reg * data->cur_resolution) % 10000 * 100;
695                                 return IIO_VAL_INT_PLUS_MICRO;
696                         }
697                         *val = reg;
698                         return IIO_VAL_INT;
699                 case IIO_INTENSITY:
700                         ret = regmap_read(regmap, VEML6030_REG_WH_DATA, &reg);
701                         if (ret < 0) {
702                                 dev_err(dev, "can't read white data %d\n", ret);
703                                 return ret;
704                         }
705                         *val = reg;
706                         return IIO_VAL_INT;
707                 default:
708                         return -EINVAL;
709                 }
710         case IIO_CHAN_INFO_INT_TIME:
711                 return veml6030_get_intgrn_tm(indio_dev, val, val2);
712         case IIO_CHAN_INFO_SCALE:
713                 return data->chip->get_als_gain(indio_dev, val, val2);
714         default:
715                 return -EINVAL;
716         }
717 }
718
719 static int veml6030_read_avail(struct iio_dev *indio_dev,
720                                struct iio_chan_spec const *chan,
721                                const int **vals, int *type, int *length,
722                                long mask)
723 {
724         struct veml6030_data *data = iio_priv(indio_dev);
725
726         switch (mask) {
727         case IIO_CHAN_INFO_INT_TIME:
728                 *vals = (int *)&veml6030_it_times;
729                 *length = 2 * ARRAY_SIZE(veml6030_it_times);
730                 *type = IIO_VAL_INT_PLUS_MICRO;
731                 return IIO_AVAIL_LIST;
732         case IIO_CHAN_INFO_SCALE:
733                 *vals = (int *)*data->chip->scale_vals;
734                 *length = 2 * data->chip->num_scale_vals;
735                 *type = IIO_VAL_INT_PLUS_MICRO;
736                 return IIO_AVAIL_LIST;
737         }
738
739         return -EINVAL;
740 }
741
742 static int veml6030_write_raw(struct iio_dev *indio_dev,
743                                 struct iio_chan_spec const *chan,
744                                 int val, int val2, long mask)
745 {
746         struct veml6030_data *data = iio_priv(indio_dev);
747
748         switch (mask) {
749         case IIO_CHAN_INFO_INT_TIME:
750                 return veml6030_set_intgrn_tm(indio_dev, val, val2);
751         case IIO_CHAN_INFO_SCALE:
752                 return data->chip->set_als_gain(indio_dev, val, val2);
753         default:
754                 return -EINVAL;
755         }
756 }
757
758 static int veml6030_read_event_val(struct iio_dev *indio_dev,
759                 const struct iio_chan_spec *chan, enum iio_event_type type,
760                 enum iio_event_direction dir, enum iio_event_info info,
761                 int *val, int *val2)
762 {
763         switch (info) {
764         case IIO_EV_INFO_VALUE:
765                 switch (dir) {
766                 case IIO_EV_DIR_RISING:
767                 case IIO_EV_DIR_FALLING:
768                         return veml6030_read_thresh(indio_dev, val, val2, dir);
769                 default:
770                         return -EINVAL;
771                 }
772                 break;
773         case IIO_EV_INFO_PERIOD:
774                 return veml6030_read_persistence(indio_dev, val, val2);
775         default:
776                 return -EINVAL;
777         }
778 }
779
780 static int veml6030_write_event_val(struct iio_dev *indio_dev,
781                 const struct iio_chan_spec *chan, enum iio_event_type type,
782                 enum iio_event_direction dir, enum iio_event_info info,
783                 int val, int val2)
784 {
785         switch (info) {
786         case IIO_EV_INFO_VALUE:
787                 return veml6030_write_thresh(indio_dev, val, val2, dir);
788         case IIO_EV_INFO_PERIOD:
789                 return veml6030_write_persistence(indio_dev, val, val2);
790         default:
791                 return -EINVAL;
792         }
793 }
794
795 static int veml6030_read_interrupt_config(struct iio_dev *indio_dev,
796                 const struct iio_chan_spec *chan, enum iio_event_type type,
797                 enum iio_event_direction dir)
798 {
799         int ret, reg;
800         struct veml6030_data *data = iio_priv(indio_dev);
801
802         ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
803         if (ret) {
804                 dev_err(&data->client->dev,
805                                 "can't read als conf register %d\n", ret);
806                 return ret;
807         }
808
809         if (reg & VEML6030_ALS_INT_EN)
810                 return 1;
811         else
812                 return 0;
813 }
814
815 /*
816  * Sensor should not be measuring light when interrupt is configured.
817  * Therefore correct sequence to configure interrupt functionality is:
818  * shut down -> enable/disable interrupt -> power on
819  *
820  * state = 1 enables interrupt, state = 0 disables interrupt
821  */
822 static int veml6030_write_interrupt_config(struct iio_dev *indio_dev,
823                 const struct iio_chan_spec *chan, enum iio_event_type type,
824                 enum iio_event_direction dir, bool state)
825 {
826         int ret;
827         struct veml6030_data *data = iio_priv(indio_dev);
828
829         ret = veml6030_als_shut_down(data);
830         if (ret < 0) {
831                 dev_err(&data->client->dev,
832                         "can't disable als to configure interrupt %d\n", ret);
833                 return ret;
834         }
835
836         /* enable interrupt + power on */
837         ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
838                         VEML6030_ALS_INT_EN | VEML6030_ALS_SD, state << 1);
839         if (ret)
840                 dev_err(&data->client->dev,
841                         "can't enable interrupt & poweron als %d\n", ret);
842
843         return ret;
844 }
845
846 static const struct iio_info veml6030_info = {
847         .read_raw  = veml6030_read_raw,
848         .read_avail  = veml6030_read_avail,
849         .write_raw = veml6030_write_raw,
850         .read_event_value = veml6030_read_event_val,
851         .write_event_value      = veml6030_write_event_val,
852         .read_event_config = veml6030_read_interrupt_config,
853         .write_event_config     = veml6030_write_interrupt_config,
854         .event_attrs = &veml6030_event_attr_group,
855 };
856
857 static const struct iio_info veml6030_info_no_irq = {
858         .read_raw  = veml6030_read_raw,
859         .read_avail  = veml6030_read_avail,
860         .write_raw = veml6030_write_raw,
861 };
862
863 static irqreturn_t veml6030_event_handler(int irq, void *private)
864 {
865         int ret, reg, evtdir;
866         struct iio_dev *indio_dev = private;
867         struct veml6030_data *data = iio_priv(indio_dev);
868
869         ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &reg);
870         if (ret) {
871                 dev_err(&data->client->dev,
872                                 "can't read als interrupt register %d\n", ret);
873                 return IRQ_HANDLED;
874         }
875
876         /* Spurious interrupt handling */
877         if (!(reg & (VEML6030_INT_TH_HIGH | VEML6030_INT_TH_LOW)))
878                 return IRQ_NONE;
879
880         if (reg & VEML6030_INT_TH_HIGH)
881                 evtdir = IIO_EV_DIR_RISING;
882         else
883                 evtdir = IIO_EV_DIR_FALLING;
884
885         iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
886                                         0, IIO_EV_TYPE_THRESH, evtdir),
887                                         iio_get_time_ns(indio_dev));
888
889         return IRQ_HANDLED;
890 }
891
892 static int veml6030_set_info(struct iio_dev *indio_dev)
893 {
894         struct veml6030_data *data = iio_priv(indio_dev);
895         struct i2c_client *client = data->client;
896         int ret;
897
898         if (client->irq) {
899                 ret = devm_request_threaded_irq(&client->dev, client->irq,
900                                                 NULL, veml6030_event_handler,
901                                                 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
902                                                 indio_dev->name, indio_dev);
903                 if (ret < 0)
904                         return dev_err_probe(&client->dev, ret,
905                                              "irq %d request failed\n",
906                                              client->irq);
907
908                 indio_dev->info = &veml6030_info;
909         } else {
910                 indio_dev->info = &veml6030_info_no_irq;
911         }
912
913         return 0;
914 }
915
916 static int veml7700_set_info(struct iio_dev *indio_dev)
917 {
918         indio_dev->info = &veml6030_info_no_irq;
919
920         return 0;
921 }
922
923 /*
924  * Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2,
925  * persistence to 1 x integration time and the threshold
926  * interrupt disabled by default. First shutdown the sensor,
927  * update registers and then power on the sensor.
928  */
929 static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev)
930 {
931         int ret, val;
932         struct veml6030_data *data = iio_priv(indio_dev);
933
934         ret = veml6030_als_shut_down(data);
935         if (ret)
936                 return dev_err_probe(dev, ret, "can't shutdown als\n");
937
938         ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001);
939         if (ret)
940                 return dev_err_probe(dev, ret, "can't setup als configs\n");
941
942         ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_PSM,
943                                  VEML6030_PSM | VEML6030_PSM_EN, 0x03);
944         if (ret)
945                 return dev_err_probe(dev, ret, "can't setup default PSM\n");
946
947         ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, 0xFFFF);
948         if (ret)
949                 return dev_err_probe(dev, ret, "can't setup high threshold\n");
950
951         ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, 0x0000);
952         if (ret)
953                 return dev_err_probe(dev, ret, "can't setup low threshold\n");
954
955         ret = veml6030_als_pwr_on(data);
956         if (ret)
957                 return dev_err_probe(dev, ret, "can't poweron als\n");
958
959         ret = devm_add_action_or_reset(dev, veml6030_als_shut_down_action, data);
960         if (ret < 0)
961                 return ret;
962
963         /* Clear stale interrupt status bits if any during start */
964         ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
965         if (ret < 0)
966                 return dev_err_probe(dev, ret,
967                                      "can't clear als interrupt status\n");
968
969         /* Cache currently active measurement parameters */
970         data->cur_gain = 3;
971         data->cur_resolution = 5376;
972         data->cur_integration_time = 3;
973
974         return ret;
975 }
976
977 /*
978  * Set ALS gain to 1/8, integration time to 100 ms, ALS and WHITE
979  * channel enabled, ALS channel interrupt, PSM enabled,
980  * PSM_WAIT = 0.8 s, persistence to 1 x integration time and the
981  * threshold interrupt disabled by default. First shutdown the sensor,
982  * update registers and then power on the sensor.
983  */
984 static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev)
985 {
986         int ret, val;
987         struct veml6030_data *data = iio_priv(indio_dev);
988
989         ret = veml6030_als_shut_down(data);
990         if (ret)
991                 return dev_err_probe(dev, ret, "can't shutdown als\n");
992
993         ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF,
994                            VEML6035_SENS | VEML6035_CHAN_EN | VEML6030_ALS_SD);
995         if (ret)
996                 return dev_err_probe(dev, ret, "can't setup als configs\n");
997
998         ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_PSM,
999                                  VEML6030_PSM | VEML6030_PSM_EN, 0x03);
1000         if (ret)
1001                 return dev_err_probe(dev, ret, "can't setup default PSM\n");
1002
1003         ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, 0xFFFF);
1004         if (ret)
1005                 return dev_err_probe(dev, ret, "can't setup high threshold\n");
1006
1007         ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, 0x0000);
1008         if (ret)
1009                 return dev_err_probe(dev, ret, "can't setup low threshold\n");
1010
1011         ret = veml6030_als_pwr_on(data);
1012         if (ret)
1013                 return dev_err_probe(dev, ret, "can't poweron als\n");
1014
1015         ret = devm_add_action_or_reset(dev, veml6030_als_shut_down_action, data);
1016         if (ret < 0)
1017                 return ret;
1018
1019         /* Clear stale interrupt status bits if any during start */
1020         ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
1021         if (ret < 0)
1022                 return dev_err_probe(dev, ret,
1023                                      "can't clear als interrupt status\n");
1024
1025         /* Cache currently active measurement parameters */
1026         data->cur_gain = 5;
1027         data->cur_resolution = 1024;
1028         data->cur_integration_time = 3;
1029
1030         return 0;
1031 }
1032
1033 static int veml6030_probe(struct i2c_client *client)
1034 {
1035         int ret;
1036         struct veml6030_data *data;
1037         struct iio_dev *indio_dev;
1038         struct regmap *regmap;
1039
1040         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
1041                 return dev_err_probe(&client->dev, -EOPNOTSUPP,
1042                                      "i2c adapter doesn't support plain i2c\n");
1043
1044         regmap = devm_regmap_init_i2c(client, &veml6030_regmap_config);
1045         if (IS_ERR(regmap))
1046                 return dev_err_probe(&client->dev, PTR_ERR(regmap),
1047                                      "can't setup regmap\n");
1048
1049         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1050         if (!indio_dev)
1051                 return -ENOMEM;
1052
1053         data = iio_priv(indio_dev);
1054         i2c_set_clientdata(client, indio_dev);
1055         data->client = client;
1056         data->regmap = regmap;
1057
1058         ret = devm_regulator_get_enable(&client->dev, "vdd");
1059         if (ret)
1060                 return dev_err_probe(&client->dev, ret,
1061                                      "failed to enable regulator\n");
1062
1063         data->chip = i2c_get_match_data(client);
1064         if (!data->chip)
1065                 return -EINVAL;
1066
1067         indio_dev->name = data->chip->name;
1068         indio_dev->channels = data->chip->channels;
1069         indio_dev->num_channels = data->chip->num_channels;
1070         indio_dev->modes = INDIO_DIRECT_MODE;
1071
1072         ret = data->chip->set_info(indio_dev);
1073         if (ret < 0)
1074                 return ret;
1075
1076         ret = data->chip->hw_init(indio_dev, &client->dev);
1077         if (ret < 0)
1078                 return ret;
1079
1080         return devm_iio_device_register(&client->dev, indio_dev);
1081 }
1082
1083 static int veml6030_runtime_suspend(struct device *dev)
1084 {
1085         int ret;
1086         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1087         struct veml6030_data *data = iio_priv(indio_dev);
1088
1089         ret = veml6030_als_shut_down(data);
1090         if (ret < 0)
1091                 dev_err(&data->client->dev, "can't suspend als %d\n", ret);
1092
1093         return ret;
1094 }
1095
1096 static int veml6030_runtime_resume(struct device *dev)
1097 {
1098         int ret;
1099         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1100         struct veml6030_data *data = iio_priv(indio_dev);
1101
1102         ret = veml6030_als_pwr_on(data);
1103         if (ret < 0)
1104                 dev_err(&data->client->dev, "can't resume als %d\n", ret);
1105
1106         return ret;
1107 }
1108
1109 static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend,
1110                                  veml6030_runtime_resume, NULL);
1111
1112 static const struct veml603x_chip veml6030_chip = {
1113         .name = "veml6030",
1114         .scale_vals = &veml6030_scale_vals,
1115         .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
1116         .channels = veml6030_channels,
1117         .num_channels = ARRAY_SIZE(veml6030_channels),
1118         .hw_init = veml6030_hw_init,
1119         .set_info = veml6030_set_info,
1120         .set_als_gain = veml6030_set_als_gain,
1121         .get_als_gain = veml6030_get_als_gain,
1122 };
1123
1124 static const struct veml603x_chip veml6035_chip = {
1125         .name = "veml6035",
1126         .scale_vals = &veml6035_scale_vals,
1127         .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals),
1128         .channels = veml6030_channels,
1129         .num_channels = ARRAY_SIZE(veml6030_channels),
1130         .hw_init = veml6035_hw_init,
1131         .set_info = veml6030_set_info,
1132         .set_als_gain = veml6035_set_als_gain,
1133         .get_als_gain = veml6035_get_als_gain,
1134 };
1135
1136 static const struct veml603x_chip veml7700_chip = {
1137         .name = "veml7700",
1138         .scale_vals = &veml6030_scale_vals,
1139         .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
1140         .channels = veml7700_channels,
1141         .num_channels = ARRAY_SIZE(veml7700_channels),
1142         .hw_init = veml6030_hw_init,
1143         .set_info = veml7700_set_info,
1144         .set_als_gain = veml6030_set_als_gain,
1145         .get_als_gain = veml6030_get_als_gain,
1146 };
1147
1148 static const struct of_device_id veml6030_of_match[] = {
1149         {
1150                 .compatible = "vishay,veml6030",
1151                 .data = &veml6030_chip,
1152         },
1153         {
1154                 .compatible = "vishay,veml6035",
1155                 .data = &veml6035_chip,
1156         },
1157         {
1158                 .compatible = "vishay,veml7700",
1159                 .data = &veml7700_chip,
1160         },
1161         { }
1162 };
1163 MODULE_DEVICE_TABLE(of, veml6030_of_match);
1164
1165 static const struct i2c_device_id veml6030_id[] = {
1166         { "veml6030", (kernel_ulong_t)&veml6030_chip},
1167         { "veml6035", (kernel_ulong_t)&veml6035_chip},
1168         { "veml7700", (kernel_ulong_t)&veml7700_chip},
1169         { }
1170 };
1171 MODULE_DEVICE_TABLE(i2c, veml6030_id);
1172
1173 static struct i2c_driver veml6030_driver = {
1174         .driver = {
1175                 .name = "veml6030",
1176                 .of_match_table = veml6030_of_match,
1177                 .pm = pm_ptr(&veml6030_pm_ops),
1178         },
1179         .probe = veml6030_probe,
1180         .id_table = veml6030_id,
1181 };
1182 module_i2c_driver(veml6030_driver);
1183
1184 MODULE_AUTHOR("Rishi Gupta <[email protected]>");
1185 MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor");
1186 MODULE_LICENSE("GPL v2");
This page took 0.096173 seconds and 4 git commands to generate.