]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/iio/light/lm3533-als.c
Merge branch 'for-4.8/core' of git://git.kernel.dk/linux-block
[karo-tx-linux.git] / drivers / iio / light / lm3533-als.c
1 /*
2  * lm3533-als.c -- LM3533 Ambient Light Sensor driver
3  *
4  * Copyright (C) 2011-2012 Texas Instruments
5  *
6  * Author: Johan Hovold <jhovold@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under  the terms of the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the License, or (at your
11  * option) any later version.
12  */
13
14 #include <linux/atomic.h>
15 #include <linux/fs.h>
16 #include <linux/interrupt.h>
17 #include <linux/io.h>
18 #include <linux/iio/events.h>
19 #include <linux/iio/iio.h>
20 #include <linux/module.h>
21 #include <linux/mutex.h>
22 #include <linux/mfd/core.h>
23 #include <linux/platform_device.h>
24 #include <linux/slab.h>
25 #include <linux/uaccess.h>
26
27 #include <linux/mfd/lm3533.h>
28
29
30 #define LM3533_ALS_RESISTOR_MIN                 1
31 #define LM3533_ALS_RESISTOR_MAX                 127
32 #define LM3533_ALS_CHANNEL_CURRENT_MAX          2
33 #define LM3533_ALS_THRESH_MAX                   3
34 #define LM3533_ALS_ZONE_MAX                     4
35
36 #define LM3533_REG_ALS_RESISTOR_SELECT          0x30
37 #define LM3533_REG_ALS_CONF                     0x31
38 #define LM3533_REG_ALS_ZONE_INFO                0x34
39 #define LM3533_REG_ALS_READ_ADC_RAW             0x37
40 #define LM3533_REG_ALS_READ_ADC_AVERAGE         0x38
41 #define LM3533_REG_ALS_BOUNDARY_BASE            0x50
42 #define LM3533_REG_ALS_TARGET_BASE              0x60
43
44 #define LM3533_ALS_ENABLE_MASK                  0x01
45 #define LM3533_ALS_INPUT_MODE_MASK              0x02
46 #define LM3533_ALS_INT_ENABLE_MASK              0x01
47
48 #define LM3533_ALS_ZONE_SHIFT                   2
49 #define LM3533_ALS_ZONE_MASK                    0x1c
50
51 #define LM3533_ALS_FLAG_INT_ENABLED             1
52
53
54 struct lm3533_als {
55         struct lm3533 *lm3533;
56         struct platform_device *pdev;
57
58         unsigned long flags;
59         int irq;
60
61         atomic_t zone;
62         struct mutex thresh_mutex;
63 };
64
65
66 static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average,
67                                                                 int *adc)
68 {
69         struct lm3533_als *als = iio_priv(indio_dev);
70         u8 reg;
71         u8 val;
72         int ret;
73
74         if (average)
75                 reg = LM3533_REG_ALS_READ_ADC_AVERAGE;
76         else
77                 reg = LM3533_REG_ALS_READ_ADC_RAW;
78
79         ret = lm3533_read(als->lm3533, reg, &val);
80         if (ret) {
81                 dev_err(&indio_dev->dev, "failed to read adc\n");
82                 return ret;
83         }
84
85         *adc = val;
86
87         return 0;
88 }
89
90 static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
91 {
92         struct lm3533_als *als = iio_priv(indio_dev);
93         u8 val;
94         int ret;
95
96         ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
97         if (ret) {
98                 dev_err(&indio_dev->dev, "failed to read zone\n");
99                 return ret;
100         }
101
102         val = (val & LM3533_ALS_ZONE_MASK) >> LM3533_ALS_ZONE_SHIFT;
103         *zone = min_t(u8, val, LM3533_ALS_ZONE_MAX);
104
105         return 0;
106 }
107
108 static int lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
109 {
110         struct lm3533_als *als = iio_priv(indio_dev);
111         int ret;
112
113         if (test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags)) {
114                 *zone = atomic_read(&als->zone);
115         } else {
116                 ret = _lm3533_als_get_zone(indio_dev, zone);
117                 if (ret)
118                         return ret;
119         }
120
121         return 0;
122 }
123
124 /*
125  * channel      output channel 0..2
126  * zone         zone 0..4
127  */
128 static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone)
129 {
130         return LM3533_REG_ALS_TARGET_BASE + 5 * channel + zone;
131 }
132
133 static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel,
134                                                         unsigned zone, u8 *val)
135 {
136         struct lm3533_als *als = iio_priv(indio_dev);
137         u8 reg;
138         int ret;
139
140         if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
141                 return -EINVAL;
142
143         if (zone > LM3533_ALS_ZONE_MAX)
144                 return -EINVAL;
145
146         reg = lm3533_als_get_target_reg(channel, zone);
147         ret = lm3533_read(als->lm3533, reg, val);
148         if (ret)
149                 dev_err(&indio_dev->dev, "failed to get target current\n");
150
151         return ret;
152 }
153
154 static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel,
155                                                         unsigned zone, u8 val)
156 {
157         struct lm3533_als *als = iio_priv(indio_dev);
158         u8 reg;
159         int ret;
160
161         if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
162                 return -EINVAL;
163
164         if (zone > LM3533_ALS_ZONE_MAX)
165                 return -EINVAL;
166
167         reg = lm3533_als_get_target_reg(channel, zone);
168         ret = lm3533_write(als->lm3533, reg, val);
169         if (ret)
170                 dev_err(&indio_dev->dev, "failed to set target current\n");
171
172         return ret;
173 }
174
175 static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel,
176                                                                 int *val)
177 {
178         u8 zone;
179         u8 target;
180         int ret;
181
182         ret = lm3533_als_get_zone(indio_dev, &zone);
183         if (ret)
184                 return ret;
185
186         ret = lm3533_als_get_target(indio_dev, channel, zone, &target);
187         if (ret)
188                 return ret;
189
190         *val = target;
191
192         return 0;
193 }
194
195 static int lm3533_als_read_raw(struct iio_dev *indio_dev,
196                                 struct iio_chan_spec const *chan,
197                                 int *val, int *val2, long mask)
198 {
199         int ret;
200
201         switch (mask) {
202         case 0:
203                 switch (chan->type) {
204                 case IIO_LIGHT:
205                         ret = lm3533_als_get_adc(indio_dev, false, val);
206                         break;
207                 case IIO_CURRENT:
208                         ret = lm3533_als_get_current(indio_dev, chan->channel,
209                                                                         val);
210                         break;
211                 default:
212                         return -EINVAL;
213                 }
214                 break;
215         case IIO_CHAN_INFO_AVERAGE_RAW:
216                 ret = lm3533_als_get_adc(indio_dev, true, val);
217                 break;
218         default:
219                 return -EINVAL;
220         }
221
222         if (ret)
223                 return ret;
224
225         return IIO_VAL_INT;
226 }
227
228 #define CHANNEL_CURRENT(_channel)                                       \
229         {                                                               \
230                 .type           = IIO_CURRENT,                          \
231                 .channel        = _channel,                             \
232                 .indexed        = true,                                 \
233                 .output         = true,                                 \
234                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
235         }
236
237 static const struct iio_chan_spec lm3533_als_channels[] = {
238         {
239                 .type           = IIO_LIGHT,
240                 .channel        = 0,
241                 .indexed        = true,
242                 .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) |
243                                    BIT(IIO_CHAN_INFO_RAW),
244         },
245         CHANNEL_CURRENT(0),
246         CHANNEL_CURRENT(1),
247         CHANNEL_CURRENT(2),
248 };
249
250 static irqreturn_t lm3533_als_isr(int irq, void *dev_id)
251 {
252
253         struct iio_dev *indio_dev = dev_id;
254         struct lm3533_als *als = iio_priv(indio_dev);
255         u8 zone;
256         int ret;
257
258         /* Clear interrupt by reading the ALS zone register. */
259         ret = _lm3533_als_get_zone(indio_dev, &zone);
260         if (ret)
261                 goto out;
262
263         atomic_set(&als->zone, zone);
264
265         iio_push_event(indio_dev,
266                        IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
267                                             0,
268                                             IIO_EV_TYPE_THRESH,
269                                             IIO_EV_DIR_EITHER),
270                        iio_get_time_ns(indio_dev));
271 out:
272         return IRQ_HANDLED;
273 }
274
275 static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable)
276 {
277         struct lm3533_als *als = iio_priv(indio_dev);
278         u8 mask = LM3533_ALS_INT_ENABLE_MASK;
279         u8 val;
280         int ret;
281
282         if (enable)
283                 val = mask;
284         else
285                 val = 0;
286
287         ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask);
288         if (ret) {
289                 dev_err(&indio_dev->dev, "failed to set int mode %d\n",
290                                                                 enable);
291                 return ret;
292         }
293
294         return 0;
295 }
296
297 static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable)
298 {
299         struct lm3533_als *als = iio_priv(indio_dev);
300         u8 mask = LM3533_ALS_INT_ENABLE_MASK;
301         u8 val;
302         int ret;
303
304         ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
305         if (ret) {
306                 dev_err(&indio_dev->dev, "failed to get int mode\n");
307                 return ret;
308         }
309
310         *enable = !!(val & mask);
311
312         return 0;
313 }
314
315 static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising)
316 {
317         u8 offset = !raising;
318
319         return LM3533_REG_ALS_BOUNDARY_BASE + 2 * nr + offset;
320 }
321
322 static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr,
323                                                         bool raising, u8 *val)
324 {
325         struct lm3533_als *als = iio_priv(indio_dev);
326         u8 reg;
327         int ret;
328
329         if (nr > LM3533_ALS_THRESH_MAX)
330                 return -EINVAL;
331
332         reg = lm3533_als_get_threshold_reg(nr, raising);
333         ret = lm3533_read(als->lm3533, reg, val);
334         if (ret)
335                 dev_err(&indio_dev->dev, "failed to get threshold\n");
336
337         return ret;
338 }
339
340 static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
341                                                         bool raising, u8 val)
342 {
343         struct lm3533_als *als = iio_priv(indio_dev);
344         u8 val2;
345         u8 reg, reg2;
346         int ret;
347
348         if (nr > LM3533_ALS_THRESH_MAX)
349                 return -EINVAL;
350
351         reg = lm3533_als_get_threshold_reg(nr, raising);
352         reg2 = lm3533_als_get_threshold_reg(nr, !raising);
353
354         mutex_lock(&als->thresh_mutex);
355         ret = lm3533_read(als->lm3533, reg2, &val2);
356         if (ret) {
357                 dev_err(&indio_dev->dev, "failed to get threshold\n");
358                 goto out;
359         }
360         /*
361          * This device does not allow negative hysteresis (in fact, it uses
362          * whichever value is smaller as the lower bound) so we need to make
363          * sure that thresh_falling <= thresh_raising.
364          */
365         if ((raising && (val < val2)) || (!raising && (val > val2))) {
366                 ret = -EINVAL;
367                 goto out;
368         }
369
370         ret = lm3533_write(als->lm3533, reg, val);
371         if (ret) {
372                 dev_err(&indio_dev->dev, "failed to set threshold\n");
373                 goto out;
374         }
375 out:
376         mutex_unlock(&als->thresh_mutex);
377
378         return ret;
379 }
380
381 static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr,
382                                                                 u8 *val)
383 {
384         struct lm3533_als *als = iio_priv(indio_dev);
385         u8 falling;
386         u8 raising;
387         int ret;
388
389         if (nr > LM3533_ALS_THRESH_MAX)
390                 return -EINVAL;
391
392         mutex_lock(&als->thresh_mutex);
393         ret = lm3533_als_get_threshold(indio_dev, nr, false, &falling);
394         if (ret)
395                 goto out;
396         ret = lm3533_als_get_threshold(indio_dev, nr, true, &raising);
397         if (ret)
398                 goto out;
399
400         *val = raising - falling;
401 out:
402         mutex_unlock(&als->thresh_mutex);
403
404         return ret;
405 }
406
407 static ssize_t show_thresh_either_en(struct device *dev,
408                                         struct device_attribute *attr,
409                                         char *buf)
410 {
411         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
412         struct lm3533_als *als = iio_priv(indio_dev);
413         int enable;
414         int ret;
415
416         if (als->irq) {
417                 ret = lm3533_als_get_int_mode(indio_dev, &enable);
418                 if (ret)
419                         return ret;
420         } else {
421                 enable = 0;
422         }
423
424         return scnprintf(buf, PAGE_SIZE, "%u\n", enable);
425 }
426
427 static ssize_t store_thresh_either_en(struct device *dev,
428                                         struct device_attribute *attr,
429                                         const char *buf, size_t len)
430 {
431         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
432         struct lm3533_als *als = iio_priv(indio_dev);
433         unsigned long enable;
434         bool int_enabled;
435         u8 zone;
436         int ret;
437
438         if (!als->irq)
439                 return -EBUSY;
440
441         if (kstrtoul(buf, 0, &enable))
442                 return -EINVAL;
443
444         int_enabled = test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
445
446         if (enable && !int_enabled) {
447                 ret = lm3533_als_get_zone(indio_dev, &zone);
448                 if (ret)
449                         return ret;
450
451                 atomic_set(&als->zone, zone);
452
453                 set_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
454         }
455
456         ret = lm3533_als_set_int_mode(indio_dev, enable);
457         if (ret) {
458                 if (!int_enabled)
459                         clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
460
461                 return ret;
462         }
463
464         if (!enable)
465                 clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
466
467         return len;
468 }
469
470 static ssize_t show_zone(struct device *dev,
471                                 struct device_attribute *attr, char *buf)
472 {
473         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
474         u8 zone;
475         int ret;
476
477         ret = lm3533_als_get_zone(indio_dev, &zone);
478         if (ret)
479                 return ret;
480
481         return scnprintf(buf, PAGE_SIZE, "%u\n", zone);
482 }
483
484 enum lm3533_als_attribute_type {
485         LM3533_ATTR_TYPE_HYSTERESIS,
486         LM3533_ATTR_TYPE_TARGET,
487         LM3533_ATTR_TYPE_THRESH_FALLING,
488         LM3533_ATTR_TYPE_THRESH_RAISING,
489 };
490
491 struct lm3533_als_attribute {
492         struct device_attribute dev_attr;
493         enum lm3533_als_attribute_type type;
494         u8 val1;
495         u8 val2;
496 };
497
498 static inline struct lm3533_als_attribute *
499 to_lm3533_als_attr(struct device_attribute *attr)
500 {
501         return container_of(attr, struct lm3533_als_attribute, dev_attr);
502 }
503
504 static ssize_t show_als_attr(struct device *dev,
505                                         struct device_attribute *attr,
506                                         char *buf)
507 {
508         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
509         struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr);
510         u8 val;
511         int ret;
512
513         switch (als_attr->type) {
514         case LM3533_ATTR_TYPE_HYSTERESIS:
515                 ret = lm3533_als_get_hysteresis(indio_dev, als_attr->val1,
516                                                                         &val);
517                 break;
518         case LM3533_ATTR_TYPE_TARGET:
519                 ret = lm3533_als_get_target(indio_dev, als_attr->val1,
520                                                         als_attr->val2, &val);
521                 break;
522         case LM3533_ATTR_TYPE_THRESH_FALLING:
523                 ret = lm3533_als_get_threshold(indio_dev, als_attr->val1,
524                                                                 false, &val);
525                 break;
526         case LM3533_ATTR_TYPE_THRESH_RAISING:
527                 ret = lm3533_als_get_threshold(indio_dev, als_attr->val1,
528                                                                 true, &val);
529                 break;
530         default:
531                 ret = -ENXIO;
532         }
533
534         if (ret)
535                 return ret;
536
537         return scnprintf(buf, PAGE_SIZE, "%u\n", val);
538 }
539
540 static ssize_t store_als_attr(struct device *dev,
541                                         struct device_attribute *attr,
542                                         const char *buf, size_t len)
543 {
544         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
545         struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr);
546         u8 val;
547         int ret;
548
549         if (kstrtou8(buf, 0, &val))
550                 return -EINVAL;
551
552         switch (als_attr->type) {
553         case LM3533_ATTR_TYPE_TARGET:
554                 ret = lm3533_als_set_target(indio_dev, als_attr->val1,
555                                                         als_attr->val2, val);
556                 break;
557         case LM3533_ATTR_TYPE_THRESH_FALLING:
558                 ret = lm3533_als_set_threshold(indio_dev, als_attr->val1,
559                                                                 false, val);
560                 break;
561         case LM3533_ATTR_TYPE_THRESH_RAISING:
562                 ret = lm3533_als_set_threshold(indio_dev, als_attr->val1,
563                                                                 true, val);
564                 break;
565         default:
566                 ret = -ENXIO;
567         }
568
569         if (ret)
570                 return ret;
571
572         return len;
573 }
574
575 #define ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2)      \
576         { .dev_attr     = __ATTR(_name, _mode, _show, _store),          \
577           .type         = _type,                                        \
578           .val1         = _val1,                                        \
579           .val2         = _val2 }
580
581 #define LM3533_ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \
582         struct lm3533_als_attribute lm3533_als_attr_##_name =             \
583                 ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2)
584
585 #define ALS_TARGET_ATTR_RW(_channel, _zone)                             \
586         LM3533_ALS_ATTR(out_current##_channel##_current##_zone##_raw,   \
587                                 S_IRUGO | S_IWUSR,                      \
588                                 show_als_attr, store_als_attr,          \
589                                 LM3533_ATTR_TYPE_TARGET, _channel, _zone)
590 /*
591  * ALS output current values (ALS mapper targets)
592  *
593  * out_current[0-2]_current[0-4]_raw            0-255
594  */
595 static ALS_TARGET_ATTR_RW(0, 0);
596 static ALS_TARGET_ATTR_RW(0, 1);
597 static ALS_TARGET_ATTR_RW(0, 2);
598 static ALS_TARGET_ATTR_RW(0, 3);
599 static ALS_TARGET_ATTR_RW(0, 4);
600
601 static ALS_TARGET_ATTR_RW(1, 0);
602 static ALS_TARGET_ATTR_RW(1, 1);
603 static ALS_TARGET_ATTR_RW(1, 2);
604 static ALS_TARGET_ATTR_RW(1, 3);
605 static ALS_TARGET_ATTR_RW(1, 4);
606
607 static ALS_TARGET_ATTR_RW(2, 0);
608 static ALS_TARGET_ATTR_RW(2, 1);
609 static ALS_TARGET_ATTR_RW(2, 2);
610 static ALS_TARGET_ATTR_RW(2, 3);
611 static ALS_TARGET_ATTR_RW(2, 4);
612
613 #define ALS_THRESH_FALLING_ATTR_RW(_nr)                                 \
614         LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_falling_value,    \
615                         S_IRUGO | S_IWUSR,                              \
616                         show_als_attr, store_als_attr,          \
617                         LM3533_ATTR_TYPE_THRESH_FALLING, _nr, 0)
618
619 #define ALS_THRESH_RAISING_ATTR_RW(_nr)                                 \
620         LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_raising_value,    \
621                         S_IRUGO | S_IWUSR,                              \
622                         show_als_attr, store_als_attr,                  \
623                         LM3533_ATTR_TYPE_THRESH_RAISING, _nr, 0)
624 /*
625  * ALS Zone thresholds (boundaries)
626  *
627  * in_illuminance0_thresh[0-3]_falling_value    0-255
628  * in_illuminance0_thresh[0-3]_raising_value    0-255
629  */
630 static ALS_THRESH_FALLING_ATTR_RW(0);
631 static ALS_THRESH_FALLING_ATTR_RW(1);
632 static ALS_THRESH_FALLING_ATTR_RW(2);
633 static ALS_THRESH_FALLING_ATTR_RW(3);
634
635 static ALS_THRESH_RAISING_ATTR_RW(0);
636 static ALS_THRESH_RAISING_ATTR_RW(1);
637 static ALS_THRESH_RAISING_ATTR_RW(2);
638 static ALS_THRESH_RAISING_ATTR_RW(3);
639
640 #define ALS_HYSTERESIS_ATTR_RO(_nr)                                     \
641         LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_hysteresis,       \
642                         S_IRUGO, show_als_attr, NULL,                   \
643                         LM3533_ATTR_TYPE_HYSTERESIS, _nr, 0)
644 /*
645  * ALS Zone threshold hysteresis
646  *
647  * threshY_hysteresis = threshY_raising - threshY_falling
648  *
649  * in_illuminance0_thresh[0-3]_hysteresis       0-255
650  * in_illuminance0_thresh[0-3]_hysteresis       0-255
651  */
652 static ALS_HYSTERESIS_ATTR_RO(0);
653 static ALS_HYSTERESIS_ATTR_RO(1);
654 static ALS_HYSTERESIS_ATTR_RO(2);
655 static ALS_HYSTERESIS_ATTR_RO(3);
656
657 #define ILLUMINANCE_ATTR_RO(_name) \
658         DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL)
659 #define ILLUMINANCE_ATTR_RW(_name) \
660         DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR, \
661                                                 show_##_name, store_##_name)
662 /*
663  * ALS Zone threshold-event enable
664  *
665  * in_illuminance0_thresh_either_en             0,1
666  */
667 static ILLUMINANCE_ATTR_RW(thresh_either_en);
668
669 /*
670  * ALS Current Zone
671  *
672  * in_illuminance0_zone         0-4
673  */
674 static ILLUMINANCE_ATTR_RO(zone);
675
676 static struct attribute *lm3533_als_event_attributes[] = {
677         &dev_attr_in_illuminance0_thresh_either_en.attr,
678         &lm3533_als_attr_in_illuminance0_thresh0_falling_value.dev_attr.attr,
679         &lm3533_als_attr_in_illuminance0_thresh0_hysteresis.dev_attr.attr,
680         &lm3533_als_attr_in_illuminance0_thresh0_raising_value.dev_attr.attr,
681         &lm3533_als_attr_in_illuminance0_thresh1_falling_value.dev_attr.attr,
682         &lm3533_als_attr_in_illuminance0_thresh1_hysteresis.dev_attr.attr,
683         &lm3533_als_attr_in_illuminance0_thresh1_raising_value.dev_attr.attr,
684         &lm3533_als_attr_in_illuminance0_thresh2_falling_value.dev_attr.attr,
685         &lm3533_als_attr_in_illuminance0_thresh2_hysteresis.dev_attr.attr,
686         &lm3533_als_attr_in_illuminance0_thresh2_raising_value.dev_attr.attr,
687         &lm3533_als_attr_in_illuminance0_thresh3_falling_value.dev_attr.attr,
688         &lm3533_als_attr_in_illuminance0_thresh3_hysteresis.dev_attr.attr,
689         &lm3533_als_attr_in_illuminance0_thresh3_raising_value.dev_attr.attr,
690         NULL
691 };
692
693 static struct attribute_group lm3533_als_event_attribute_group = {
694         .attrs = lm3533_als_event_attributes
695 };
696
697 static struct attribute *lm3533_als_attributes[] = {
698         &dev_attr_in_illuminance0_zone.attr,
699         &lm3533_als_attr_out_current0_current0_raw.dev_attr.attr,
700         &lm3533_als_attr_out_current0_current1_raw.dev_attr.attr,
701         &lm3533_als_attr_out_current0_current2_raw.dev_attr.attr,
702         &lm3533_als_attr_out_current0_current3_raw.dev_attr.attr,
703         &lm3533_als_attr_out_current0_current4_raw.dev_attr.attr,
704         &lm3533_als_attr_out_current1_current0_raw.dev_attr.attr,
705         &lm3533_als_attr_out_current1_current1_raw.dev_attr.attr,
706         &lm3533_als_attr_out_current1_current2_raw.dev_attr.attr,
707         &lm3533_als_attr_out_current1_current3_raw.dev_attr.attr,
708         &lm3533_als_attr_out_current1_current4_raw.dev_attr.attr,
709         &lm3533_als_attr_out_current2_current0_raw.dev_attr.attr,
710         &lm3533_als_attr_out_current2_current1_raw.dev_attr.attr,
711         &lm3533_als_attr_out_current2_current2_raw.dev_attr.attr,
712         &lm3533_als_attr_out_current2_current3_raw.dev_attr.attr,
713         &lm3533_als_attr_out_current2_current4_raw.dev_attr.attr,
714         NULL
715 };
716
717 static struct attribute_group lm3533_als_attribute_group = {
718         .attrs = lm3533_als_attributes
719 };
720
721 static int lm3533_als_set_input_mode(struct lm3533_als *als, bool pwm_mode)
722 {
723         u8 mask = LM3533_ALS_INPUT_MODE_MASK;
724         u8 val;
725         int ret;
726
727         if (pwm_mode)
728                 val = mask;     /* pwm input */
729         else
730                 val = 0;        /* analog input */
731
732         ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask);
733         if (ret) {
734                 dev_err(&als->pdev->dev, "failed to set input mode %d\n",
735                                                                 pwm_mode);
736                 return ret;
737         }
738
739         return 0;
740 }
741
742 static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
743 {
744         int ret;
745
746         if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) {
747                 dev_err(&als->pdev->dev, "invalid resistor value\n");
748                 return -EINVAL;
749         };
750
751         ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val);
752         if (ret) {
753                 dev_err(&als->pdev->dev, "failed to set resistor\n");
754                 return ret;
755         }
756
757         return 0;
758 }
759
760 static int lm3533_als_setup(struct lm3533_als *als,
761                             struct lm3533_als_platform_data *pdata)
762 {
763         int ret;
764
765         ret = lm3533_als_set_input_mode(als, pdata->pwm_mode);
766         if (ret)
767                 return ret;
768
769         /* ALS input is always high impedance in PWM-mode. */
770         if (!pdata->pwm_mode) {
771                 ret = lm3533_als_set_resistor(als, pdata->r_select);
772                 if (ret)
773                         return ret;
774         }
775
776         return 0;
777 }
778
779 static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev)
780 {
781         u8 mask = LM3533_ALS_INT_ENABLE_MASK;
782         int ret;
783
784         /* Make sure interrupts are disabled. */
785         ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask);
786         if (ret) {
787                 dev_err(&als->pdev->dev, "failed to disable interrupts\n");
788                 return ret;
789         }
790
791         ret = request_threaded_irq(als->irq, NULL, lm3533_als_isr,
792                                         IRQF_TRIGGER_LOW | IRQF_ONESHOT,
793                                         dev_name(&als->pdev->dev), dev);
794         if (ret) {
795                 dev_err(&als->pdev->dev, "failed to request irq %d\n",
796                                                                 als->irq);
797                 return ret;
798         }
799
800         return 0;
801 }
802
803 static int lm3533_als_enable(struct lm3533_als *als)
804 {
805         u8 mask = LM3533_ALS_ENABLE_MASK;
806         int ret;
807
808         ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask);
809         if (ret)
810                 dev_err(&als->pdev->dev, "failed to enable ALS\n");
811
812         return ret;
813 }
814
815 static int lm3533_als_disable(struct lm3533_als *als)
816 {
817         u8 mask = LM3533_ALS_ENABLE_MASK;
818         int ret;
819
820         ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask);
821         if (ret)
822                 dev_err(&als->pdev->dev, "failed to disable ALS\n");
823
824         return ret;
825 }
826
827 static const struct iio_info lm3533_als_info = {
828         .attrs          = &lm3533_als_attribute_group,
829         .event_attrs    = &lm3533_als_event_attribute_group,
830         .driver_module  = THIS_MODULE,
831         .read_raw       = &lm3533_als_read_raw,
832 };
833
834 static int lm3533_als_probe(struct platform_device *pdev)
835 {
836         struct lm3533 *lm3533;
837         struct lm3533_als_platform_data *pdata;
838         struct lm3533_als *als;
839         struct iio_dev *indio_dev;
840         int ret;
841
842         lm3533 = dev_get_drvdata(pdev->dev.parent);
843         if (!lm3533)
844                 return -EINVAL;
845
846         pdata = pdev->dev.platform_data;
847         if (!pdata) {
848                 dev_err(&pdev->dev, "no platform data\n");
849                 return -EINVAL;
850         }
851
852         indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
853         if (!indio_dev)
854                 return -ENOMEM;
855
856         indio_dev->info = &lm3533_als_info;
857         indio_dev->channels = lm3533_als_channels;
858         indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels);
859         indio_dev->name = dev_name(&pdev->dev);
860         indio_dev->dev.parent = pdev->dev.parent;
861         indio_dev->modes = INDIO_DIRECT_MODE;
862
863         als = iio_priv(indio_dev);
864         als->lm3533 = lm3533;
865         als->pdev = pdev;
866         als->irq = lm3533->irq;
867         atomic_set(&als->zone, 0);
868         mutex_init(&als->thresh_mutex);
869
870         platform_set_drvdata(pdev, indio_dev);
871
872         if (als->irq) {
873                 ret = lm3533_als_setup_irq(als, indio_dev);
874                 if (ret)
875                         return ret;
876         }
877
878         ret = lm3533_als_setup(als, pdata);
879         if (ret)
880                 goto err_free_irq;
881
882         ret = lm3533_als_enable(als);
883         if (ret)
884                 goto err_free_irq;
885
886         ret = iio_device_register(indio_dev);
887         if (ret) {
888                 dev_err(&pdev->dev, "failed to register ALS\n");
889                 goto err_disable;
890         }
891
892         return 0;
893
894 err_disable:
895         lm3533_als_disable(als);
896 err_free_irq:
897         if (als->irq)
898                 free_irq(als->irq, indio_dev);
899
900         return ret;
901 }
902
903 static int lm3533_als_remove(struct platform_device *pdev)
904 {
905         struct iio_dev *indio_dev = platform_get_drvdata(pdev);
906         struct lm3533_als *als = iio_priv(indio_dev);
907
908         lm3533_als_set_int_mode(indio_dev, false);
909         iio_device_unregister(indio_dev);
910         lm3533_als_disable(als);
911         if (als->irq)
912                 free_irq(als->irq, indio_dev);
913
914         return 0;
915 }
916
917 static struct platform_driver lm3533_als_driver = {
918         .driver = {
919                 .name   = "lm3533-als",
920         },
921         .probe          = lm3533_als_probe,
922         .remove         = lm3533_als_remove,
923 };
924 module_platform_driver(lm3533_als_driver);
925
926 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
927 MODULE_DESCRIPTION("LM3533 Ambient Light Sensor driver");
928 MODULE_LICENSE("GPL");
929 MODULE_ALIAS("platform:lm3533-als");