aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/cm3217.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/input/misc/cm3217.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/input/misc/cm3217.c')
-rw-r--r--drivers/input/misc/cm3217.c1081
1 files changed, 1081 insertions, 0 deletions
diff --git a/drivers/input/misc/cm3217.c b/drivers/input/misc/cm3217.c
new file mode 100644
index 00000000000..9c9b60d6961
--- /dev/null
+++ b/drivers/input/misc/cm3217.c
@@ -0,0 +1,1081 @@
1/* drivers/input/misc/cm3217.c - cm3217 optical sensors driver
2 *
3 * Copyright (C) 2011 Capella Microsystems Inc.
4 * Author: Frank Hsieh <pengyueh@gmail.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/delay.h>
18#include <linux/earlysuspend.h>
19#include <linux/i2c.h>
20#include <linux/input.h>
21#include <linux/interrupt.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/workqueue.h>
25#include <linux/irq.h>
26#include <linux/errno.h>
27#include <linux/err.h>
28#include <linux/gpio.h>
29#include <linux/miscdevice.h>
30#include <linux/lightsensor.h>
31#include <linux/slab.h>
32#include <linux/uaccess.h>
33#include <linux/cm3217.h>
34#include <linux/wakelock.h>
35#include <linux/jiffies.h>
36#include <asm/mach-types.h>
37#include <asm/setup.h>
38
39#define D(x...) pr_info(x)
40
41#define I2C_RETRY_COUNT 10
42
43#define LS_POLLING_DELAY 500
44
45static void report_do_work(struct work_struct *w);
46static DECLARE_DELAYED_WORK(report_work, report_do_work);
47
48struct cm3217_info {
49 struct class *cm3217_class;
50 struct device *ls_dev;
51 struct input_dev *ls_input_dev;
52
53 struct early_suspend early_suspend;
54 struct i2c_client *i2c_client;
55 struct workqueue_struct *lp_wq;
56
57 int als_enable;
58 int als_enabled_before_suspend;
59 uint16_t *adc_table;
60 uint16_t cali_table[10];
61 int irq;
62 int ls_calibrate;
63 int (*power) (int, uint8_t); /* power to the chip */
64
65 uint32_t als_kadc;
66 uint32_t als_gadc;
67 uint16_t golden_adc;
68
69 int lightsensor_opened;
70 int current_level;
71 uint16_t current_adc;
72 int polling_delay;
73};
74
75struct cm3217_info *lp_info;
76
77int enable_log;
78int fLevel = -1;
79
80static struct mutex als_enable_mutex, als_disable_mutex, als_get_adc_mutex;
81
82static int lightsensor_enable(struct cm3217_info *lpi);
83static int lightsensor_disable(struct cm3217_info *lpi);
84
85int32_t als_kadc;
86
87static int I2C_RxData(uint16_t slaveAddr, uint8_t *rxData, int length)
88{
89 uint8_t loop_i;
90
91 struct i2c_msg msgs[] = {
92 {
93 .addr = slaveAddr,
94 .flags = I2C_M_RD,
95 .len = length,
96 .buf = rxData,
97 },
98 };
99
100 for (loop_i = 0; loop_i < I2C_RETRY_COUNT; loop_i++) {
101 if (i2c_transfer(lp_info->i2c_client->adapter, msgs, 1) > 0)
102 break;
103 msleep(10);
104 }
105
106 if (loop_i >= I2C_RETRY_COUNT) {
107 printk(KERN_ERR "[ERR][CM3217 error] %s retry over %d\n",
108 __func__, I2C_RETRY_COUNT);
109 return -EIO;
110 }
111
112 return 0;
113}
114
115static int I2C_TxData(uint16_t slaveAddr, uint8_t *txData, int length)
116{
117 uint8_t loop_i;
118
119 struct i2c_msg msg[] = {
120 {
121 .addr = slaveAddr,
122 .flags = 0,
123 .len = length,
124 .buf = txData,
125 },
126 };
127
128 for (loop_i = 0; loop_i < I2C_RETRY_COUNT; loop_i++) {
129 if (i2c_transfer(lp_info->i2c_client->adapter, msg, 1) > 0)
130 break;
131 msleep(10);
132 }
133
134 if (loop_i >= I2C_RETRY_COUNT) {
135 printk(KERN_ERR "[ERR][CM3217 error] %s retry over %d\n",
136 __func__, I2C_RETRY_COUNT);
137 return -EIO;
138 }
139
140 return 0;
141}
142
143static int _cm3217_I2C_Read_Byte(uint16_t slaveAddr, uint8_t *pdata)
144{
145 uint8_t buffer = 0;
146 int ret = 0;
147
148 if (pdata == NULL)
149 return -EFAULT;
150
151 ret = I2C_RxData(slaveAddr, &buffer, 1);
152 if (ret < 0) {
153 pr_err("[ERR][CM3217 error]%s: I2C_RxData fail, slave addr: 0x%x\n",
154 __func__, slaveAddr);
155 return ret;
156 }
157
158 *pdata = buffer;
159
160#if 0
161 /* Debug use */
162 printk(KERN_DEBUG "[CM3217] %s: I2C_RxData[0x%x] = 0x%x\n",
163 __func__, slaveAddr, buffer);
164#endif
165
166 return ret;
167}
168
169static int _cm3217_I2C_Write_Byte(uint16_t SlaveAddress, uint8_t data)
170{
171 char buffer[2];
172 int ret = 0;
173
174#if 0
175 /* Debug use */
176 printk(KERN_DEBUG
177 "[CM3217] %s: _cm3217_I2C_Write_Byte[0x%x, 0x%x, 0x%x]\n",
178 __func__, SlaveAddress, cmd, data);
179#endif
180
181 buffer[0] = data;
182
183 ret = I2C_TxData(SlaveAddress, buffer, 1);
184 if (ret < 0) {
185 pr_err("[ERR][CM3217 error]%s: I2C_TxData fail\n", __func__);
186 return -EIO;
187 }
188
189 return ret;
190}
191
192static int get_ls_adc_value(uint16_t *als_step, bool resume)
193{
194 uint8_t lsb, msb;
195 int ret = 0;
196 struct cm3217_info *lpi = lp_info;
197
198 if (als_step == NULL)
199 return -EFAULT;
200
201 /* Read ALS data: LSB */
202 ret = _cm3217_I2C_Read_Byte(ALS_R_LSB_addr, &lsb);
203 if (ret < 0) {
204 pr_err("[LS][CM3217 error]%s: _cm3217_I2C_Read_Byte LSB fail\n",
205 __func__);
206 return -EIO;
207 }
208
209 /* Read ALS data: MSB */
210 ret = _cm3217_I2C_Read_Byte(ALS_R_MSB_addr, &msb);
211 if (ret < 0) {
212 pr_err("[LS][CM3217 error]%s: _cm3217_I2C_Read_Byte MSB fail\n",
213 __func__);
214 return -EIO;
215 }
216
217 *als_step = (uint16_t) msb;
218 *als_step <<= 8;
219 *als_step |= (uint16_t) lsb;
220
221 D("[LS][CM3217] %s: raw adc = 0x%X\n", __func__, *als_step);
222
223 if (!lpi->ls_calibrate) {
224 *als_step = (*als_step) * lpi->als_gadc / lpi->als_kadc;
225 if (*als_step > 0xFFFF)
226 *als_step = 0xFFFF;
227 }
228
229 return ret;
230}
231
232static void report_lsensor_input_event(struct cm3217_info *lpi, bool resume)
233{
234 uint16_t adc_value = 0;
235 int level = 0, i, ret = 0;
236
237 mutex_lock(&als_get_adc_mutex);
238
239 ret = get_ls_adc_value(&adc_value, resume);
240
241 if (lpi->ls_calibrate) {
242 for (i = 0; i < 10; i++) {
243 if (adc_value <= (*(lpi->cali_table + i))) {
244 level = i;
245 if (*(lpi->cali_table + i))
246 break;
247 }
248 /* avoid i = 10, because 'cali_table' of size is 10 */
249 if (i == 9) {
250 level = i;
251 break;
252 }
253 }
254 } else {
255 for (i = 0; i < 10; i++) {
256 if (adc_value <= (*(lpi->adc_table + i))) {
257 level = i;
258 if (*(lpi->adc_table + i))
259 break;
260 }
261 /* avoid i = 10, because 'cali_table' of size is 10 */
262 if (i == 9) {
263 level = i;
264 break;
265 }
266 }
267 }
268
269 if ((i == 0) || (adc_value == 0))
270 D("[LS][CM3217] %s: ADC=0x%03X, Level=%d, l_thd equal 0, "
271 "h_thd = 0x%x\n", __func__, adc_value, level,
272 *(lpi->cali_table + i));
273 else
274 D("[LS][CM3217] %s: ADC=0x%03X, Level=%d, l_thd = 0x%x, "
275 "h_thd = 0x%x\n", __func__, adc_value, level,
276 *(lpi->cali_table + (i - 1)) + 1, *(lpi->cali_table + i));
277
278 lpi->current_level = level;
279 lpi->current_adc = adc_value;
280
281 /*
282 D("[CM3217] %s: *(lpi->cali_table + (i - 1)) + 1 = 0x%X, "
283 "*(lpi->cali_table + i) = 0x%x\n", __func__,
284 *(lpi->cali_table + (i - 1)) + 1, *(lpi->cali_table + i));
285 */
286
287 if (fLevel >= 0) {
288 D("[LS][CM3217] L-sensor force level enable level=%d "
289 "fLevel=%d\n", level, fLevel);
290 level = fLevel;
291 }
292
293 input_report_abs(lpi->ls_input_dev, ABS_MISC, level);
294 input_sync(lpi->ls_input_dev);
295
296 mutex_unlock(&als_get_adc_mutex);
297}
298
299static void report_do_work(struct work_struct *work)
300{
301 struct cm3217_info *lpi = lp_info;
302
303 if (enable_log)
304 D("[CM3217] %s\n", __func__);
305
306 report_lsensor_input_event(lpi, 0);
307
308 queue_delayed_work(lpi->lp_wq, &report_work, lpi->polling_delay);
309}
310
311static int als_power(int enable)
312{
313 struct cm3217_info *lpi = lp_info;
314
315 if (lpi->power)
316 lpi->power(LS_PWR_ON, 1);
317
318 return 0;
319}
320
321void lightsensor_set_kvalue(struct cm3217_info *lpi)
322{
323 if (!lpi) {
324 pr_err("[LS][CM3217 error]%s: ls_info is empty\n", __func__);
325 return;
326 }
327
328 D("[LS][CM3217] %s: ALS calibrated als_kadc=0x%x\n",
329 __func__, als_kadc);
330
331 if (als_kadc >> 16 == ALS_CALIBRATED)
332 lpi->als_kadc = als_kadc & 0xFFFF;
333 else {
334 lpi->als_kadc = 0;
335 D("[LS][CM3217] %s: no ALS calibrated\n", __func__);
336 }
337
338 if (lpi->als_kadc && lpi->golden_adc > 0) {
339 lpi->als_kadc = (lpi->als_kadc > 0 && lpi->als_kadc < 0x1000) ?
340 lpi->als_kadc : lpi->golden_adc;
341 lpi->als_gadc = lpi->golden_adc;
342 } else {
343 lpi->als_kadc = 1;
344 lpi->als_gadc = 1;
345 }
346
347 D("[LS][CM3217] %s: als_kadc=0x%x, als_gadc=0x%x\n",
348 __func__, lpi->als_kadc, lpi->als_gadc);
349}
350
351static int lightsensor_update_table(struct cm3217_info *lpi)
352{
353 uint32_t tmpData[10];
354 int i;
355
356 for (i = 0; i < 10; i++) {
357 tmpData[i] = (uint32_t) (*(lpi->adc_table + i))
358 * lpi->als_kadc / lpi->als_gadc;
359 if (tmpData[i] <= 0xFFFF)
360 lpi->cali_table[i] = (uint16_t) tmpData[i];
361 else
362 lpi->cali_table[i] = 0xFFFF;
363 D("[LS][CM3217] %s: Calibrated adc_table: data[%d], %x\n",
364 __func__, i, lpi->cali_table[i]);
365 }
366
367 return 0;
368}
369
370static int lightsensor_enable(struct cm3217_info *lpi)
371{
372 int ret = 0;
373 uint8_t cmd = 0;
374
375 mutex_lock(&als_enable_mutex);
376
377 D("[LS][CM3217] %s\n", __func__);
378
379 cmd = (CM3217_ALS_IT_2_T | CM3217_ALS_BIT5_Default_1 |
380 CM3217_ALS_WDM_DEFAULT_1);
381 ret = _cm3217_I2C_Write_Byte(ALS_W_CMD1_addr, cmd);
382 if (ret < 0)
383 pr_err("[LS][CM3217 error]%s: set auto light sensor fail\n",
384 __func__);
385 else {
386 msleep(50); /* wait for 50 ms for the first report adc */
387
388 /* report an invalid value first to ensure we
389 * trigger an event when adc_level is zero.
390 */
391 input_report_abs(lpi->ls_input_dev, ABS_MISC, -1);
392 input_sync(lpi->ls_input_dev);
393 /* resume, IOCTL and DEVICE_ATTR */
394 report_lsensor_input_event(lpi, 1);
395 lpi->als_enable = 1;
396 }
397
398 queue_delayed_work(lpi->lp_wq, &report_work, lpi->polling_delay);
399 lpi->als_enable = 1;
400
401 mutex_unlock(&als_enable_mutex);
402
403 return ret;
404}
405
406static int lightsensor_disable(struct cm3217_info *lpi)
407{
408 int ret = 0;
409 char cmd = 0;
410
411 mutex_lock(&als_disable_mutex);
412
413 D("[LS][CM3217] %s\n", __func__);
414
415 cmd = (CM3217_ALS_IT_2_T | CM3217_ALS_BIT5_Default_1 |
416 CM3217_ALS_WDM_DEFAULT_1 | CM3217_ALS_SD);
417 ret = _cm3217_I2C_Write_Byte(ALS_W_CMD1_addr, cmd);
418 if (ret < 0)
419 pr_err("[LS][CM3217 error]%s: disable auto light sensor fail\n",
420 __func__);
421 else {
422 lpi->als_enable = 0;
423 }
424
425 cancel_delayed_work(&report_work);
426 lpi->als_enable = 0;
427
428 mutex_unlock(&als_disable_mutex);
429
430 return ret;
431}
432
433static int lightsensor_open(struct inode *inode, struct file *file)
434{
435 struct cm3217_info *lpi = lp_info;
436 int rc = 0;
437
438 D("[LS][CM3217] %s\n", __func__);
439 if (lpi->lightsensor_opened) {
440 pr_err("[LS][CM3217 error]%s: already opened\n", __func__);
441 rc = -EBUSY;
442 }
443 lpi->lightsensor_opened = 1;
444
445 return rc;
446}
447
448static int lightsensor_release(struct inode *inode, struct file *file)
449{
450 struct cm3217_info *lpi = lp_info;
451
452 D("[LS][CM3217] %s\n", __func__);
453 lpi->lightsensor_opened = 0;
454
455 return 0;
456}
457
458static long lightsensor_ioctl(struct file *file, unsigned int cmd,
459 unsigned long arg)
460{
461 int rc, val;
462 struct cm3217_info *lpi = lp_info;
463
464 /* D("[CM3217] %s cmd %d\n", __func__, _IOC_NR(cmd)); */
465
466 switch (cmd) {
467 case LIGHTSENSOR_IOCTL_ENABLE:
468 if (get_user(val, (unsigned long __user *)arg)) {
469 rc = -EFAULT;
470 break;
471 }
472 D("[LS][CM3217] %s LIGHTSENSOR_IOCTL_ENABLE, value = %d\n",
473 __func__, val);
474 rc = val ? lightsensor_enable(lpi) : lightsensor_disable(lpi);
475 break;
476
477 case LIGHTSENSOR_IOCTL_GET_ENABLED:
478 val = lpi->als_enable;
479 D("[LS][CM3217] %s LIGHTSENSOR_IOCTL_GET_ENABLED, enabled %d\n",
480 __func__, val);
481 rc = put_user(val, (unsigned long __user *)arg);
482 break;
483
484 default:
485 pr_err("[LS][CM3217 error]%s: invalid cmd %d\n",
486 __func__, _IOC_NR(cmd));
487 rc = -EINVAL;
488 }
489
490 return rc;
491}
492
493static const struct file_operations lightsensor_fops = {
494 .owner = THIS_MODULE,
495 .open = lightsensor_open,
496 .release = lightsensor_release,
497 .unlocked_ioctl = lightsensor_ioctl
498};
499
500static struct miscdevice lightsensor_misc = {
501 .minor = MISC_DYNAMIC_MINOR,
502 .name = "lightsensor",
503 .fops = &lightsensor_fops
504};
505
506static ssize_t ls_adc_show(struct device *dev,
507 struct device_attribute *attr, char *buf)
508{
509 int ret;
510 struct cm3217_info *lpi = lp_info;
511
512 D("[LS][CM3217] %s: ADC = 0x%04X, Level = %d\n",
513 __func__, lpi->current_adc, lpi->current_level);
514
515 ret = sprintf(buf, "ADC[0x%04X] => level %d\n",
516 lpi->current_adc, lpi->current_level);
517
518 return ret;
519}
520
521static DEVICE_ATTR(ls_adc, 0664, ls_adc_show, NULL);
522
523static ssize_t ls_enable_show(struct device *dev,
524 struct device_attribute *attr, char *buf)
525{
526 int ret = 0;
527 struct cm3217_info *lpi = lp_info;
528
529 ret = sprintf(buf, "Light sensor Auto Enable = %d\n", lpi->als_enable);
530
531 return ret;
532}
533
534static ssize_t ls_enable_store(struct device *dev,
535 struct device_attribute *attr,
536 const char *buf, size_t count)
537{
538 int ret = 0;
539 int ls_auto;
540 struct cm3217_info *lpi = lp_info;
541
542 ls_auto = -1;
543 sscanf(buf, "%d", &ls_auto);
544
545 if (ls_auto != 0 && ls_auto != 1)
546 return -EINVAL;
547
548 if (ls_auto)
549 ret = lightsensor_enable(lpi);
550 else
551 ret = lightsensor_disable(lpi);
552
553 D("[LS][CM3217] %s: lpi->als_enable = %d, lpi->ls_calibrate = %d, "
554 "ls_auto=%d\n", __func__, lpi->als_enable, lpi->ls_calibrate,
555 ls_auto);
556
557 if (ret < 0)
558 pr_err("[LS][CM3217 error]%s: set auto light sensor fail\n",
559 __func__);
560
561 return count;
562}
563
564static DEVICE_ATTR(ls_auto, 0664, ls_enable_show, ls_enable_store);
565
566static ssize_t ls_kadc_show(struct device *dev,
567 struct device_attribute *attr, char *buf)
568{
569 struct cm3217_info *lpi = lp_info;
570 int ret;
571
572 ret = sprintf(buf, "kadc = 0x%x", lpi->als_kadc);
573
574 return ret;
575}
576
577static ssize_t ls_kadc_store(struct device *dev,
578 struct device_attribute *attr,
579 const char *buf, size_t count)
580{
581 struct cm3217_info *lpi = lp_info;
582 int kadc_temp = 0;
583
584 sscanf(buf, "%d", &kadc_temp);
585
586 /* if (kadc_temp <= 0 || lpi->golden_adc <= 0) {
587 printk(KERN_ERR "[LS][CM3217 error] %s: kadc_temp=0x%x, "
588 "als_gadc=0x%x\n", __func__, kadc_temp,
589 lpi->golden_adc);
590 return -EINVAL;
591 } */
592
593 mutex_lock(&als_get_adc_mutex);
594
595 if (kadc_temp != 0) {
596 lpi->als_kadc = kadc_temp;
597 if (lpi->als_gadc != 0) {
598 if (lightsensor_update_table(lpi) < 0)
599 printk(KERN_ERR
600 "[LS][CM3217 error] %s: "
601 "update ls table fail\n", __func__);
602 } else {
603 printk(KERN_INFO
604 "[LS]%s: als_gadc =0x%x wait to be set\n",
605 __func__, lpi->als_gadc);
606 }
607 } else {
608 printk(KERN_INFO "[LS]%s: als_kadc can't be set to zero\n",
609 __func__);
610 }
611
612 mutex_unlock(&als_get_adc_mutex);
613
614 return count;
615}
616
617static DEVICE_ATTR(ls_kadc, 0664, ls_kadc_show, ls_kadc_store);
618
619static ssize_t ls_gadc_show(struct device *dev,
620 struct device_attribute *attr, char *buf)
621{
622 struct cm3217_info *lpi = lp_info;
623 int ret;
624
625 ret = sprintf(buf, "gadc = 0x%x\n", lpi->als_gadc);
626
627 return ret;
628}
629
630static ssize_t ls_gadc_store(struct device *dev,
631 struct device_attribute *attr,
632 const char *buf, size_t count)
633{
634 struct cm3217_info *lpi = lp_info;
635 int gadc_temp = 0;
636
637 sscanf(buf, "%d", &gadc_temp);
638
639 /* if (gadc_temp <= 0 || lpi->golden_adc <= 0) {
640 printk(KERN_ERR "[LS][CM3217 error] %s: kadc_temp=0x%x, "
641 "als_gadc=0x%x\n", __func__, kadc_temp,
642 lpi->golden_adc);
643 return -EINVAL;
644 } */
645
646 mutex_lock(&als_get_adc_mutex);
647
648 if (gadc_temp != 0) {
649 lpi->als_gadc = gadc_temp;
650 if (lpi->als_kadc != 0) {
651 if (lightsensor_update_table(lpi) < 0)
652 printk(KERN_ERR
653 "[LS][CM3217 error] %s: "
654 "update ls table fail\n", __func__);
655 } else {
656 printk(KERN_INFO
657 "[LS]%s: als_kadc =0x%x wait to be set\n",
658 __func__, lpi->als_kadc);
659 }
660 } else {
661 printk(KERN_INFO "[LS]%s: als_gadc can't be set to zero\n",
662 __func__);
663 }
664
665 mutex_unlock(&als_get_adc_mutex);
666
667 return count;
668}
669
670static DEVICE_ATTR(ls_gadc, 0664, ls_gadc_show, ls_gadc_store);
671
672static ssize_t ls_adc_table_show(struct device *dev,
673 struct device_attribute *attr, char *buf)
674{
675 unsigned length = 0;
676 int i;
677
678 for (i = 0; i < 10; i++) {
679 length += sprintf(buf + length,
680 "[CM3217]Get adc_table[%d] = 0x%x ; %d, "
681 "Get cali_table[%d] = 0x%x ; %d,\n",
682 i, *(lp_info->adc_table + i),
683 *(lp_info->adc_table + i),
684 i, *(lp_info->cali_table + i),
685 *(lp_info->cali_table + i));
686 }
687
688 return length;
689}
690
691static ssize_t ls_adc_table_store(struct device *dev,
692 struct device_attribute *attr,
693 const char *buf, size_t count)
694{
695 struct cm3217_info *lpi = lp_info;
696 char *token[10];
697 unsigned long tempdata[10];
698 int i, r;
699
700 printk(KERN_INFO "[LS][CM3217]%s\n", buf);
701 for (i = 0; i < 10; i++) {
702 token[i] = strsep((char **)&buf, " ");
703 r = kstrtoul(token[i], 16, &tempdata[i]);
704 if (tempdata[i] < 1 || tempdata[i] > 0xffff || r) {
705 printk(KERN_ERR
706 "[LS][CM3217 error] adc_table[%d] = "
707 "0x%lx Err\n", i, tempdata[i]);
708 return count;
709 }
710 }
711
712 mutex_lock(&als_get_adc_mutex);
713
714 for (i = 0; i < 10; i++) {
715 lpi->adc_table[i] = tempdata[i];
716 printk(KERN_INFO
717 "[LS][CM3217]Set lpi->adc_table[%d] = 0x%x\n",
718 i, *(lp_info->adc_table + i));
719 }
720 if (lightsensor_update_table(lpi) < 0)
721 printk(KERN_ERR "[LS][CM3217 error] %s: update ls table fail\n",
722 __func__);
723
724 mutex_unlock(&als_get_adc_mutex);
725
726 D("[LS][CM3217] %s\n", __func__);
727
728 return count;
729}
730
731static DEVICE_ATTR(ls_adc_table, 0664, ls_adc_table_show, ls_adc_table_store);
732
733static uint8_t ALS_CONF1;
734
735static ssize_t ls_conf1_show(struct device *dev,
736 struct device_attribute *attr, char *buf)
737{
738 return sprintf(buf, "ALS_CONF1 = %x\n", ALS_CONF1);
739}
740
741static ssize_t ls_conf1_store(struct device *dev,
742 struct device_attribute *attr,
743 const char *buf, size_t count)
744{
745 int value = 0;
746
747 sscanf(buf, "0x%x", &value);
748
749 ALS_CONF1 = value;
750 printk(KERN_INFO "[LS]set ALS_CONF1 = %x\n", ALS_CONF1);
751 _cm3217_I2C_Write_Byte(ALS_W_CMD1_addr, ALS_CONF1);
752
753 return count;
754}
755
756static DEVICE_ATTR(ls_conf1, 0664, ls_conf1_show, ls_conf1_store);
757
758static uint8_t ALS_CONF2;
759static ssize_t ls_conf2_show(struct device *dev,
760 struct device_attribute *attr, char *buf)
761{
762 return sprintf(buf, "ALS_CONF2 = %x\n", ALS_CONF2);
763}
764
765static ssize_t ls_conf2_store(struct device *dev,
766 struct device_attribute *attr,
767 const char *buf, size_t count)
768{
769 int value = 0;
770
771 sscanf(buf, "0x%x", &value);
772
773 ALS_CONF2 = value;
774 printk(KERN_INFO "[LS]set ALS_CONF2 = %x\n", ALS_CONF2);
775 _cm3217_I2C_Write_Byte(ALS_W_CMD2_addr, ALS_CONF2);
776
777 return count;
778}
779
780static DEVICE_ATTR(ls_conf2, 0664, ls_conf2_show, ls_conf2_store);
781
782static ssize_t ls_fLevel_show(struct device *dev,
783 struct device_attribute *attr, char *buf)
784{
785 return sprintf(buf, "fLevel = %d\n", fLevel);
786}
787
788static ssize_t ls_fLevel_store(struct device *dev,
789 struct device_attribute *attr,
790 const char *buf, size_t count)
791{
792 struct cm3217_info *lpi = lp_info;
793 int value = 0;
794
795 sscanf(buf, "%d", &value);
796 (value >= 0) ? (value = min(value, 10)) : (value = max(value, -1));
797 fLevel = value;
798
799 input_report_abs(lpi->ls_input_dev, ABS_MISC, fLevel);
800 input_sync(lpi->ls_input_dev);
801
802 printk(KERN_INFO "[LS]set fLevel = %d\n", fLevel);
803
804 msleep(1000);
805 fLevel = -1;
806
807 return count;
808}
809
810static DEVICE_ATTR(ls_flevel, 0664, ls_fLevel_show, ls_fLevel_store);
811
812static int lightsensor_setup(struct cm3217_info *lpi)
813{
814 int ret;
815
816 lpi->ls_input_dev = input_allocate_device();
817 if (!lpi->ls_input_dev) {
818 pr_err("[LS][CM3217 error]%s: "
819 "could not allocate ls input device\n", __func__);
820 return -ENOMEM;
821 }
822 lpi->ls_input_dev->name = "cm3217-ls";
823 set_bit(EV_ABS, lpi->ls_input_dev->evbit);
824 input_set_abs_params(lpi->ls_input_dev, ABS_MISC, 0, 9, 0, 0);
825
826 ret = input_register_device(lpi->ls_input_dev);
827 if (ret < 0) {
828 pr_err("[LS][CM3217 error]%s: "
829 "can not register ls input device\n", __func__);
830 goto err_free_ls_input_device;
831 }
832
833 ret = misc_register(&lightsensor_misc);
834 if (ret < 0) {
835 pr_err("[LS][CM3217 error]%s: "
836 "can not register ls misc device\n", __func__);
837 goto err_unregister_ls_input_device;
838 }
839
840 return ret;
841
842err_unregister_ls_input_device:
843 input_unregister_device(lpi->ls_input_dev);
844err_free_ls_input_device:
845 input_free_device(lpi->ls_input_dev);
846 return ret;
847}
848
849static int cm3217_setup(struct cm3217_info *lpi)
850{
851 int ret = 0;
852
853 als_power(1);
854 msleep(5);
855
856 ret = _cm3217_I2C_Write_Byte(ALS_W_CMD2_addr,
857 CM3217_ALS_WDM_DEFAULT_1
858 | CM3217_ALS_IT_2_T
859 | CM3217_ALS_BIT5_Default_1);
860 if (ret < 0)
861 return ret;
862
863 ret = _cm3217_I2C_Write_Byte(ALS_W_CMD2_addr, CM3217_ALS_IT_100ms);
864 msleep(10);
865
866 return ret;
867}
868
869static void cm3217_early_suspend(struct early_suspend *h)
870{
871 struct cm3217_info *lpi = lp_info;
872
873 D("[LS][CM3217] %s\n", __func__);
874
875 lpi->als_enabled_before_suspend = lpi->als_enable;
876 if (lpi->als_enable)
877 lightsensor_disable(lpi);
878}
879
880static void cm3217_late_resume(struct early_suspend *h)
881{
882 struct cm3217_info *lpi = lp_info;
883
884 D("[LS][CM3217] %s\n", __func__);
885
886 if (lpi->als_enabled_before_suspend)
887 lightsensor_enable(lpi);
888}
889
890static int cm3217_probe(struct i2c_client *client,
891 const struct i2c_device_id *id)
892{
893 int ret = 0;
894 struct cm3217_info *lpi;
895 struct cm3217_platform_data *pdata;
896
897 D("[CM3217] %s\n", __func__);
898
899 lpi = kzalloc(sizeof(struct cm3217_info), GFP_KERNEL);
900 if (!lpi)
901 return -ENOMEM;
902
903 /* D("[CM3217] %s: client->irq = %d\n", __func__, client->irq); */
904
905 lpi->i2c_client = client;
906 pdata = client->dev.platform_data;
907 if (!pdata) {
908 pr_err("[CM3217 error]%s: Assign platform_data error!!\n",
909 __func__);
910 ret = -EBUSY;
911 goto err_platform_data_null;
912 }
913
914 lpi->irq = client->irq;
915
916 i2c_set_clientdata(client, lpi);
917 lpi->adc_table = pdata->levels;
918 lpi->golden_adc = pdata->golden_adc;
919 lpi->power = pdata->power;
920
921 lpi->polling_delay = msecs_to_jiffies(LS_POLLING_DELAY);
922
923 lp_info = lpi;
924
925 mutex_init(&als_enable_mutex);
926 mutex_init(&als_disable_mutex);
927 mutex_init(&als_get_adc_mutex);
928
929 ret = lightsensor_setup(lpi);
930 if (ret < 0) {
931 pr_err("[LS][CM3217 error]%s: lightsensor_setup error!!\n",
932 __func__);
933 goto err_lightsensor_setup;
934 }
935
936 /* SET LUX STEP FACTOR HERE
937 * if adc raw value one step = 0.3 lux
938 * the following will set the factor 0.3 = 3/10
939 * and lpi->golden_adc = 3;
940 * set als_kadc = (ALS_CALIBRATED <<16) | 10; */
941
942 als_kadc = (ALS_CALIBRATED << 16) | 10;
943 lpi->golden_adc = 3;
944
945 /* ls calibrate always set to 1 */
946 lpi->ls_calibrate = 1;
947
948 lightsensor_set_kvalue(lpi);
949 ret = lightsensor_update_table(lpi);
950 if (ret < 0) {
951 pr_err("[LS][CM3217 error]%s: update ls table fail\n",
952 __func__);
953 goto err_lightsensor_update_table;
954 }
955
956 lpi->lp_wq = create_singlethread_workqueue("cm3217_wq");
957 if (!lpi->lp_wq) {
958 pr_err("[CM3217 error]%s: can't create workqueue\n", __func__);
959 ret = -ENOMEM;
960 goto err_create_singlethread_workqueue;
961 }
962
963 ret = cm3217_setup(lpi);
964 if (ret < 0) {
965 pr_err("[ERR][CM3217 error]%s: cm3217_setup error!\n",
966 __func__);
967 goto err_cm3217_setup;
968 }
969
970 lpi->cm3217_class = class_create(THIS_MODULE, "optical_sensors");
971 if (IS_ERR(lpi->cm3217_class)) {
972 ret = PTR_ERR(lpi->cm3217_class);
973 lpi->cm3217_class = NULL;
974 goto err_create_class;
975 }
976
977 lpi->ls_dev = device_create(lpi->cm3217_class,
978 NULL, 0, "%s", "lightsensor");
979 if (unlikely(IS_ERR(lpi->ls_dev))) {
980 ret = PTR_ERR(lpi->ls_dev);
981 lpi->ls_dev = NULL;
982 goto err_create_ls_device;
983 }
984
985 /* register the attributes */
986 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc);
987 if (ret)
988 goto err_create_ls_device_file;
989
990 /* register the attributes */
991 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_auto);
992 if (ret)
993 goto err_create_ls_device_file;
994
995 /* register the attributes */
996 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_kadc);
997 if (ret)
998 goto err_create_ls_device_file;
999
1000 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_gadc);
1001 if (ret)
1002 goto err_create_ls_device_file;
1003
1004 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc_table);
1005 if (ret)
1006 goto err_create_ls_device_file;
1007
1008 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_conf1);
1009 if (ret)
1010 goto err_create_ls_device_file;
1011
1012 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_conf2);
1013 if (ret)
1014 goto err_create_ls_device_file;
1015
1016 ret = device_create_file(lpi->ls_dev, &dev_attr_ls_flevel);
1017 if (ret)
1018 goto err_create_ls_device_file;
1019
1020 lpi->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
1021 lpi->early_suspend.suspend = cm3217_early_suspend;
1022 lpi->early_suspend.resume = cm3217_late_resume;
1023 register_early_suspend(&lpi->early_suspend);
1024
1025 lpi->als_enable = 0;
1026 lpi->als_enabled_before_suspend = 0;
1027 D("[CM3217] %s: Probe success!\n", __func__);
1028
1029 return ret;
1030
1031err_create_ls_device_file:
1032 device_unregister(lpi->ls_dev);
1033err_create_ls_device:
1034 class_destroy(lpi->cm3217_class);
1035err_create_class:
1036err_cm3217_setup:
1037 destroy_workqueue(lpi->lp_wq);
1038 mutex_destroy(&als_enable_mutex);
1039 mutex_destroy(&als_disable_mutex);
1040 mutex_destroy(&als_get_adc_mutex);
1041 input_unregister_device(lpi->ls_input_dev);
1042 input_free_device(lpi->ls_input_dev);
1043err_create_singlethread_workqueue:
1044err_lightsensor_update_table:
1045 misc_deregister(&lightsensor_misc);
1046err_lightsensor_setup:
1047err_platform_data_null:
1048 kfree(lpi);
1049 return ret;
1050}
1051
1052static const struct i2c_device_id cm3217_i2c_id[] = {
1053 {CM3217_I2C_NAME, 0},
1054 {}
1055};
1056
1057static struct i2c_driver cm3217_driver = {
1058 .id_table = cm3217_i2c_id,
1059 .probe = cm3217_probe,
1060 .driver = {
1061 .name = CM3217_I2C_NAME,
1062 .owner = THIS_MODULE,
1063 },
1064};
1065
1066static int __init cm3217_init(void)
1067{
1068 return i2c_add_driver(&cm3217_driver);
1069}
1070
1071static void __exit cm3217_exit(void)
1072{
1073 i2c_del_driver(&cm3217_driver);
1074}
1075
1076module_init(cm3217_init);
1077module_exit(cm3217_exit);
1078
1079MODULE_LICENSE("GPL");
1080MODULE_DESCRIPTION("CM3217 Driver");
1081MODULE_AUTHOR("Frank Hsieh <pengyueh@gmail.com>");