aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@kernel.org>2013-01-12 05:35:00 -0500
committerJonathan Cameron <jic23@kernel.org>2013-01-27 12:37:24 -0500
commit9c2251dd4b7feba14d35835c6835024840b1f76b (patch)
tree5f0ce5da5d55d02379f23b9eff0314f7cb595c38 /drivers/iio
parentaf0b8ee32c831e6e8fbfe0b311b9ac017d14b78d (diff)
iio:light:tsl2563 move out of staging
This driver is simple, uses the latest interfaces and contains few if any controversial elements. All of its interfaces have been in place for a long time now. Hence let's move it out of staging. Signed-off-by: Jonathan Cameron <jic23@kernel.org> Acked-by: Peter Meerwald <pmeerw@pmeerw.net>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/light/Kconfig10
-rw-r--r--drivers/iio/light/Makefile1
-rw-r--r--drivers/iio/light/tsl2563.c887
3 files changed, 898 insertions, 0 deletions
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index dbf80abc834f..5ef1a396e0c9 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -32,6 +32,16 @@ config SENSORS_LM3533
32 changes. The ALS-control output values can be set per zone for the 32 changes. The ALS-control output values can be set per zone for the
33 three current output channels. 33 three current output channels.
34 34
35config SENSORS_TSL2563
36 tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
37 depends on I2C
38 help
39 If you say yes here you get support for the Taos TSL2560,
40 TSL2561, TSL2562 and TSL2563 ambient light sensors.
41
42 This driver can also be built as a module. If so, the module
43 will be called tsl2563.
44
35config VCNL4000 45config VCNL4000
36 tristate "VCNL4000 combined ALS and proximity sensor" 46 tristate "VCNL4000 combined ALS and proximity sensor"
37 depends on I2C 47 depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 21a8f0df1407..040d9c75f8e6 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -4,5 +4,6 @@
4 4
5obj-$(CONFIG_ADJD_S311) += adjd_s311.o 5obj-$(CONFIG_ADJD_S311) += adjd_s311.o
6obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o 6obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
7obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
7obj-$(CONFIG_VCNL4000) += vcnl4000.o 8obj-$(CONFIG_VCNL4000) += vcnl4000.o
8obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o 9obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c
new file mode 100644
index 000000000000..fd8be69b7d05
--- /dev/null
+++ b/drivers/iio/light/tsl2563.c
@@ -0,0 +1,887 @@
1/*
2 * drivers/iio/light/tsl2563.c
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Written by Timo O. Karjalainen <timo.o.karjalainen@nokia.com>
7 * Contact: Amit Kucheria <amit.kucheria@verdurent.com>
8 *
9 * Converted to IIO driver
10 * Amit Kucheria <amit.kucheria@verdurent.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/module.h>
28#include <linux/i2c.h>
29#include <linux/interrupt.h>
30#include <linux/irq.h>
31#include <linux/sched.h>
32#include <linux/mutex.h>
33#include <linux/delay.h>
34#include <linux/pm.h>
35#include <linux/err.h>
36#include <linux/slab.h>
37
38#include <linux/iio/iio.h>
39#include <linux/iio/sysfs.h>
40#include <linux/iio/events.h>
41#include <linux/platform_data/tsl2563.h>
42
43/* Use this many bits for fraction part. */
44#define ADC_FRAC_BITS 14
45
46/* Given number of 1/10000's in ADC_FRAC_BITS precision. */
47#define FRAC10K(f) (((f) * (1L << (ADC_FRAC_BITS))) / (10000))
48
49/* Bits used for fraction in calibration coefficients.*/
50#define CALIB_FRAC_BITS 10
51/* 0.5 in CALIB_FRAC_BITS precision */
52#define CALIB_FRAC_HALF (1 << (CALIB_FRAC_BITS - 1))
53/* Make a fraction from a number n that was multiplied with b. */
54#define CALIB_FRAC(n, b) (((n) << CALIB_FRAC_BITS) / (b))
55/* Decimal 10^(digits in sysfs presentation) */
56#define CALIB_BASE_SYSFS 1000
57
58#define TSL2563_CMD 0x80
59#define TSL2563_CLEARINT 0x40
60
61#define TSL2563_REG_CTRL 0x00
62#define TSL2563_REG_TIMING 0x01
63#define TSL2563_REG_LOWLOW 0x02 /* data0 low threshold, 2 bytes */
64#define TSL2563_REG_LOWHIGH 0x03
65#define TSL2563_REG_HIGHLOW 0x04 /* data0 high threshold, 2 bytes */
66#define TSL2563_REG_HIGHHIGH 0x05
67#define TSL2563_REG_INT 0x06
68#define TSL2563_REG_ID 0x0a
69#define TSL2563_REG_DATA0LOW 0x0c /* broadband sensor value, 2 bytes */
70#define TSL2563_REG_DATA0HIGH 0x0d
71#define TSL2563_REG_DATA1LOW 0x0e /* infrared sensor value, 2 bytes */
72#define TSL2563_REG_DATA1HIGH 0x0f
73
74#define TSL2563_CMD_POWER_ON 0x03
75#define TSL2563_CMD_POWER_OFF 0x00
76#define TSL2563_CTRL_POWER_MASK 0x03
77
78#define TSL2563_TIMING_13MS 0x00
79#define TSL2563_TIMING_100MS 0x01
80#define TSL2563_TIMING_400MS 0x02
81#define TSL2563_TIMING_MASK 0x03
82#define TSL2563_TIMING_GAIN16 0x10
83#define TSL2563_TIMING_GAIN1 0x00
84
85#define TSL2563_INT_DISBLED 0x00
86#define TSL2563_INT_LEVEL 0x10
87#define TSL2563_INT_PERSIST(n) ((n) & 0x0F)
88
89struct tsl2563_gainlevel_coeff {
90 u8 gaintime;
91 u16 min;
92 u16 max;
93};
94
95static const struct tsl2563_gainlevel_coeff tsl2563_gainlevel_table[] = {
96 {
97 .gaintime = TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN16,
98 .min = 0,
99 .max = 65534,
100 }, {
101 .gaintime = TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN1,
102 .min = 2048,
103 .max = 65534,
104 }, {
105 .gaintime = TSL2563_TIMING_100MS | TSL2563_TIMING_GAIN1,
106 .min = 4095,
107 .max = 37177,
108 }, {
109 .gaintime = TSL2563_TIMING_13MS | TSL2563_TIMING_GAIN1,
110 .min = 3000,
111 .max = 65535,
112 },
113};
114
115struct tsl2563_chip {
116 struct mutex lock;
117 struct i2c_client *client;
118 struct delayed_work poweroff_work;
119
120 /* Remember state for suspend and resume functions */
121 bool suspended;
122
123 struct tsl2563_gainlevel_coeff const *gainlevel;
124
125 u16 low_thres;
126 u16 high_thres;
127 u8 intr;
128 bool int_enabled;
129
130 /* Calibration coefficients */
131 u32 calib0;
132 u32 calib1;
133 int cover_comp_gain;
134
135 /* Cache current values, to be returned while suspended */
136 u32 data0;
137 u32 data1;
138};
139
140static int tsl2563_set_power(struct tsl2563_chip *chip, int on)
141{
142 struct i2c_client *client = chip->client;
143 u8 cmd;
144
145 cmd = on ? TSL2563_CMD_POWER_ON : TSL2563_CMD_POWER_OFF;
146 return i2c_smbus_write_byte_data(client,
147 TSL2563_CMD | TSL2563_REG_CTRL, cmd);
148}
149
150/*
151 * Return value is 0 for off, 1 for on, or a negative error
152 * code if reading failed.
153 */
154static int tsl2563_get_power(struct tsl2563_chip *chip)
155{
156 struct i2c_client *client = chip->client;
157 int ret;
158
159 ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_CTRL);
160 if (ret < 0)
161 return ret;
162
163 return (ret & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON;
164}
165
166static int tsl2563_configure(struct tsl2563_chip *chip)
167{
168 int ret;
169
170 ret = i2c_smbus_write_byte_data(chip->client,
171 TSL2563_CMD | TSL2563_REG_TIMING,
172 chip->gainlevel->gaintime);
173 if (ret)
174 goto error_ret;
175 ret = i2c_smbus_write_byte_data(chip->client,
176 TSL2563_CMD | TSL2563_REG_HIGHLOW,
177 chip->high_thres & 0xFF);
178 if (ret)
179 goto error_ret;
180 ret = i2c_smbus_write_byte_data(chip->client,
181 TSL2563_CMD | TSL2563_REG_HIGHHIGH,
182 (chip->high_thres >> 8) & 0xFF);
183 if (ret)
184 goto error_ret;
185 ret = i2c_smbus_write_byte_data(chip->client,
186 TSL2563_CMD | TSL2563_REG_LOWLOW,
187 chip->low_thres & 0xFF);
188 if (ret)
189 goto error_ret;
190 ret = i2c_smbus_write_byte_data(chip->client,
191 TSL2563_CMD | TSL2563_REG_LOWHIGH,
192 (chip->low_thres >> 8) & 0xFF);
193/*
194 * Interrupt register is automatically written anyway if it is relevant
195 * so is not here.
196 */
197error_ret:
198 return ret;
199}
200
201static void tsl2563_poweroff_work(struct work_struct *work)
202{
203 struct tsl2563_chip *chip =
204 container_of(work, struct tsl2563_chip, poweroff_work.work);
205 tsl2563_set_power(chip, 0);
206}
207
208static int tsl2563_detect(struct tsl2563_chip *chip)
209{
210 int ret;
211
212 ret = tsl2563_set_power(chip, 1);
213 if (ret)
214 return ret;
215
216 ret = tsl2563_get_power(chip);
217 if (ret < 0)
218 return ret;
219
220 return ret ? 0 : -ENODEV;
221}
222
223static int tsl2563_read_id(struct tsl2563_chip *chip, u8 *id)
224{
225 struct i2c_client *client = chip->client;
226 int ret;
227
228 ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_ID);
229 if (ret < 0)
230 return ret;
231
232 *id = ret;
233
234 return 0;
235}
236
237/*
238 * "Normalized" ADC value is one obtained with 400ms of integration time and
239 * 16x gain. This function returns the number of bits of shift needed to
240 * convert between normalized values and HW values obtained using given
241 * timing and gain settings.
242 */
243static int adc_shiftbits(u8 timing)
244{
245 int shift = 0;
246
247 switch (timing & TSL2563_TIMING_MASK) {
248 case TSL2563_TIMING_13MS:
249 shift += 5;
250 break;
251 case TSL2563_TIMING_100MS:
252 shift += 2;
253 break;
254 case TSL2563_TIMING_400MS:
255 /* no-op */
256 break;
257 }
258
259 if (!(timing & TSL2563_TIMING_GAIN16))
260 shift += 4;
261
262 return shift;
263}
264
265/* Convert a HW ADC value to normalized scale. */
266static u32 normalize_adc(u16 adc, u8 timing)
267{
268 return adc << adc_shiftbits(timing);
269}
270
271static void tsl2563_wait_adc(struct tsl2563_chip *chip)
272{
273 unsigned int delay;
274
275 switch (chip->gainlevel->gaintime & TSL2563_TIMING_MASK) {
276 case TSL2563_TIMING_13MS:
277 delay = 14;
278 break;
279 case TSL2563_TIMING_100MS:
280 delay = 101;
281 break;
282 default:
283 delay = 402;
284 }
285 /*
286 * TODO: Make sure that we wait at least required delay but why we
287 * have to extend it one tick more?
288 */
289 schedule_timeout_interruptible(msecs_to_jiffies(delay) + 2);
290}
291
292static int tsl2563_adjust_gainlevel(struct tsl2563_chip *chip, u16 adc)
293{
294 struct i2c_client *client = chip->client;
295
296 if (adc > chip->gainlevel->max || adc < chip->gainlevel->min) {
297
298 (adc > chip->gainlevel->max) ?
299 chip->gainlevel++ : chip->gainlevel--;
300
301 i2c_smbus_write_byte_data(client,
302 TSL2563_CMD | TSL2563_REG_TIMING,
303 chip->gainlevel->gaintime);
304
305 tsl2563_wait_adc(chip);
306 tsl2563_wait_adc(chip);
307
308 return 1;
309 } else
310 return 0;
311}
312
313static int tsl2563_get_adc(struct tsl2563_chip *chip)
314{
315 struct i2c_client *client = chip->client;
316 u16 adc0, adc1;
317 int retry = 1;
318 int ret = 0;
319
320 if (chip->suspended)
321 goto out;
322
323 if (!chip->int_enabled) {
324 cancel_delayed_work(&chip->poweroff_work);
325
326 if (!tsl2563_get_power(chip)) {
327 ret = tsl2563_set_power(chip, 1);
328 if (ret)
329 goto out;
330 ret = tsl2563_configure(chip);
331 if (ret)
332 goto out;
333 tsl2563_wait_adc(chip);
334 }
335 }
336
337 while (retry) {
338 ret = i2c_smbus_read_word_data(client,
339 TSL2563_CMD | TSL2563_REG_DATA0LOW);
340 if (ret < 0)
341 goto out;
342 adc0 = ret;
343
344 ret = i2c_smbus_read_word_data(client,
345 TSL2563_CMD | TSL2563_REG_DATA1LOW);
346 if (ret < 0)
347 goto out;
348 adc1 = ret;
349
350 retry = tsl2563_adjust_gainlevel(chip, adc0);
351 }
352
353 chip->data0 = normalize_adc(adc0, chip->gainlevel->gaintime);
354 chip->data1 = normalize_adc(adc1, chip->gainlevel->gaintime);
355
356 if (!chip->int_enabled)
357 schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
358
359 ret = 0;
360out:
361 return ret;
362}
363
364static inline int calib_to_sysfs(u32 calib)
365{
366 return (int) (((calib * CALIB_BASE_SYSFS) +
367 CALIB_FRAC_HALF) >> CALIB_FRAC_BITS);
368}
369
370static inline u32 calib_from_sysfs(int value)
371{
372 return (((u32) value) << CALIB_FRAC_BITS) / CALIB_BASE_SYSFS;
373}
374
375/*
376 * Conversions between lux and ADC values.
377 *
378 * The basic formula is lux = c0 * adc0 - c1 * adc1, where c0 and c1 are
379 * appropriate constants. Different constants are needed for different
380 * kinds of light, determined by the ratio adc1/adc0 (basically the ratio
381 * of the intensities in infrared and visible wavelengths). lux_table below
382 * lists the upper threshold of the adc1/adc0 ratio and the corresponding
383 * constants.
384 */
385
386struct tsl2563_lux_coeff {
387 unsigned long ch_ratio;
388 unsigned long ch0_coeff;
389 unsigned long ch1_coeff;
390};
391
392static const struct tsl2563_lux_coeff lux_table[] = {
393 {
394 .ch_ratio = FRAC10K(1300),
395 .ch0_coeff = FRAC10K(315),
396 .ch1_coeff = FRAC10K(262),
397 }, {
398 .ch_ratio = FRAC10K(2600),
399 .ch0_coeff = FRAC10K(337),
400 .ch1_coeff = FRAC10K(430),
401 }, {
402 .ch_ratio = FRAC10K(3900),
403 .ch0_coeff = FRAC10K(363),
404 .ch1_coeff = FRAC10K(529),
405 }, {
406 .ch_ratio = FRAC10K(5200),
407 .ch0_coeff = FRAC10K(392),
408 .ch1_coeff = FRAC10K(605),
409 }, {
410 .ch_ratio = FRAC10K(6500),
411 .ch0_coeff = FRAC10K(229),
412 .ch1_coeff = FRAC10K(291),
413 }, {
414 .ch_ratio = FRAC10K(8000),
415 .ch0_coeff = FRAC10K(157),
416 .ch1_coeff = FRAC10K(180),
417 }, {
418 .ch_ratio = FRAC10K(13000),
419 .ch0_coeff = FRAC10K(34),
420 .ch1_coeff = FRAC10K(26),
421 }, {
422 .ch_ratio = ULONG_MAX,
423 .ch0_coeff = 0,
424 .ch1_coeff = 0,
425 },
426};
427
428/* Convert normalized, scaled ADC values to lux. */
429static unsigned int adc_to_lux(u32 adc0, u32 adc1)
430{
431 const struct tsl2563_lux_coeff *lp = lux_table;
432 unsigned long ratio, lux, ch0 = adc0, ch1 = adc1;
433
434 ratio = ch0 ? ((ch1 << ADC_FRAC_BITS) / ch0) : ULONG_MAX;
435
436 while (lp->ch_ratio < ratio)
437 lp++;
438
439 lux = ch0 * lp->ch0_coeff - ch1 * lp->ch1_coeff;
440
441 return (unsigned int) (lux >> ADC_FRAC_BITS);
442}
443
444/* Apply calibration coefficient to ADC count. */
445static u32 calib_adc(u32 adc, u32 calib)
446{
447 unsigned long scaled = adc;
448
449 scaled *= calib;
450 scaled >>= CALIB_FRAC_BITS;
451
452 return (u32) scaled;
453}
454
455static int tsl2563_write_raw(struct iio_dev *indio_dev,
456 struct iio_chan_spec const *chan,
457 int val,
458 int val2,
459 long mask)
460{
461 struct tsl2563_chip *chip = iio_priv(indio_dev);
462
463 if (chan->channel == IIO_MOD_LIGHT_BOTH)
464 chip->calib0 = calib_from_sysfs(val);
465 else
466 chip->calib1 = calib_from_sysfs(val);
467
468 return 0;
469}
470
471static int tsl2563_read_raw(struct iio_dev *indio_dev,
472 struct iio_chan_spec const *chan,
473 int *val,
474 int *val2,
475 long m)
476{
477 int ret = -EINVAL;
478 u32 calib0, calib1;
479 struct tsl2563_chip *chip = iio_priv(indio_dev);
480
481 mutex_lock(&chip->lock);
482 switch (m) {
483 case IIO_CHAN_INFO_RAW:
484 case IIO_CHAN_INFO_PROCESSED:
485 switch (chan->type) {
486 case IIO_LIGHT:
487 ret = tsl2563_get_adc(chip);
488 if (ret)
489 goto error_ret;
490 calib0 = calib_adc(chip->data0, chip->calib0) *
491 chip->cover_comp_gain;
492 calib1 = calib_adc(chip->data1, chip->calib1) *
493 chip->cover_comp_gain;
494 *val = adc_to_lux(calib0, calib1);
495 ret = IIO_VAL_INT;
496 break;
497 case IIO_INTENSITY:
498 ret = tsl2563_get_adc(chip);
499 if (ret)
500 goto error_ret;
501 if (chan->channel == 0)
502 *val = chip->data0;
503 else
504 *val = chip->data1;
505 ret = IIO_VAL_INT;
506 break;
507 default:
508 break;
509 }
510 break;
511
512 case IIO_CHAN_INFO_CALIBSCALE:
513 if (chan->channel == 0)
514 *val = calib_to_sysfs(chip->calib0);
515 else
516 *val = calib_to_sysfs(chip->calib1);
517 ret = IIO_VAL_INT;
518 break;
519 default:
520 ret = -EINVAL;
521 goto error_ret;
522 }
523
524error_ret:
525 mutex_unlock(&chip->lock);
526 return ret;
527}
528
529static const struct iio_chan_spec tsl2563_channels[] = {
530 {
531 .type = IIO_LIGHT,
532 .indexed = 1,
533 .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT,
534 .channel = 0,
535 }, {
536 .type = IIO_INTENSITY,
537 .modified = 1,
538 .channel2 = IIO_MOD_LIGHT_BOTH,
539 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
540 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
541 .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
542 IIO_EV_DIR_RISING) |
543 IIO_EV_BIT(IIO_EV_TYPE_THRESH,
544 IIO_EV_DIR_FALLING)),
545 }, {
546 .type = IIO_INTENSITY,
547 .modified = 1,
548 .channel2 = IIO_MOD_LIGHT_IR,
549 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
550 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
551 }
552};
553
554static int tsl2563_read_thresh(struct iio_dev *indio_dev,
555 u64 event_code,
556 int *val)
557{
558 struct tsl2563_chip *chip = iio_priv(indio_dev);
559
560 switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
561 case IIO_EV_DIR_RISING:
562 *val = chip->high_thres;
563 break;
564 case IIO_EV_DIR_FALLING:
565 *val = chip->low_thres;
566 break;
567 default:
568 return -EINVAL;
569 }
570
571 return 0;
572}
573
574static int tsl2563_write_thresh(struct iio_dev *indio_dev,
575 u64 event_code,
576 int val)
577{
578 struct tsl2563_chip *chip = iio_priv(indio_dev);
579 int ret;
580 u8 address;
581
582 if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
583 address = TSL2563_REG_HIGHLOW;
584 else
585 address = TSL2563_REG_LOWLOW;
586 mutex_lock(&chip->lock);
587 ret = i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | address,
588 val & 0xFF);
589 if (ret)
590 goto error_ret;
591 ret = i2c_smbus_write_byte_data(chip->client,
592 TSL2563_CMD | (address + 1),
593 (val >> 8) & 0xFF);
594 if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
595 chip->high_thres = val;
596 else
597 chip->low_thres = val;
598
599error_ret:
600 mutex_unlock(&chip->lock);
601
602 return ret;
603}
604
605static irqreturn_t tsl2563_event_handler(int irq, void *private)
606{
607 struct iio_dev *dev_info = private;
608 struct tsl2563_chip *chip = iio_priv(dev_info);
609
610 iio_push_event(dev_info,
611 IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
612 0,
613 IIO_EV_TYPE_THRESH,
614 IIO_EV_DIR_EITHER),
615 iio_get_time_ns());
616
617 /* clear the interrupt and push the event */
618 i2c_smbus_write_byte(chip->client, TSL2563_CMD | TSL2563_CLEARINT);
619 return IRQ_HANDLED;
620}
621
622static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
623 u64 event_code,
624 int state)
625{
626 struct tsl2563_chip *chip = iio_priv(indio_dev);
627 int ret = 0;
628
629 mutex_lock(&chip->lock);
630 if (state && !(chip->intr & 0x30)) {
631 chip->intr &= ~0x30;
632 chip->intr |= 0x10;
633 /* ensure the chip is actually on */
634 cancel_delayed_work(&chip->poweroff_work);
635 if (!tsl2563_get_power(chip)) {
636 ret = tsl2563_set_power(chip, 1);
637 if (ret)
638 goto out;
639 ret = tsl2563_configure(chip);
640 if (ret)
641 goto out;
642 }
643 ret = i2c_smbus_write_byte_data(chip->client,
644 TSL2563_CMD | TSL2563_REG_INT,
645 chip->intr);
646 chip->int_enabled = true;
647 }
648
649 if (!state && (chip->intr & 0x30)) {
650 chip->intr &= ~0x30;
651 ret = i2c_smbus_write_byte_data(chip->client,
652 TSL2563_CMD | TSL2563_REG_INT,
653 chip->intr);
654 chip->int_enabled = false;
655 /* now the interrupt is not enabled, we can go to sleep */
656 schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
657 }
658out:
659 mutex_unlock(&chip->lock);
660
661 return ret;
662}
663
664static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
665 u64 event_code)
666{
667 struct tsl2563_chip *chip = iio_priv(indio_dev);
668 int ret;
669
670 mutex_lock(&chip->lock);
671 ret = i2c_smbus_read_byte_data(chip->client,
672 TSL2563_CMD | TSL2563_REG_INT);
673 mutex_unlock(&chip->lock);
674 if (ret < 0)
675 return ret;
676
677 return !!(ret & 0x30);
678}
679
680static const struct iio_info tsl2563_info_no_irq = {
681 .driver_module = THIS_MODULE,
682 .read_raw = &tsl2563_read_raw,
683 .write_raw = &tsl2563_write_raw,
684};
685
686static const struct iio_info tsl2563_info = {
687 .driver_module = THIS_MODULE,
688 .read_raw = &tsl2563_read_raw,
689 .write_raw = &tsl2563_write_raw,
690 .read_event_value = &tsl2563_read_thresh,
691 .write_event_value = &tsl2563_write_thresh,
692 .read_event_config = &tsl2563_read_interrupt_config,
693 .write_event_config = &tsl2563_write_interrupt_config,
694};
695
696static int tsl2563_probe(struct i2c_client *client,
697 const struct i2c_device_id *device_id)
698{
699 struct iio_dev *indio_dev;
700 struct tsl2563_chip *chip;
701 struct tsl2563_platform_data *pdata = client->dev.platform_data;
702 int err = 0;
703 u8 id = 0;
704
705 indio_dev = iio_device_alloc(sizeof(*chip));
706 if (!indio_dev)
707 return -ENOMEM;
708
709 chip = iio_priv(indio_dev);
710
711 i2c_set_clientdata(client, chip);
712 chip->client = client;
713
714 err = tsl2563_detect(chip);
715 if (err) {
716 dev_err(&client->dev, "detect error %d\n", -err);
717 goto fail1;
718 }
719
720 err = tsl2563_read_id(chip, &id);
721 if (err) {
722 dev_err(&client->dev, "read id error %d\n", -err);
723 goto fail1;
724 }
725
726 mutex_init(&chip->lock);
727
728 /* Default values used until userspace says otherwise */
729 chip->low_thres = 0x0;
730 chip->high_thres = 0xffff;
731 chip->gainlevel = tsl2563_gainlevel_table;
732 chip->intr = TSL2563_INT_PERSIST(4);
733 chip->calib0 = calib_from_sysfs(CALIB_BASE_SYSFS);
734 chip->calib1 = calib_from_sysfs(CALIB_BASE_SYSFS);
735
736 if (pdata)
737 chip->cover_comp_gain = pdata->cover_comp_gain;
738 else
739 chip->cover_comp_gain = 1;
740
741 dev_info(&client->dev, "model %d, rev. %d\n", id >> 4, id & 0x0f);
742 indio_dev->name = client->name;
743 indio_dev->channels = tsl2563_channels;
744 indio_dev->num_channels = ARRAY_SIZE(tsl2563_channels);
745 indio_dev->dev.parent = &client->dev;
746 indio_dev->modes = INDIO_DIRECT_MODE;
747
748 if (client->irq)
749 indio_dev->info = &tsl2563_info;
750 else
751 indio_dev->info = &tsl2563_info_no_irq;
752
753 if (client->irq) {
754 err = request_threaded_irq(client->irq,
755 NULL,
756 &tsl2563_event_handler,
757 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
758 "tsl2563_event",
759 indio_dev);
760 if (err) {
761 dev_err(&client->dev, "irq request error %d\n", -err);
762 goto fail1;
763 }
764 }
765
766 err = tsl2563_configure(chip);
767 if (err) {
768 dev_err(&client->dev, "configure error %d\n", -err);
769 goto fail2;
770 }
771
772 INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
773
774 /* The interrupt cannot yet be enabled so this is fine without lock */
775 schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
776
777 err = iio_device_register(indio_dev);
778 if (err) {
779 dev_err(&client->dev, "iio registration error %d\n", -err);
780 goto fail3;
781 }
782
783 return 0;
784
785fail3:
786 cancel_delayed_work(&chip->poweroff_work);
787 flush_scheduled_work();
788fail2:
789 if (client->irq)
790 free_irq(client->irq, indio_dev);
791fail1:
792 iio_device_free(indio_dev);
793 return err;
794}
795
796static int tsl2563_remove(struct i2c_client *client)
797{
798 struct tsl2563_chip *chip = i2c_get_clientdata(client);
799 struct iio_dev *indio_dev = iio_priv_to_dev(chip);
800
801 iio_device_unregister(indio_dev);
802 if (!chip->int_enabled)
803 cancel_delayed_work(&chip->poweroff_work);
804 /* Ensure that interrupts are disabled - then flush any bottom halves */
805 chip->intr &= ~0x30;
806 i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT,
807 chip->intr);
808 flush_scheduled_work();
809 tsl2563_set_power(chip, 0);
810 if (client->irq)
811 free_irq(client->irq, indio_dev);
812
813 iio_device_free(indio_dev);
814
815 return 0;
816}
817
818#ifdef CONFIG_PM_SLEEP
819static int tsl2563_suspend(struct device *dev)
820{
821 struct tsl2563_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
822 int ret;
823
824 mutex_lock(&chip->lock);
825
826 ret = tsl2563_set_power(chip, 0);
827 if (ret)
828 goto out;
829
830 chip->suspended = true;
831
832out:
833 mutex_unlock(&chip->lock);
834 return ret;
835}
836
837static int tsl2563_resume(struct device *dev)
838{
839 struct tsl2563_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
840 int ret;
841
842 mutex_lock(&chip->lock);
843
844 ret = tsl2563_set_power(chip, 1);
845 if (ret)
846 goto out;
847
848 ret = tsl2563_configure(chip);
849 if (ret)
850 goto out;
851
852 chip->suspended = false;
853
854out:
855 mutex_unlock(&chip->lock);
856 return ret;
857}
858
859static SIMPLE_DEV_PM_OPS(tsl2563_pm_ops, tsl2563_suspend, tsl2563_resume);
860#define TSL2563_PM_OPS (&tsl2563_pm_ops)
861#else
862#define TSL2563_PM_OPS NULL
863#endif
864
865static const struct i2c_device_id tsl2563_id[] = {
866 { "tsl2560", 0 },
867 { "tsl2561", 1 },
868 { "tsl2562", 2 },
869 { "tsl2563", 3 },
870 {}
871};
872MODULE_DEVICE_TABLE(i2c, tsl2563_id);
873
874static struct i2c_driver tsl2563_i2c_driver = {
875 .driver = {
876 .name = "tsl2563",
877 .pm = TSL2563_PM_OPS,
878 },
879 .probe = tsl2563_probe,
880 .remove = tsl2563_remove,
881 .id_table = tsl2563_id,
882};
883module_i2c_driver(tsl2563_i2c_driver);
884
885MODULE_AUTHOR("Nokia Corporation");
886MODULE_DESCRIPTION("tsl2563 light sensor driver");
887MODULE_LICENSE("GPL");