aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLuwei Zhou <b45643@freescale.com>2013-08-26 04:46:48 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:01:27 -0400
commit52b94dea6c3ba2e2f14a13be7adf481ab625a12f (patch)
treef80e6b043d0b8f220c0bc28ccf7bf5c41e037bce /drivers
parent45a22464aaee2569f9c26d90e46c9d99ea7ed774 (diff)
ENGR00276684-2 hwmon: isl29023: add isl29023 driver support
ISL29023 is an integrated ambient and infrared light to digital converter with I2C (SMBus Compatible) Interface. (Cherry-pick from freescale internal kernel 3.0.35_4.1.0 branch) Signed-off-by: Luwei Zhou <b45643@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rwxr-xr-xdrivers/input/misc/isl29023.c1029
3 files changed, 1040 insertions, 0 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index bb698e1f9e42..c807bc9f5d44 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -637,4 +637,14 @@ config INPUT_XEN_KBDDEV_FRONTEND
637 To compile this driver as a module, choose M here: the 637 To compile this driver as a module, choose M here: the
638 module will be called xen-kbdfront. 638 module will be called xen-kbdfront.
639 639
640config INPUT_ISL29023
641 tristate "Intersil ISL29023 ambient light sensor"
642 depends on I2C && SYSFS
643 help
644 If you say yes here you get support for the Intersil ISL29023
645 ambient light sensor.
646
647 This driver can also be built as a module. If so, the module
648 will be called isl29023.
649
640endif 650endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index d7fc17f11d77..d187cd5a813b 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -60,3 +60,4 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
60obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o 60obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
61obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o 61obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
62obj-$(CONFIG_INPUT_YEALINK) += yealink.o 62obj-$(CONFIG_INPUT_YEALINK) += yealink.o
63obj-$(CONFIG_INPUT_ISL29023) += isl29023.o
diff --git a/drivers/input/misc/isl29023.c b/drivers/input/misc/isl29023.c
new file mode 100755
index 000000000000..9bcea5e3dd3f
--- /dev/null
+++ b/drivers/input/misc/isl29023.c
@@ -0,0 +1,1029 @@
1/*
2 * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/i2c.h>
25#include <linux/input.h>
26#include <linux/interrupt.h>
27#include <linux/irq.h>
28#include <linux/mutex.h>
29#include <linux/delay.h>
30#include <linux/of.h>
31#include <linux/regulator/consumer.h>
32#include <linux/isl29023.h>
33
34#define ISL29023_DRV_NAME "isl29023"
35#define DRIVER_VERSION "1.0"
36
37#define ISL29023_COMMAND1 0x00
38#define ISL29023_MODE_SHIFT (5)
39#define ISL29023_MODE_MASK (0x7 << ISL29023_MODE_SHIFT)
40#define ISL29023_INT_FLAG_SHIFT (2)
41#define ISL29023_INT_FLAG_MASK (0x1 << ISL29023_INT_FLAG_SHIFT)
42#define ISL29023_INT_PERSISTS_SHIFT (0)
43#define ISL29023_INT_PERSISTS_MASK (0x3 << ISL29023_INT_PERSISTS_SHIFT)
44
45#define ISL29023_COMMAND2 0x01
46#define ISL29023_RES_SHIFT (2)
47#define ISL29023_RES_MASK (0x3 << ISL29023_RES_SHIFT)
48#define ISL29023_RANGE_SHIFT (0)
49#define ISL29023_RANGE_MASK (0x3 << ISL29023_RANGE_SHIFT)
50
51#define ISL29023_REG_LSB_SENSOR 0x02
52#define ISL29023_REG_MSB_SENSOR 0x03
53#define ISL29023_REG_IRQ_TH_LO_LSB 0x04
54#define ISL29023_REG_IRQ_TH_LO_MSB 0x05
55#define ISL29023_REG_IRQ_TH_HI_LSB 0x06
56#define ISL29023_REG_IRQ_TH_HI_MSB 0x07
57
58#define ISL29023_NUM_CACHABLE_REGS 8
59#define DEF_RANGE 2
60#define DEFAULT_REGISTOR_VAL 499
61
62struct isl29023_data {
63 struct i2c_client *client;
64 struct mutex lock;
65 struct input_dev *input;
66 struct work_struct work;
67 struct workqueue_struct *workqueue;
68 char phys[32];
69 u8 reg_cache[ISL29023_NUM_CACHABLE_REGS];
70 u8 mode_before_suspend;
71 u8 mode_before_interrupt;
72 u16 rext;
73};
74
75static int gain_range[] = {
76 1000, 4000, 16000, 64000
77};
78
79/*
80 * register access helpers
81 */
82static int __isl29023_read_reg(struct i2c_client *client,
83 u32 reg, u8 mask, u8 shift)
84{
85 struct isl29023_data *data = i2c_get_clientdata(client);
86 return (data->reg_cache[reg] & mask) >> shift;
87}
88
89static int __isl29023_write_reg(struct i2c_client *client,
90 u32 reg, u8 mask, u8 shift, u8 val)
91{
92 struct isl29023_data *data = i2c_get_clientdata(client);
93 int ret = 0;
94 u8 tmp;
95
96 if (reg >= ISL29023_NUM_CACHABLE_REGS)
97 return -EINVAL;
98
99 mutex_lock(&data->lock);
100
101 tmp = data->reg_cache[reg];
102 tmp &= ~mask;
103 tmp |= val << shift;
104
105 ret = i2c_smbus_write_byte_data(client, reg, tmp);
106 if (!ret)
107 data->reg_cache[reg] = tmp;
108
109 mutex_unlock(&data->lock);
110 return ret;
111}
112
113/*
114 * internally used functions
115 */
116
117/* interrupt persists */
118static int isl29023_get_int_persists(struct i2c_client *client)
119{
120 return __isl29023_read_reg(client, ISL29023_COMMAND1,
121 ISL29023_INT_PERSISTS_MASK, ISL29023_INT_PERSISTS_SHIFT);
122}
123
124static int isl29023_set_int_persists(struct i2c_client *client,
125 int int_persists)
126{
127 return __isl29023_write_reg(client, ISL29023_COMMAND1,
128 ISL29023_INT_PERSISTS_MASK, ISL29023_INT_PERSISTS_SHIFT,
129 int_persists);
130}
131
132/* interrupt flag */
133static int isl29023_get_int_flag(struct i2c_client *client)
134{
135 return __isl29023_read_reg(client, ISL29023_COMMAND1,
136 ISL29023_INT_FLAG_MASK, ISL29023_INT_FLAG_SHIFT);
137}
138
139static int isl29023_set_int_flag(struct i2c_client *client, int flag)
140{
141 return __isl29023_write_reg(client, ISL29023_COMMAND1,
142 ISL29023_INT_FLAG_MASK, ISL29023_INT_FLAG_SHIFT, flag);
143}
144
145/* interrupt lt */
146static int isl29023_get_int_lt(struct i2c_client *client)
147{
148 struct isl29023_data *data = i2c_get_clientdata(client);
149 int lsb, msb, lt;
150
151 mutex_lock(&data->lock);
152 lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB);
153
154 if (lsb < 0) {
155 mutex_unlock(&data->lock);
156 return lsb;
157 }
158
159 msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB);
160 mutex_unlock(&data->lock);
161
162 if (msb < 0)
163 return msb;
164
165 lt = ((msb << 8) | lsb);
166
167 return lt;
168}
169
170static int isl29023_set_int_lt(struct i2c_client *client, int lt)
171{
172 int ret = 0;
173 struct isl29023_data *data = i2c_get_clientdata(client);
174
175 mutex_lock(&data->lock);
176 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB,
177 lt & 0xff);
178 if (ret < 0) {
179 mutex_unlock(&data->lock);
180 return ret;
181 }
182
183 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB,
184 (lt >> 8) & 0xff);
185 if (ret < 0) {
186 mutex_unlock(&data->lock);
187 return ret;
188 }
189
190 data->reg_cache[ISL29023_REG_IRQ_TH_LO_MSB] = (lt >> 8) & 0xff;
191 data->reg_cache[ISL29023_REG_IRQ_TH_LO_LSB] = lt & 0xff;
192 mutex_unlock(&data->lock);
193
194 return ret;
195}
196
197/* interrupt ht */
198static int isl29023_get_int_ht(struct i2c_client *client)
199{
200 struct isl29023_data *data = i2c_get_clientdata(client);
201 int lsb, msb, ht;
202
203 mutex_lock(&data->lock);
204 lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB);
205
206 if (lsb < 0) {
207 mutex_unlock(&data->lock);
208 return lsb;
209 }
210
211 msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB);
212 mutex_unlock(&data->lock);
213
214 if (msb < 0)
215 return msb;
216
217 ht = ((msb << 8) | lsb);
218
219 return ht;
220}
221
222static int isl29023_set_int_ht(struct i2c_client *client, int ht)
223{
224 int ret = 0;
225 struct isl29023_data *data = i2c_get_clientdata(client);
226
227 mutex_lock(&data->lock);
228 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB,
229 ht & 0xff);
230 if (ret < 0) {
231 mutex_unlock(&data->lock);
232 return ret;
233 }
234
235 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB,
236 (ht >> 8) & 0xff);
237 if (ret < 0) {
238 mutex_unlock(&data->lock);
239 return ret;
240 }
241
242 data->reg_cache[ISL29023_REG_IRQ_TH_HI_MSB] = (ht >> 8) & 0xff;
243 data->reg_cache[ISL29023_REG_IRQ_TH_HI_LSB] = ht & 0xff;
244 mutex_unlock(&data->lock);
245
246 return ret;
247}
248
249/* range */
250static int isl29023_get_range(struct i2c_client *client)
251{
252 return __isl29023_read_reg(client, ISL29023_COMMAND2,
253 ISL29023_RANGE_MASK, ISL29023_RANGE_SHIFT);
254}
255
256static int isl29023_set_range(struct i2c_client *client, int range)
257{
258 return __isl29023_write_reg(client, ISL29023_COMMAND2,
259 ISL29023_RANGE_MASK, ISL29023_RANGE_SHIFT, range);
260}
261
262/* resolution */
263static int isl29023_get_resolution(struct i2c_client *client)
264{
265 return __isl29023_read_reg(client, ISL29023_COMMAND2,
266 ISL29023_RES_MASK, ISL29023_RES_SHIFT);
267}
268
269static int isl29023_set_resolution(struct i2c_client *client, int res)
270{
271 return __isl29023_write_reg(client, ISL29023_COMMAND2,
272 ISL29023_RES_MASK, ISL29023_RES_SHIFT, res);
273}
274
275/* mode */
276static int isl29023_get_mode(struct i2c_client *client)
277{
278 return __isl29023_read_reg(client, ISL29023_COMMAND1,
279 ISL29023_MODE_MASK, ISL29023_MODE_SHIFT);
280}
281
282static int isl29023_set_mode(struct i2c_client *client, int mode)
283{
284 return __isl29023_write_reg(client, ISL29023_COMMAND1,
285 ISL29023_MODE_MASK, ISL29023_MODE_SHIFT, mode);
286}
287
288/* power_state */
289static int isl29023_set_power_state(struct i2c_client *client, int state)
290{
291 return __isl29023_write_reg(client, ISL29023_COMMAND1,
292 ISL29023_MODE_MASK, ISL29023_MODE_SHIFT,
293 state ?
294 ISL29023_ALS_ONCE_MODE : ISL29023_PD_MODE);
295}
296
297static int isl29023_get_power_state(struct i2c_client *client)
298{
299 struct isl29023_data *data = i2c_get_clientdata(client);
300 u8 cmdreg = data->reg_cache[ISL29023_COMMAND1];
301
302 if (cmdreg & ISL29023_MODE_MASK)
303 return 1;
304 else
305 return 0;
306}
307
308static int isl29023_get_adc_value(struct i2c_client *client)
309{
310 struct isl29023_data *data = i2c_get_clientdata(client);
311 int lsb, msb, range, bitdepth;
312
313 mutex_lock(&data->lock);
314 lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_LSB_SENSOR);
315
316 if (lsb < 0) {
317 mutex_unlock(&data->lock);
318 return lsb;
319 }
320
321 msb = i2c_smbus_read_byte_data(client, ISL29023_REG_MSB_SENSOR);
322 mutex_unlock(&data->lock);
323
324 if (msb < 0)
325 return msb;
326
327 range = isl29023_get_range(client);
328 bitdepth = (4 - isl29023_get_resolution(client)) * 4;
329 return (((msb << 8) | lsb) * ((gain_range[range] * 499) / data->rext))
330 >> bitdepth;
331}
332
333static int isl29023_get_int_lt_value(struct i2c_client *client)
334{
335 struct isl29023_data *data = i2c_get_clientdata(client);
336 int lsb, msb, range, bitdepth;
337
338 mutex_lock(&data->lock);
339 lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB);
340
341 if (lsb < 0) {
342 mutex_unlock(&data->lock);
343 return lsb;
344 }
345
346 msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB);
347 mutex_unlock(&data->lock);
348
349 if (msb < 0)
350 return msb;
351
352 range = isl29023_get_range(client);
353 bitdepth = (4 - isl29023_get_resolution(client)) * 4;
354 return (((msb << 8) | lsb) * ((gain_range[range] * 499) / data->rext))
355 >> bitdepth;
356}
357
358static int isl29023_get_int_ht_value(struct i2c_client *client)
359{
360 struct isl29023_data *data = i2c_get_clientdata(client);
361 int lsb, msb, range, bitdepth;
362
363 mutex_lock(&data->lock);
364 lsb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB);
365
366 if (lsb < 0) {
367 mutex_unlock(&data->lock);
368 return lsb;
369 }
370
371 msb = i2c_smbus_read_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB);
372 mutex_unlock(&data->lock);
373
374 if (msb < 0)
375 return msb;
376
377 range = isl29023_get_range(client);
378 bitdepth = (4 - isl29023_get_resolution(client)) * 4;
379 return (((msb << 8) | lsb) * ((gain_range[range] * 499) / data->rext))
380 >> bitdepth;
381}
382
383/*
384 * sysfs layer
385 */
386
387/* interrupt persists */
388static ssize_t isl29023_show_int_persists(struct device *dev,
389 struct device_attribute *attr,
390 char *buf)
391{
392 struct i2c_client *client = to_i2c_client(dev);
393 return sprintf(buf, "%i\n", isl29023_get_int_persists(client));
394}
395
396static ssize_t isl29023_store_int_persists(struct device *dev,
397 struct device_attribute *attr,
398 const char *buf, size_t count)
399{
400 struct i2c_client *client = to_i2c_client(dev);
401 unsigned long val;
402 int ret;
403
404 if ((strict_strtoul(buf, 10, &val) < 0) ||
405 (val > ISL29023_INT_PERSISTS_16))
406 return -EINVAL;
407
408 ret = isl29023_set_int_persists(client, val);
409 if (ret < 0)
410 return ret;
411
412 return count;
413}
414
415static DEVICE_ATTR(int_persists, S_IWUSR | S_IRUGO,
416 isl29023_show_int_persists, isl29023_store_int_persists);
417
418/* interrupt flag */
419static ssize_t isl29023_show_int_flag(struct device *dev,
420 struct device_attribute *attr,
421 char *buf)
422{
423 struct i2c_client *client = to_i2c_client(dev);
424 return sprintf(buf, "%i\n", isl29023_get_int_flag(client));
425}
426
427static ssize_t isl29023_store_int_flag(struct device *dev,
428 struct device_attribute *attr,
429 const char *buf, size_t count)
430{
431 struct i2c_client *client = to_i2c_client(dev);
432 unsigned long val;
433 int ret;
434
435 if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
436 return -EINVAL;
437
438 ret = isl29023_set_int_flag(client, val);
439 if (ret < 0)
440 return ret;
441
442 return count;
443}
444
445static DEVICE_ATTR(int_flag, S_IWUSR | S_IRUGO,
446 isl29023_show_int_flag, isl29023_store_int_flag);
447
448/* interrupt lt */
449static ssize_t isl29023_show_int_lt(struct device *dev,
450 struct device_attribute *attr, char *buf)
451{
452 struct i2c_client *client = to_i2c_client(dev);
453 return sprintf(buf, "%i\n", isl29023_get_int_lt(client));
454}
455
456static ssize_t isl29023_store_int_lt(struct device *dev,
457 struct device_attribute *attr,
458 const char *buf, size_t count)
459{
460 struct i2c_client *client = to_i2c_client(dev);
461 unsigned long val;
462 int ret;
463
464 if ((strict_strtoul(buf, 16, &val) < 0) || (val > 0xffff))
465 return -EINVAL;
466
467 ret = isl29023_set_int_lt(client, val);
468 if (ret < 0)
469 return ret;
470
471 return count;
472}
473
474static DEVICE_ATTR(int_lt, S_IWUSR | S_IRUGO,
475 isl29023_show_int_lt, isl29023_store_int_lt);
476
477/* interrupt ht */
478static ssize_t isl29023_show_int_ht(struct device *dev,
479 struct device_attribute *attr, char *buf)
480{
481 struct i2c_client *client = to_i2c_client(dev);
482 return sprintf(buf, "%i\n", isl29023_get_int_ht(client));
483}
484
485static ssize_t isl29023_store_int_ht(struct device *dev,
486 struct device_attribute *attr,
487 const char *buf, size_t count)
488{
489 struct i2c_client *client = to_i2c_client(dev);
490 unsigned long val;
491 int ret;
492
493 if ((strict_strtoul(buf, 16, &val) < 0) || (val > 0xffff))
494 return -EINVAL;
495
496 ret = isl29023_set_int_ht(client, val);
497 if (ret < 0)
498 return ret;
499
500 return count;
501}
502
503static DEVICE_ATTR(int_ht, S_IWUSR | S_IRUGO,
504 isl29023_show_int_ht, isl29023_store_int_ht);
505
506/* range */
507static ssize_t isl29023_show_range(struct device *dev,
508 struct device_attribute *attr, char *buf)
509{
510 struct i2c_client *client = to_i2c_client(dev);
511 return sprintf(buf, "%i\n", isl29023_get_range(client));
512}
513
514static ssize_t isl29023_store_range(struct device *dev,
515 struct device_attribute *attr,
516 const char *buf, size_t count)
517{
518 struct i2c_client *client = to_i2c_client(dev);
519 unsigned long val;
520 int ret;
521
522 if ((strict_strtoul(buf, 10, &val) < 0) || (val > ISL29023_RANGE_64K))
523 return -EINVAL;
524
525 ret = isl29023_set_range(client, val);
526 if (ret < 0)
527 return ret;
528
529 return count;
530}
531
532static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
533 isl29023_show_range, isl29023_store_range);
534
535
536/* resolution */
537static ssize_t isl29023_show_resolution(struct device *dev,
538 struct device_attribute *attr,
539 char *buf)
540{
541 struct i2c_client *client = to_i2c_client(dev);
542 return sprintf(buf, "%d\n", isl29023_get_resolution(client));
543}
544
545static ssize_t isl29023_store_resolution(struct device *dev,
546 struct device_attribute *attr,
547 const char *buf, size_t count)
548{
549 struct i2c_client *client = to_i2c_client(dev);
550 unsigned long val;
551 int ret;
552
553 if ((strict_strtoul(buf, 10, &val) < 0) || (val > ISL29023_RES_4))
554 return -EINVAL;
555
556 ret = isl29023_set_resolution(client, val);
557 if (ret < 0)
558 return ret;
559
560 return count;
561}
562
563static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
564 isl29023_show_resolution, isl29023_store_resolution);
565
566/* mode */
567static ssize_t isl29023_show_mode(struct device *dev,
568 struct device_attribute *attr, char *buf)
569{
570 struct i2c_client *client = to_i2c_client(dev);
571 return sprintf(buf, "%d\n", isl29023_get_mode(client));
572}
573
574static ssize_t isl29023_store_mode(struct device *dev,
575 struct device_attribute *attr, const char *buf, size_t count)
576{
577 struct i2c_client *client = to_i2c_client(dev);
578 unsigned long val;
579 int ret;
580
581 if ((strict_strtoul(buf, 10, &val) < 0) ||
582 (val > ISL29023_IR_CONT_MODE))
583 return -EINVAL;
584
585 ret = isl29023_set_mode(client, val);
586 if (ret < 0)
587 return ret;
588
589 return count;
590}
591
592static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
593 isl29023_show_mode, isl29023_store_mode);
594
595
596/* power state */
597static ssize_t isl29023_show_power_state(struct device *dev,
598 struct device_attribute *attr,
599 char *buf)
600{
601 struct i2c_client *client = to_i2c_client(dev);
602 return sprintf(buf, "%d\n", isl29023_get_power_state(client));
603}
604
605static ssize_t isl29023_store_power_state(struct device *dev,
606 struct device_attribute *attr,
607 const char *buf, size_t count)
608{
609 struct i2c_client *client = to_i2c_client(dev);
610 unsigned long val;
611 int ret;
612
613 if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
614 return -EINVAL;
615
616 ret = isl29023_set_power_state(client, val);
617 return ret ? ret : count;
618}
619
620static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
621 isl29023_show_power_state, isl29023_store_power_state);
622
623/* lux */
624static ssize_t isl29023_show_lux(struct device *dev,
625 struct device_attribute *attr, char *buf)
626{
627 struct i2c_client *client = to_i2c_client(dev);
628
629 /* No LUX data if not operational */
630 if (!isl29023_get_power_state(client))
631 return -EBUSY;
632
633 return sprintf(buf, "%d\n", isl29023_get_adc_value(client));
634}
635
636static DEVICE_ATTR(lux, S_IRUGO, isl29023_show_lux, NULL);
637
638/* lux interrupt low threshold */
639static ssize_t isl29023_show_int_lt_lux(struct device *dev,
640 struct device_attribute *attr, char *buf)
641{
642 struct i2c_client *client = to_i2c_client(dev);
643
644 /* No LUX data if not operational */
645 if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
646 isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
647 return -EIO;
648
649 return sprintf(buf, "%d\n", isl29023_get_int_lt_value(client));
650}
651
652static ssize_t isl29023_store_int_lt_lux(struct device *dev,
653 struct device_attribute *attr, const char *buf, size_t count)
654{
655 struct i2c_client *client = to_i2c_client(dev);
656 struct isl29023_data *data = i2c_get_clientdata(client);
657 unsigned long val, lux_data;
658 int range, bitdepth, ret;
659 u8 lsb, msb;
660
661 if ((strict_strtoul(buf, 10, &val) < 0))
662 return -EINVAL;
663
664 /* No LUX data if not operational */
665 if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
666 isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
667 return -EIO;
668
669 if (val > (gain_range[isl29023_get_range(client)]*499/data->rext))
670 return -EINVAL;
671
672 range = isl29023_get_range(client);
673 bitdepth = (4 - isl29023_get_resolution(client)) * 4;
674 lux_data = ((unsigned long)(val << bitdepth)) /
675 ((gain_range[range] * 499) / data->rext);
676 lux_data &= 0xffff;
677
678 msb = lux_data >> 8;
679 lsb = lux_data & 0xff;
680
681 mutex_lock(&data->lock);
682 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_LSB,
683 lsb);
684 if (ret < 0) {
685 mutex_unlock(&data->lock);
686 return ret;
687 }
688
689 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_LO_MSB,
690 msb);
691 if (ret < 0) {
692 mutex_unlock(&data->lock);
693 return ret;
694 }
695
696 data->reg_cache[ISL29023_REG_IRQ_TH_LO_MSB] = msb;
697 data->reg_cache[ISL29023_REG_IRQ_TH_LO_LSB] = lsb;
698 mutex_unlock(&data->lock);
699
700 return count;
701}
702
703static DEVICE_ATTR(int_lt_lux, S_IWUSR | S_IRUGO,
704 isl29023_show_int_lt_lux, isl29023_store_int_lt_lux);
705
706/* lux interrupt high threshold */
707static ssize_t isl29023_show_int_ht_lux(struct device *dev,
708 struct device_attribute *attr, char *buf)
709{
710 struct i2c_client *client = to_i2c_client(dev);
711
712 /* No LUX data if not operational */
713 if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
714 isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
715 return -EIO;
716
717 return sprintf(buf, "%d\n", isl29023_get_int_ht_value(client));
718}
719
720static ssize_t isl29023_store_int_ht_lux(struct device *dev,
721 struct device_attribute *attr, const char *buf, size_t count)
722{
723 struct i2c_client *client = to_i2c_client(dev);
724 struct isl29023_data *data = i2c_get_clientdata(client);
725 unsigned long val, lux_data;
726 int range, bitdepth, ret;
727 u8 lsb, msb;
728
729 if ((strict_strtoul(buf, 10, &val) < 0))
730 return -EINVAL;
731
732 /* No LUX data if not operational */
733 if (isl29023_get_mode(client) != ISL29023_ALS_ONCE_MODE &&
734 isl29023_get_mode(client) != ISL29023_ALS_CONT_MODE)
735 return -EIO;
736
737 if (val > (gain_range[isl29023_get_range(client)]*499/data->rext))
738 return -EINVAL;
739
740 range = isl29023_get_range(client);
741 bitdepth = (4 - isl29023_get_resolution(client)) * 4;
742 lux_data = ((unsigned long)(val << bitdepth)) /
743 ((gain_range[range] * 499) / data->rext);
744 lux_data &= 0xffff;
745
746 msb = lux_data >> 8;
747 lsb = lux_data & 0xff;
748
749 mutex_lock(&data->lock);
750 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_LSB,
751 lsb);
752 if (ret < 0) {
753 mutex_unlock(&data->lock);
754 return ret;
755 }
756
757 ret = i2c_smbus_write_byte_data(client, ISL29023_REG_IRQ_TH_HI_MSB,
758 msb);
759 if (ret < 0) {
760 mutex_unlock(&data->lock);
761 return ret;
762 }
763
764 data->reg_cache[ISL29023_REG_IRQ_TH_HI_MSB] = msb;
765 data->reg_cache[ISL29023_REG_IRQ_TH_HI_LSB] = lsb;
766 mutex_unlock(&data->lock);
767
768 return count;
769}
770
771static DEVICE_ATTR(int_ht_lux, S_IWUSR | S_IRUGO,
772 isl29023_show_int_ht_lux, isl29023_store_int_ht_lux);
773
774static struct attribute *isl29023_attributes[] = {
775 &dev_attr_int_persists.attr,
776 &dev_attr_range.attr,
777 &dev_attr_resolution.attr,
778 &dev_attr_mode.attr,
779 &dev_attr_power_state.attr,
780 &dev_attr_lux.attr,
781 &dev_attr_int_lt_lux.attr,
782 &dev_attr_int_ht_lux.attr,
783 &dev_attr_int_lt.attr,
784 &dev_attr_int_ht.attr,
785 &dev_attr_int_flag.attr,
786 NULL
787};
788
789static const struct attribute_group isl29023_attr_group = {
790 .attrs = isl29023_attributes,
791};
792
793static int isl29023_init_client(struct i2c_client *client)
794{
795 struct isl29023_data *data = i2c_get_clientdata(client);
796 int i;
797
798 /* read all the registers once to fill the cache.
799 * if one of the reads fails, we consider the init failed */
800 for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
801 int v = i2c_smbus_read_byte_data(client, i);
802 if (v < 0)
803 return -ENODEV;
804
805 data->reg_cache[i] = v;
806 }
807
808 /* set defaults */
809 isl29023_set_int_persists(client, ISL29023_INT_PERSISTS_8);
810 isl29023_set_int_ht(client, 0xffff);
811 isl29023_set_int_lt(client, 0x0);
812 isl29023_set_range(client, ISL29023_RANGE_16K);
813 isl29023_set_resolution(client, ISL29023_RES_16);
814 isl29023_set_mode(client, ISL29023_ALS_ONCE_MODE);
815 isl29023_set_int_flag(client, 0);
816 isl29023_set_power_state(client, 0);
817
818 return 0;
819}
820
821static void isl29023_work(struct work_struct *work)
822{
823 struct isl29023_data *data =
824 container_of(work, struct isl29023_data, work);
825 struct i2c_client *client = data->client;
826 int lux;
827
828 /* Clear interrupt flag */
829 isl29023_set_int_flag(client, 0);
830
831 data->mode_before_interrupt = isl29023_get_mode(client);
832 lux = isl29023_get_adc_value(client);
833
834 /* To clear the interrpt status */
835 isl29023_set_power_state(client, ISL29023_PD_MODE);
836 isl29023_set_mode(client, data->mode_before_interrupt);
837
838 msleep(100);
839
840 input_report_abs(data->input, ABS_MISC, lux);
841 input_sync(data->input);
842}
843
844static irqreturn_t isl29023_irq_handler(int irq, void *handle)
845{
846 struct isl29023_data *data = handle;
847 queue_work(data->workqueue, &data->work);
848 return IRQ_HANDLED;
849}
850
851/*
852 * I2C layer
853 */
854
855static int isl29023_probe(struct i2c_client *client,
856 const struct i2c_device_id *id)
857{
858 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
859 struct isl29023_data *data;
860 struct input_dev *input_dev;
861 int err = 0;
862 struct regulator *vdd = NULL;
863 u32 rext = 0;
864 struct device_node *of_node = client->dev.of_node;
865
866 vdd = devm_regulator_get(&client->dev, "vdd");
867 if (!IS_ERR(vdd)) {
868 err = regulator_enable(vdd);
869 if (err) {
870 dev_err(&client->dev, "vdd set voltage error\n");
871 return err;
872 }
873 }
874
875 err = of_property_read_u32(of_node, "rext", &rext);
876 if (err)
877 rext = DEFAULT_REGISTOR_VAL;
878
879 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
880 return -EIO;
881
882 data = kzalloc(sizeof(struct isl29023_data), GFP_KERNEL);
883 if (!data)
884 return -ENOMEM;
885
886 data->client = client;
887 data->rext = (u16)rext;
888 snprintf(data->phys, sizeof(data->phys),
889 "%s", dev_name(&client->dev));
890 i2c_set_clientdata(client, data);
891 mutex_init(&data->lock);
892
893 /* initialize the ISL29023 chip */
894 err = isl29023_init_client(client);
895 if (err)
896 goto exit_kfree;
897
898 /* register sysfs hooks */
899 err = sysfs_create_group(&client->dev.kobj, &isl29023_attr_group);
900 if (err)
901 goto exit_kfree;
902
903 input_dev = input_allocate_device();
904 if (!input_dev) {
905 err = -ENOMEM;
906 goto exit_kfree;
907 }
908
909 data->input = input_dev;
910 input_dev->name = "isl29023 light sensor";
911 input_dev->id.bustype = BUS_I2C;
912 input_dev->phys = data->phys;
913
914 __set_bit(EV_ABS, input_dev->evbit);
915 input_set_abs_params(input_dev, ABS_MISC, 0,
916 gain_range[DEF_RANGE]*499/data->rext, 0, 0);
917
918 err = input_register_device(input_dev);
919 if (err)
920 goto exit_free_input;
921
922 /* set irq type to edge falling */
923 irq_set_irq_type(client->irq, IRQF_TRIGGER_FALLING);
924 err = request_irq(client->irq, isl29023_irq_handler, 0,
925 client->dev.driver->name, data);
926 if (err < 0) {
927 dev_err(&client->dev, "failed to register irq %d!\n",
928 client->irq);
929 goto exit_free_input;
930 }
931
932 data->workqueue = create_singlethread_workqueue("isl29023");
933 INIT_WORK(&data->work, isl29023_work);
934 if (data->workqueue == NULL) {
935 dev_err(&client->dev, "couldn't create workqueue\n");
936 err = -ENOMEM;
937 goto exit_free_interrupt;
938 }
939
940 dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
941 return 0;
942
943exit_free_interrupt:
944 free_irq(client->irq, data);
945exit_free_input:
946 input_free_device(input_dev);
947exit_kfree:
948 kfree(data);
949 return err;
950}
951
952static int isl29023_remove(struct i2c_client *client)
953{
954 struct isl29023_data *data = i2c_get_clientdata(client);
955
956 cancel_work_sync(&data->work);
957 destroy_workqueue(data->workqueue);
958 free_irq(client->irq, data);
959 input_unregister_device(data->input);
960 input_free_device(data->input);
961 sysfs_remove_group(&client->dev.kobj, &isl29023_attr_group);
962 isl29023_set_power_state(client, 0);
963 kfree(i2c_get_clientdata(client));
964
965 return 0;
966}
967
968#ifdef CONFIG_PM
969static int isl29023_suspend(struct i2c_client *client, pm_message_t mesg)
970{
971 struct isl29023_data *data = i2c_get_clientdata(client);
972
973 data->mode_before_suspend = isl29023_get_mode(client);
974 return isl29023_set_power_state(client, ISL29023_PD_MODE);
975}
976
977static int isl29023_resume(struct i2c_client *client)
978{
979 int i;
980 struct isl29023_data *data = i2c_get_clientdata(client);
981
982 /* restore registers from cache */
983 for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
984 if (i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
985 return -EIO;
986
987 return isl29023_set_mode(client, data->mode_before_suspend);
988}
989
990#else
991#define isl29023_suspend NULL
992#define isl29023_resume NULL
993#endif /* CONFIG_PM */
994
995static const struct i2c_device_id isl29023_id[] = {
996 { ISL29023_DRV_NAME, 0 },
997 {}
998};
999MODULE_DEVICE_TABLE(i2c, isl29023_id);
1000
1001static struct i2c_driver isl29023_driver = {
1002 .driver = {
1003 .name = ISL29023_DRV_NAME,
1004 .owner = THIS_MODULE,
1005 },
1006 .suspend = isl29023_suspend,
1007 .resume = isl29023_resume,
1008 .probe = isl29023_probe,
1009 .remove = isl29023_remove,
1010 .id_table = isl29023_id,
1011};
1012
1013static int __init isl29023_init(void)
1014{
1015 return i2c_add_driver(&isl29023_driver);
1016}
1017
1018static void __exit isl29023_exit(void)
1019{
1020 i2c_del_driver(&isl29023_driver);
1021}
1022
1023MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1024MODULE_DESCRIPTION("ISL29023 ambient light sensor driver");
1025MODULE_LICENSE("GPL");
1026MODULE_VERSION(DRIVER_VERSION);
1027
1028module_init(isl29023_init);
1029module_exit(isl29023_exit);