inet: frag: enforce memory limits earlier
[linux/fpc-iii.git] / drivers / iio / light / lm3533-als.c
blobf409c2047c050104437ca0387bccb5c401c6a602
1 /*
2 * lm3533-als.c -- LM3533 Ambient Light Sensor driver
4 * Copyright (C) 2011-2012 Texas Instruments
6 * Author: Johan Hovold <jhovold@gmail.com>
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.
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>
27 #include <linux/mfd/lm3533.h>
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
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
44 #define LM3533_ALS_ENABLE_MASK 0x01
45 #define LM3533_ALS_INPUT_MODE_MASK 0x02
46 #define LM3533_ALS_INT_ENABLE_MASK 0x01
48 #define LM3533_ALS_ZONE_SHIFT 2
49 #define LM3533_ALS_ZONE_MASK 0x1c
51 #define LM3533_ALS_FLAG_INT_ENABLED 1
54 struct lm3533_als {
55 struct lm3533 *lm3533;
56 struct platform_device *pdev;
58 unsigned long flags;
59 int irq;
61 atomic_t zone;
62 struct mutex thresh_mutex;
66 static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average,
67 int *adc)
69 struct lm3533_als *als = iio_priv(indio_dev);
70 u8 reg;
71 u8 val;
72 int ret;
74 if (average)
75 reg = LM3533_REG_ALS_READ_ADC_AVERAGE;
76 else
77 reg = LM3533_REG_ALS_READ_ADC_RAW;
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;
85 *adc = val;
87 return 0;
90 static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
92 struct lm3533_als *als = iio_priv(indio_dev);
93 u8 val;
94 int ret;
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;
102 val = (val & LM3533_ALS_ZONE_MASK) >> LM3533_ALS_ZONE_SHIFT;
103 *zone = min_t(u8, val, LM3533_ALS_ZONE_MAX);
105 return 0;
108 static int lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
110 struct lm3533_als *als = iio_priv(indio_dev);
111 int ret;
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;
121 return 0;
125 * channel output channel 0..2
126 * zone zone 0..4
128 static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone)
130 return LM3533_REG_ALS_TARGET_BASE + 5 * channel + zone;
133 static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel,
134 unsigned zone, u8 *val)
136 struct lm3533_als *als = iio_priv(indio_dev);
137 u8 reg;
138 int ret;
140 if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
141 return -EINVAL;
143 if (zone > LM3533_ALS_ZONE_MAX)
144 return -EINVAL;
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");
151 return ret;
154 static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel,
155 unsigned zone, u8 val)
157 struct lm3533_als *als = iio_priv(indio_dev);
158 u8 reg;
159 int ret;
161 if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
162 return -EINVAL;
164 if (zone > LM3533_ALS_ZONE_MAX)
165 return -EINVAL;
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");
172 return ret;
175 static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel,
176 int *val)
178 u8 zone;
179 u8 target;
180 int ret;
182 ret = lm3533_als_get_zone(indio_dev, &zone);
183 if (ret)
184 return ret;
186 ret = lm3533_als_get_target(indio_dev, channel, zone, &target);
187 if (ret)
188 return ret;
190 *val = target;
192 return 0;
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)
199 int ret;
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;
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;
222 if (ret)
223 return ret;
225 return IIO_VAL_INT;
228 #define CHANNEL_CURRENT(_channel) \
230 .type = IIO_CURRENT, \
231 .channel = _channel, \
232 .indexed = true, \
233 .output = true, \
234 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
237 static const struct iio_chan_spec lm3533_als_channels[] = {
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),
245 CHANNEL_CURRENT(0),
246 CHANNEL_CURRENT(1),
247 CHANNEL_CURRENT(2),
250 static irqreturn_t lm3533_als_isr(int irq, void *dev_id)
253 struct iio_dev *indio_dev = dev_id;
254 struct lm3533_als *als = iio_priv(indio_dev);
255 u8 zone;
256 int ret;
258 /* Clear interrupt by reading the ALS zone register. */
259 ret = _lm3533_als_get_zone(indio_dev, &zone);
260 if (ret)
261 goto out;
263 atomic_set(&als->zone, zone);
265 iio_push_event(indio_dev,
266 IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
268 IIO_EV_TYPE_THRESH,
269 IIO_EV_DIR_EITHER),
270 iio_get_time_ns(indio_dev));
271 out:
272 return IRQ_HANDLED;
275 static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable)
277 struct lm3533_als *als = iio_priv(indio_dev);
278 u8 mask = LM3533_ALS_INT_ENABLE_MASK;
279 u8 val;
280 int ret;
282 if (enable)
283 val = mask;
284 else
285 val = 0;
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;
294 return 0;
297 static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable)
299 struct lm3533_als *als = iio_priv(indio_dev);
300 u8 mask = LM3533_ALS_INT_ENABLE_MASK;
301 u8 val;
302 int ret;
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;
310 *enable = !!(val & mask);
312 return 0;
315 static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising)
317 u8 offset = !raising;
319 return LM3533_REG_ALS_BOUNDARY_BASE + 2 * nr + offset;
322 static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr,
323 bool raising, u8 *val)
325 struct lm3533_als *als = iio_priv(indio_dev);
326 u8 reg;
327 int ret;
329 if (nr > LM3533_ALS_THRESH_MAX)
330 return -EINVAL;
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");
337 return ret;
340 static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
341 bool raising, u8 val)
343 struct lm3533_als *als = iio_priv(indio_dev);
344 u8 val2;
345 u8 reg, reg2;
346 int ret;
348 if (nr > LM3533_ALS_THRESH_MAX)
349 return -EINVAL;
351 reg = lm3533_als_get_threshold_reg(nr, raising);
352 reg2 = lm3533_als_get_threshold_reg(nr, !raising);
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;
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.
365 if ((raising && (val < val2)) || (!raising && (val > val2))) {
366 ret = -EINVAL;
367 goto out;
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;
375 out:
376 mutex_unlock(&als->thresh_mutex);
378 return ret;
381 static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr,
382 u8 *val)
384 struct lm3533_als *als = iio_priv(indio_dev);
385 u8 falling;
386 u8 raising;
387 int ret;
389 if (nr > LM3533_ALS_THRESH_MAX)
390 return -EINVAL;
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;
400 *val = raising - falling;
401 out:
402 mutex_unlock(&als->thresh_mutex);
404 return ret;
407 static ssize_t show_thresh_either_en(struct device *dev,
408 struct device_attribute *attr,
409 char *buf)
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;
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;
424 return scnprintf(buf, PAGE_SIZE, "%u\n", enable);
427 static ssize_t store_thresh_either_en(struct device *dev,
428 struct device_attribute *attr,
429 const char *buf, size_t len)
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;
438 if (!als->irq)
439 return -EBUSY;
441 if (kstrtoul(buf, 0, &enable))
442 return -EINVAL;
444 int_enabled = test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
446 if (enable && !int_enabled) {
447 ret = lm3533_als_get_zone(indio_dev, &zone);
448 if (ret)
449 return ret;
451 atomic_set(&als->zone, zone);
453 set_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
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);
461 return ret;
464 if (!enable)
465 clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
467 return len;
470 static ssize_t show_zone(struct device *dev,
471 struct device_attribute *attr, char *buf)
473 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
474 u8 zone;
475 int ret;
477 ret = lm3533_als_get_zone(indio_dev, &zone);
478 if (ret)
479 return ret;
481 return scnprintf(buf, PAGE_SIZE, "%u\n", zone);
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,
491 struct lm3533_als_attribute {
492 struct device_attribute dev_attr;
493 enum lm3533_als_attribute_type type;
494 u8 val1;
495 u8 val2;
498 static inline struct lm3533_als_attribute *
499 to_lm3533_als_attr(struct device_attribute *attr)
501 return container_of(attr, struct lm3533_als_attribute, dev_attr);
504 static ssize_t show_als_attr(struct device *dev,
505 struct device_attribute *attr,
506 char *buf)
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;
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;
534 if (ret)
535 return ret;
537 return scnprintf(buf, PAGE_SIZE, "%u\n", val);
540 static ssize_t store_als_attr(struct device *dev,
541 struct device_attribute *attr,
542 const char *buf, size_t len)
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;
549 if (kstrtou8(buf, 0, &val))
550 return -EINVAL;
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;
569 if (ret)
570 return ret;
572 return len;
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 }
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)
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)
591 * ALS output current values (ALS mapper targets)
593 * out_current[0-2]_current[0-4]_raw 0-255
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);
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);
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);
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)
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)
625 * ALS Zone thresholds (boundaries)
627 * in_illuminance0_thresh[0-3]_falling_value 0-255
628 * in_illuminance0_thresh[0-3]_raising_value 0-255
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);
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);
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)
645 * ALS Zone threshold hysteresis
647 * threshY_hysteresis = threshY_raising - threshY_falling
649 * in_illuminance0_thresh[0-3]_hysteresis 0-255
650 * in_illuminance0_thresh[0-3]_hysteresis 0-255
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);
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)
663 * ALS Zone threshold-event enable
665 * in_illuminance0_thresh_either_en 0,1
667 static ILLUMINANCE_ATTR_RW(thresh_either_en);
670 * ALS Current Zone
672 * in_illuminance0_zone 0-4
674 static ILLUMINANCE_ATTR_RO(zone);
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
693 static struct attribute_group lm3533_als_event_attribute_group = {
694 .attrs = lm3533_als_event_attributes
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
717 static struct attribute_group lm3533_als_attribute_group = {
718 .attrs = lm3533_als_attributes
721 static int lm3533_als_set_input_mode(struct lm3533_als *als, bool pwm_mode)
723 u8 mask = LM3533_ALS_INPUT_MODE_MASK;
724 u8 val;
725 int ret;
727 if (pwm_mode)
728 val = mask; /* pwm input */
729 else
730 val = 0; /* analog input */
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;
739 return 0;
742 static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
744 int ret;
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;
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;
757 return 0;
760 static int lm3533_als_setup(struct lm3533_als *als,
761 struct lm3533_als_platform_data *pdata)
763 int ret;
765 ret = lm3533_als_set_input_mode(als, pdata->pwm_mode);
766 if (ret)
767 return ret;
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;
776 return 0;
779 static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev)
781 u8 mask = LM3533_ALS_INT_ENABLE_MASK;
782 int ret;
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;
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;
800 return 0;
803 static int lm3533_als_enable(struct lm3533_als *als)
805 u8 mask = LM3533_ALS_ENABLE_MASK;
806 int ret;
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");
812 return ret;
815 static int lm3533_als_disable(struct lm3533_als *als)
817 u8 mask = LM3533_ALS_ENABLE_MASK;
818 int ret;
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");
824 return ret;
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,
834 static int lm3533_als_probe(struct platform_device *pdev)
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;
842 lm3533 = dev_get_drvdata(pdev->dev.parent);
843 if (!lm3533)
844 return -EINVAL;
846 pdata = pdev->dev.platform_data;
847 if (!pdata) {
848 dev_err(&pdev->dev, "no platform data\n");
849 return -EINVAL;
852 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
853 if (!indio_dev)
854 return -ENOMEM;
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;
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);
870 platform_set_drvdata(pdev, indio_dev);
872 if (als->irq) {
873 ret = lm3533_als_setup_irq(als, indio_dev);
874 if (ret)
875 return ret;
878 ret = lm3533_als_setup(als, pdata);
879 if (ret)
880 goto err_free_irq;
882 ret = lm3533_als_enable(als);
883 if (ret)
884 goto err_free_irq;
886 ret = iio_device_register(indio_dev);
887 if (ret) {
888 dev_err(&pdev->dev, "failed to register ALS\n");
889 goto err_disable;
892 return 0;
894 err_disable:
895 lm3533_als_disable(als);
896 err_free_irq:
897 if (als->irq)
898 free_irq(als->irq, indio_dev);
900 return ret;
903 static int lm3533_als_remove(struct platform_device *pdev)
905 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
906 struct lm3533_als *als = iio_priv(indio_dev);
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);
914 return 0;
917 static struct platform_driver lm3533_als_driver = {
918 .driver = {
919 .name = "lm3533-als",
921 .probe = lm3533_als_probe,
922 .remove = lm3533_als_remove,
924 module_platform_driver(lm3533_als_driver);
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");