xref: /openbmc/linux/drivers/iio/light/lm3533-als.c (revision 95d1c8c7)
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	= IIO_CHAN_INFO_RAW_SEPARATE_BIT,	\
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	= (IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT |
243 				   IIO_CHAN_INFO_RAW_SEPARATE_BIT),
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());
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 __devinit lm3533_als_set_input_mode(struct lm3533_als *als,
722 								bool pwm_mode)
723 {
724 	u8 mask = LM3533_ALS_INPUT_MODE_MASK;
725 	u8 val;
726 	int ret;
727 
728 	if (pwm_mode)
729 		val = mask;	/* pwm input */
730 	else
731 		val = 0;	/* analog input */
732 
733 	ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask);
734 	if (ret) {
735 		dev_err(&als->pdev->dev, "failed to set input mode %d\n",
736 								pwm_mode);
737 		return ret;
738 	}
739 
740 	return 0;
741 }
742 
743 static int __devinit lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
744 {
745 	int ret;
746 
747 	if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX)
748 		return -EINVAL;
749 
750 	ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val);
751 	if (ret) {
752 		dev_err(&als->pdev->dev, "failed to set resistor\n");
753 		return ret;
754 	}
755 
756 	return 0;
757 }
758 
759 static int __devinit lm3533_als_setup(struct lm3533_als *als,
760 					struct lm3533_als_platform_data *pdata)
761 {
762 	int ret;
763 
764 	ret = lm3533_als_set_input_mode(als, pdata->pwm_mode);
765 	if (ret)
766 		return ret;
767 
768 	/* ALS input is always high impedance in PWM-mode. */
769 	if (!pdata->pwm_mode) {
770 		ret = lm3533_als_set_resistor(als, pdata->r_select);
771 		if (ret)
772 			return ret;
773 	}
774 
775 	return 0;
776 }
777 
778 static int __devinit lm3533_als_setup_irq(struct lm3533_als *als, void *dev)
779 {
780 	u8 mask = LM3533_ALS_INT_ENABLE_MASK;
781 	int ret;
782 
783 	/* Make sure interrupts are disabled. */
784 	ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask);
785 	if (ret) {
786 		dev_err(&als->pdev->dev, "failed to disable interrupts\n");
787 		return ret;
788 	}
789 
790 	ret = request_threaded_irq(als->irq, NULL, lm3533_als_isr,
791 					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
792 					dev_name(&als->pdev->dev), dev);
793 	if (ret) {
794 		dev_err(&als->pdev->dev, "failed to request irq %d\n",
795 								als->irq);
796 		return ret;
797 	}
798 
799 	return 0;
800 }
801 
802 static int __devinit lm3533_als_enable(struct lm3533_als *als)
803 {
804 	u8 mask = LM3533_ALS_ENABLE_MASK;
805 	int ret;
806 
807 	ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask);
808 	if (ret)
809 		dev_err(&als->pdev->dev, "failed to enable ALS\n");
810 
811 	return ret;
812 }
813 
814 static int lm3533_als_disable(struct lm3533_als *als)
815 {
816 	u8 mask = LM3533_ALS_ENABLE_MASK;
817 	int ret;
818 
819 	ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask);
820 	if (ret)
821 		dev_err(&als->pdev->dev, "failed to disable ALS\n");
822 
823 	return ret;
824 }
825 
826 static const struct iio_info lm3533_als_info = {
827 	.attrs		= &lm3533_als_attribute_group,
828 	.event_attrs	= &lm3533_als_event_attribute_group,
829 	.driver_module	= THIS_MODULE,
830 	.read_raw	= &lm3533_als_read_raw,
831 };
832 
833 static int __devinit lm3533_als_probe(struct platform_device *pdev)
834 {
835 	struct lm3533 *lm3533;
836 	struct lm3533_als_platform_data *pdata;
837 	struct lm3533_als *als;
838 	struct iio_dev *indio_dev;
839 	int ret;
840 
841 	lm3533 = dev_get_drvdata(pdev->dev.parent);
842 	if (!lm3533)
843 		return -EINVAL;
844 
845 	pdata = pdev->dev.platform_data;
846 	if (!pdata) {
847 		dev_err(&pdev->dev, "no platform data\n");
848 		return -EINVAL;
849 	}
850 
851 	indio_dev = iio_device_alloc(sizeof(*als));
852 	if (!indio_dev)
853 		return -ENOMEM;
854 
855 	indio_dev->info = &lm3533_als_info;
856 	indio_dev->channels = lm3533_als_channels;
857 	indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels);
858 	indio_dev->name = dev_name(&pdev->dev);
859 	indio_dev->dev.parent = pdev->dev.parent;
860 	indio_dev->modes = INDIO_DIRECT_MODE;
861 
862 	als = iio_priv(indio_dev);
863 	als->lm3533 = lm3533;
864 	als->pdev = pdev;
865 	als->irq = lm3533->irq;
866 	atomic_set(&als->zone, 0);
867 	mutex_init(&als->thresh_mutex);
868 
869 	platform_set_drvdata(pdev, indio_dev);
870 
871 	if (als->irq) {
872 		ret = lm3533_als_setup_irq(als, indio_dev);
873 		if (ret)
874 			goto err_free_dev;
875 	}
876 
877 	ret = lm3533_als_setup(als, pdata);
878 	if (ret)
879 		goto err_free_irq;
880 
881 	ret = lm3533_als_enable(als);
882 	if (ret)
883 		goto err_free_irq;
884 
885 	ret = iio_device_register(indio_dev);
886 	if (ret) {
887 		dev_err(&pdev->dev, "failed to register ALS\n");
888 		goto err_disable;
889 	}
890 
891 	return 0;
892 
893 err_disable:
894 	lm3533_als_disable(als);
895 err_free_irq:
896 	if (als->irq)
897 		free_irq(als->irq, indio_dev);
898 err_free_dev:
899 	iio_device_free(indio_dev);
900 
901 	return ret;
902 }
903 
904 static int __devexit lm3533_als_remove(struct platform_device *pdev)
905 {
906 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
907 	struct lm3533_als *als = iio_priv(indio_dev);
908 
909 	lm3533_als_set_int_mode(indio_dev, false);
910 	iio_device_unregister(indio_dev);
911 	lm3533_als_disable(als);
912 	if (als->irq)
913 		free_irq(als->irq, indio_dev);
914 	iio_device_free(indio_dev);
915 
916 	return 0;
917 }
918 
919 static struct platform_driver lm3533_als_driver = {
920 	.driver	= {
921 		.name	= "lm3533-als",
922 		.owner	= THIS_MODULE,
923 	},
924 	.probe		= lm3533_als_probe,
925 	.remove		= __devexit_p(lm3533_als_remove),
926 };
927 module_platform_driver(lm3533_als_driver);
928 
929 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
930 MODULE_DESCRIPTION("LM3533 Ambient Light Sensor driver");
931 MODULE_LICENSE("GPL");
932 MODULE_ALIAS("platform:lm3533-als");
933