-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <mach/gpio.h>\r
-#include <mach/board.h> \r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-#include <linux/types.h>\r
-\r
-\r
-#define DRIVER_VERSION "1.0"\r
-\r
-#define PWR_MODE_DOWN_MASK 0x80\r
-#define PWR_MODE_OPERATE_MASK 0x7F\r
-\r
-\r
-/*us5152 Slave Addr*/\r
-#define LIGHT_ADDR 0x72 \r
-\r
-/*Interrupt PIN for S3C6410*/\r
-#define IRQ_LIGHT_INT IRQ_EINT(6)\r
-\r
-/*Register Set*/\r
-#define REGS_CR0 0x00\r
-#define REGS_CR1 0x01\r
-#define REGS_CR2 0x02\r
-#define REGS_CR3 0x03\r
-//ALS\r
-#define REGS_INT_LSB_TH_LO 0x04\r
-#define REGS_INT_MSB_TH_LO 0x05\r
-#define REGS_INT_LSB_TH_HI 0x06\r
-#define REGS_INT_MSB_TH_HI 0x07\r
-//ALS data\r
-#define REGS_LBS_SENSOR 0x0C\r
-#define REGS_MBS_SENSOR 0x0D\r
-\r
-#define REGS_CR10 0x10\r
-#define REGS_CR11 0x11\r
-#define REGS_VERSION_ID 0x1F\r
-#define REGS_CHIP_ID 0xB2\r
-\r
-/*ShutDown_EN*/\r
-#define CR0_OPERATION 0x0\r
-#define CR0_SHUTDOWN_EN 0x1\r
-\r
-#define CR0_SHUTDOWN_SHIFT (7)\r
-#define CR0_SHUTDOWN_MASK (0x1 << CR0_SHUTDOWN_SHIFT)\r
-\r
-/*OneShot_EN*/\r
-#define CR0_ONESHOT_EN 0x01\r
-\r
-#define CR0_ONESHOT_SHIFT (6)\r
-#define CR0_ONESHOT_MASK (0x1 << CR0_ONESHOT_SHIFT)\r
-\r
-/*Operation Mode*/\r
-#define CR0_OPMODE_ALSANDPS 0x0 \r
-#define CR0_OPMODE_ALSONLY 0x1 \r
-#define CR0_OPMODE_IRONLY 0x2 \r
-\r
-#define CR0_OPMODE_SHIFT (4)\r
-#define CR0_OPMODE_MASK (0x3 << CR0_OPMODE_SHIFT)\r
-\r
-/*all int flag (PROX, INT_A, INT_P)*/\r
-#define CR0_ALL_INT_CLEAR 0x0\r
-\r
-#define CR0_ALL_INT_SHIFT (1)\r
-#define CR0_ALL_INT_MASK (0x7 << CR0_ALL_INT_SHIFT)\r
-\r
-\r
-/*indicator of object proximity detection*/\r
-#define CR0_PROX_CLEAR 0x0\r
-\r
-#define CR0_PROX_SHIFT (3)\r
-#define CR0_PROX_MASK (0x1 << CR0_PROX_SHIFT)\r
-\r
-/*interrupt status of proximity sensor*/\r
-#define CR0_INTP_CLEAR 0x0\r
-\r
-#define CR0_INTP_SHIFT (2)\r
-#define CR0_INTP_MASK (0x1 << CR0_INTP_SHIFT)\r
-\r
-/*interrupt status of ambient sensor*/\r
-#define CR0_INTA_CLEAR 0x0\r
-\r
-#define CR0_INTA_SHIFT (1)\r
-#define CR0_INTA_MASK (0x1 << CR0_INTA_SHIFT)\r
-\r
-/*Word mode enable*/\r
-#define CR0_WORD_EN 0x1\r
-\r
-#define CR0_WORD_SHIFT (0)\r
-#define CR0_WORD_MASK (0x1 << CR0_WORD_SHIFT)\r
-\r
-\r
-/*ALS fault queue depth for interrupt enent output*/\r
-#define CR1_ALS_FQ_1 0x0 \r
-#define CR1_ALS_FQ_4 0x1 \r
-#define CR1_ALS_FQ_8 0x2\r
-#define CR1_ALS_FQ_16 0x3\r
-#define CR1_ALS_FQ_24 0x4\r
-#define CR1_ALS_FQ_32 0x5\r
-#define CR1_ALS_FQ_48 0x6\r
-#define CR1_ALS_FQ_63 0x7\r
-\r
-#define CR1_ALS_FQ_SHIFT (5)\r
-#define CR1_ALS_FQ_MASK (0x7 << CR1_ALS_FQ_SHIFT)\r
-\r
-/*resolution for ALS*/\r
-#define CR1_ALS_RES_12BIT 0x0 \r
-#define CR1_ALS_RES_14BIT 0x1 \r
-#define CR1_ALS_RES_16BIT 0x2\r
-#define CR1_ALS_RES_16BIT_2 0x3\r
-\r
-#define CR1_ALS_RES_SHIFT (3)\r
-#define CR1_ALS_RES_MASK (0x3 << CR1_ALS_RES_SHIFT)\r
-\r
-/*sensing amplifier selection for ALS*/\r
-#define CR1_ALS_GAIN_X1 0x0 \r
-#define CR1_ALS_GAIN_X2 0x1 \r
-#define CR1_ALS_GAIN_X4 0x2\r
-#define CR1_ALS_GAIN_X8 0x3\r
-#define CR1_ALS_GAIN_X16 0x4\r
-#define CR1_ALS_GAIN_X32 0x5\r
-#define CR1_ALS_GAIN_X64 0x6\r
-#define CR1_ALS_GAIN_X128 0x7\r
-\r
-#define CR1_ALS_GAIN_SHIFT (0)\r
-#define CR1_ALS_GAIN_MASK (0x7 << CR1_ALS_GAIN_SHIFT)\r
-\r
-\r
-/*PS fault queue depth for interrupt event output*/\r
-#define CR2_PS_FQ_1 0x0 \r
-#define CR2_PS_FQ_4 0x1 \r
-#define CR2_PS_FQ_8 0x2\r
-#define CR2_PS_FQ_15 0x3\r
-\r
-#define CR2_PS_FQ_SHIFT (6)\r
-#define CR2_PS_FQ_MASK (0x3 << CR2_PS_FQ_SHIFT)\r
-\r
-/*interrupt type setting */\r
-/*low active*/\r
-#define CR2_INT_LEVEL 0x0 \r
-/*low pulse*/\r
-#define CR2_INT_PULSE 0x1 \r
-\r
-#define CR2_INT_SHIFT (5)\r
-#define CR2_INT_MASK (0x1 << CR2_INT_SHIFT)\r
-\r
-/*resolution for PS*/\r
-#define CR2_PS_RES_12 0x0 \r
-#define CR2_PS_RES_14 0x1 \r
-#define CR2_PS_RES_16 0x2\r
-#define CR2_PS_RES_16_2 0x3\r
-\r
-#define CR2_PS_RES_SHIFT (3)\r
-#define CR2_PS_RES_MASK (0x3 << CR2_PS_RES_SHIFT)\r
-\r
-/*sensing amplifier selection for PS*/\r
-#define CR2_PS_GAIN_1 0x0 \r
-#define CR2_PS_GAIN_2 0x1 \r
-#define CR2_PS_GAIN_4 0x2\r
-#define CR2_PS_GAIN_8 0x3\r
-#define CR2_PS_GAIN_16 0x4\r
-#define CR2_PS_GAIN_32 0x5\r
-#define CR2_PS_GAIN_64 0x6\r
-#define CR2_PS_GAIN_128 0x7\r
-\r
-#define CR2_PS_GAIN_SHIFT (0)\r
-#define CR2_PS_GAIN_MASK (0x7 << CR2_PS_GAIN_SHIFT)\r
-\r
-/*wait-time slot selection*/\r
-#define CR3_WAIT_SEL_0 0x0 \r
-#define CR3_WAIT_SEL_4 0x1 \r
-#define CR3_WAIT_SEL_8 0x2\r
-#define CR3_WAIT_SEL_16 0x3\r
-\r
-#define CR3_WAIT_SEL_SHIFT (6)\r
-#define CR3_WAIT_SEL_MASK (0x3 << CR3_WAIT_SEL_SHIFT)\r
-\r
-/*IR-LED drive peak current setting*/\r
-#define CR3_LEDDR_12_5 0x0 \r
-#define CR3_LEDDR_25 0x1 \r
-#define CR3_LEDDR_50 0x2\r
-#define CR3_LEDDR_100 0x3\r
-\r
-#define CR3_LEDDR_SHIFT (4)\r
-#define CR3_LEDDR_MASK (0x3 << CR3_LEDDR_SHIFT)\r
-\r
-/*INT pin source selection*/\r
-#define CR3_INT_SEL_BATH 0x0 \r
-#define CR3_INT_SEL_ALS 0x1 \r
-#define CR3_INT_SEL_PS 0x2\r
-#define CR3_INT_SEL_PSAPP 0x3\r
-\r
-#define CR3_INT_SEL_SHIFT (2)\r
-#define CR3_INT_SEL_MASK (0x3 << CR3_INT_SEL_SHIFT)\r
-\r
-/*software reset for register and core*/\r
-#define CR3_SOFTRST_EN 0x1\r
-\r
-#define CR3_SOFTRST_SHIFT (0)\r
-#define CR3_SOFTRST_MASK (0x1 << CR3_SOFTRST_SHIFT)\r
-\r
-/*modulation frequency of LED driver*/\r
-#define CR10_FREQ_DIV2 0x0 \r
-#define CR10_FREQ_DIV4 0x1 \r
-#define CR10_FREQ_DIV8 0x2\r
-#define CR10_FREQ_DIV16 0x3\r
-\r
-#define CR10_FREQ_SHIFT (1)\r
-#define CR10_FREQ_MASK (0x3 << CR10_FREQ_SHIFT)\r
-\r
-/*50/60 Rejection enable*/\r
-#define CR10_REJ_5060_DIS 0x00\r
-#define CR10_REJ_5060_EN 0x01\r
-\r
-#define CR10_REJ_5060_SHIFT (0)\r
-#define CR10_REJ_5060_MASK (0x1 << CR10_REJ_5060_SHIFT)\r
-\r
-#define us5152_NUM_CACHABLE_REGS 0x12\r
-\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- //struct sensor_private_data *sensor =\r
- // (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- int i = 0;\r
- \r
- for(i=0; i<3; i++)\r
- {\r
- if(!enable)\r
- { \r
- value = sensor_read_reg(client, REGS_CR0);\r
- value |= PWR_MODE_DOWN_MASK; //ShutDown_EN=1\r
- result = sensor_write_reg(client, REGS_CR0, value);\r
- if(result)\r
- return result;\r
- }\r
- else\r
- { \r
- value = sensor_read_reg(client, REGS_CR0);\r
- value &= PWR_MODE_OPERATE_MASK ; //Operation_EN=0\r
- result = sensor_write_reg(client, REGS_CR0, value);\r
- if(result)\r
- return result;\r
- }\r
- \r
- if(!result)\r
- break;\r
- }\r
- \r
- if(i>1)\r
- printk("%s:set %d times",__func__,i);\r
-\r
- \r
- //TODO:? function to be added here\r
-\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- value = sensor_read_reg(client, REGS_CHIP_ID); //read chip ids\r
- printk("us5152 chip id is %x!\n", value);\r
-\r
- value = 0x01;//word accessing\r
- \r
- result = sensor_write_reg(client, REGS_CR0, value);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int us5152_value_report(struct input_dev *input, int data)\r
-{\r
- unsigned char index = 0;\r
- if(data <= 10){\r
- index = 0;goto report;\r
- }\r
- else if(data <= 160){\r
- index = 1;goto report;\r
- }\r
- else if(data <= 225){\r
- index = 2;goto report;\r
- }\r
- else if(data <= 320){\r
- index = 3;goto report;\r
- }\r
- else if(data <= 640){\r
- index = 4;goto report;\r
- }\r
- else if(data <= 1280){\r
- index = 5;goto report;\r
- }\r
- else if(data <= 2600){\r
- index = 6;goto report;\r
- }\r
- else{\r
- index = 7;goto report;\r
- }\r
-\r
-report:\r
- input_report_abs(input, ABS_MISC, index);\r
- input_sync(input);\r
- return index;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int value = 0;\r
- char index = 0;\r
- char buffer[2]= { 0 } ;\r
- int ret=0;\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(sensor->ops->int_status_reg >= 0)\r
- {\r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- }\r
- \r
- }\r
- \r
- //value = sensor_read_reg(client, sensor->ops->read_reg); //TODO:? to be changed\r
- if(sensor->ops->read_len< 2) //12bit\r
- {\r
- printk("us5152 data read para num error ; len = %d\n ",sensor->ops->read_len);\r
- return -1;\r
- }\r
- memset(buffer , 0 , 2);\r
- do\r
- {\r
- *buffer = sensor->ops->read_reg;\r
- ret=sensor_rx_data(client,buffer,sensor->ops->read_len);\r
- if(ret<0)\r
- return ret;\r
- }\r
- while(0);\r
- value=buffer[1];\r
- value =((value << 8) | buffer[0]) & 0xffff;\r
- index = us5152_value_report(sensor->input_dev, value); //now is 12bit \r
- \r
- //printk("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
- DBG("%s:%s result=%d,index=%d buffer[1]=0x%x , buffer[0]=0x%x \n",__func__,sensor->ops->name, value,index,buffer[1],buffer[0]);\r
- \r
- return result;\r
-}\r
-\r
-\r
-struct sensor_operate light_us5152_ops = {\r
- .name = "ls_us5152",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_US5152, //i2c id number\r
- .read_reg = REGS_LBS_SENSOR, //read data\r
- .read_len = 2, //data length\r
- .id_reg = REGS_CHIP_ID, //read device id from this register\r
- .id_data = 0x26, //device id\r
- .precision = 12, //12 bits\r
- .ctrl_reg = REGS_CR0, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
- .range = {0,10}, //range\r
- .brightness = {10,4095}, // brightness\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT , \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_us5152_ops;\r
-}\r
-\r
-\r
-static int __init us5152_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
-\r
- return result;\r
-}\r
-\r
-static void __exit us5152_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-MODULE_AUTHOR("Finley Huang finley_huang@upi-semi.com");\r
-MODULE_DESCRIPTION("us5152 ambient light sensor driver");\r
-MODULE_LICENSE("GPL");\r
-MODULE_VERSION(DRIVER_VERSION);\r
-\r
-module_init(us5152_init);\r
-module_exit(us5152_exit);\r
-\r
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+#include <linux/types.h>
+
+
+#define DRIVER_VERSION "1.0"
+
+#define PWR_MODE_DOWN_MASK 0x80
+#define PWR_MODE_OPERATE_MASK 0x7F
+
+
+/*us5152 Slave Addr*/
+#define LIGHT_ADDR 0x72
+
+/*Interrupt PIN for S3C6410*/
+#define IRQ_LIGHT_INT IRQ_EINT(6)
+
+/*Register Set*/
+#define REGS_CR0 0x00
+#define REGS_CR1 0x01
+#define REGS_CR2 0x02
+#define REGS_CR3 0x03
+//ALS
+#define REGS_INT_LSB_TH_LO 0x04
+#define REGS_INT_MSB_TH_LO 0x05
+#define REGS_INT_LSB_TH_HI 0x06
+#define REGS_INT_MSB_TH_HI 0x07
+//ALS data
+#define REGS_LBS_SENSOR 0x0C
+#define REGS_MBS_SENSOR 0x0D
+
+#define REGS_CR10 0x10
+#define REGS_CR11 0x11
+#define REGS_VERSION_ID 0x1F
+#define REGS_CHIP_ID 0xB2
+
+/*ShutDown_EN*/
+#define CR0_OPERATION 0x0
+#define CR0_SHUTDOWN_EN 0x1
+
+#define CR0_SHUTDOWN_SHIFT (7)
+#define CR0_SHUTDOWN_MASK (0x1 << CR0_SHUTDOWN_SHIFT)
+
+/*OneShot_EN*/
+#define CR0_ONESHOT_EN 0x01
+
+#define CR0_ONESHOT_SHIFT (6)
+#define CR0_ONESHOT_MASK (0x1 << CR0_ONESHOT_SHIFT)
+
+/*Operation Mode*/
+#define CR0_OPMODE_ALSANDPS 0x0
+#define CR0_OPMODE_ALSONLY 0x1
+#define CR0_OPMODE_IRONLY 0x2
+
+#define CR0_OPMODE_SHIFT (4)
+#define CR0_OPMODE_MASK (0x3 << CR0_OPMODE_SHIFT)
+
+/*all int flag (PROX, INT_A, INT_P)*/
+#define CR0_ALL_INT_CLEAR 0x0
+
+#define CR0_ALL_INT_SHIFT (1)
+#define CR0_ALL_INT_MASK (0x7 << CR0_ALL_INT_SHIFT)
+
+
+/*indicator of object proximity detection*/
+#define CR0_PROX_CLEAR 0x0
+
+#define CR0_PROX_SHIFT (3)
+#define CR0_PROX_MASK (0x1 << CR0_PROX_SHIFT)
+
+/*interrupt status of proximity sensor*/
+#define CR0_INTP_CLEAR 0x0
+
+#define CR0_INTP_SHIFT (2)
+#define CR0_INTP_MASK (0x1 << CR0_INTP_SHIFT)
+
+/*interrupt status of ambient sensor*/
+#define CR0_INTA_CLEAR 0x0
+
+#define CR0_INTA_SHIFT (1)
+#define CR0_INTA_MASK (0x1 << CR0_INTA_SHIFT)
+
+/*Word mode enable*/
+#define CR0_WORD_EN 0x1
+
+#define CR0_WORD_SHIFT (0)
+#define CR0_WORD_MASK (0x1 << CR0_WORD_SHIFT)
+
+
+/*ALS fault queue depth for interrupt enent output*/
+#define CR1_ALS_FQ_1 0x0
+#define CR1_ALS_FQ_4 0x1
+#define CR1_ALS_FQ_8 0x2
+#define CR1_ALS_FQ_16 0x3
+#define CR1_ALS_FQ_24 0x4
+#define CR1_ALS_FQ_32 0x5
+#define CR1_ALS_FQ_48 0x6
+#define CR1_ALS_FQ_63 0x7
+
+#define CR1_ALS_FQ_SHIFT (5)
+#define CR1_ALS_FQ_MASK (0x7 << CR1_ALS_FQ_SHIFT)
+
+/*resolution for ALS*/
+#define CR1_ALS_RES_12BIT 0x0
+#define CR1_ALS_RES_14BIT 0x1
+#define CR1_ALS_RES_16BIT 0x2
+#define CR1_ALS_RES_16BIT_2 0x3
+
+#define CR1_ALS_RES_SHIFT (3)
+#define CR1_ALS_RES_MASK (0x3 << CR1_ALS_RES_SHIFT)
+
+/*sensing amplifier selection for ALS*/
+#define CR1_ALS_GAIN_X1 0x0
+#define CR1_ALS_GAIN_X2 0x1
+#define CR1_ALS_GAIN_X4 0x2
+#define CR1_ALS_GAIN_X8 0x3
+#define CR1_ALS_GAIN_X16 0x4
+#define CR1_ALS_GAIN_X32 0x5
+#define CR1_ALS_GAIN_X64 0x6
+#define CR1_ALS_GAIN_X128 0x7
+
+#define CR1_ALS_GAIN_SHIFT (0)
+#define CR1_ALS_GAIN_MASK (0x7 << CR1_ALS_GAIN_SHIFT)
+
+
+/*PS fault queue depth for interrupt event output*/
+#define CR2_PS_FQ_1 0x0
+#define CR2_PS_FQ_4 0x1
+#define CR2_PS_FQ_8 0x2
+#define CR2_PS_FQ_15 0x3
+
+#define CR2_PS_FQ_SHIFT (6)
+#define CR2_PS_FQ_MASK (0x3 << CR2_PS_FQ_SHIFT)
+
+/*interrupt type setting */
+/*low active*/
+#define CR2_INT_LEVEL 0x0
+/*low pulse*/
+#define CR2_INT_PULSE 0x1
+
+#define CR2_INT_SHIFT (5)
+#define CR2_INT_MASK (0x1 << CR2_INT_SHIFT)
+
+/*resolution for PS*/
+#define CR2_PS_RES_12 0x0
+#define CR2_PS_RES_14 0x1
+#define CR2_PS_RES_16 0x2
+#define CR2_PS_RES_16_2 0x3
+
+#define CR2_PS_RES_SHIFT (3)
+#define CR2_PS_RES_MASK (0x3 << CR2_PS_RES_SHIFT)
+
+/*sensing amplifier selection for PS*/
+#define CR2_PS_GAIN_1 0x0
+#define CR2_PS_GAIN_2 0x1
+#define CR2_PS_GAIN_4 0x2
+#define CR2_PS_GAIN_8 0x3
+#define CR2_PS_GAIN_16 0x4
+#define CR2_PS_GAIN_32 0x5
+#define CR2_PS_GAIN_64 0x6
+#define CR2_PS_GAIN_128 0x7
+
+#define CR2_PS_GAIN_SHIFT (0)
+#define CR2_PS_GAIN_MASK (0x7 << CR2_PS_GAIN_SHIFT)
+
+/*wait-time slot selection*/
+#define CR3_WAIT_SEL_0 0x0
+#define CR3_WAIT_SEL_4 0x1
+#define CR3_WAIT_SEL_8 0x2
+#define CR3_WAIT_SEL_16 0x3
+
+#define CR3_WAIT_SEL_SHIFT (6)
+#define CR3_WAIT_SEL_MASK (0x3 << CR3_WAIT_SEL_SHIFT)
+
+/*IR-LED drive peak current setting*/
+#define CR3_LEDDR_12_5 0x0
+#define CR3_LEDDR_25 0x1
+#define CR3_LEDDR_50 0x2
+#define CR3_LEDDR_100 0x3
+
+#define CR3_LEDDR_SHIFT (4)
+#define CR3_LEDDR_MASK (0x3 << CR3_LEDDR_SHIFT)
+
+/*INT pin source selection*/
+#define CR3_INT_SEL_BATH 0x0
+#define CR3_INT_SEL_ALS 0x1
+#define CR3_INT_SEL_PS 0x2
+#define CR3_INT_SEL_PSAPP 0x3
+
+#define CR3_INT_SEL_SHIFT (2)
+#define CR3_INT_SEL_MASK (0x3 << CR3_INT_SEL_SHIFT)
+
+/*software reset for register and core*/
+#define CR3_SOFTRST_EN 0x1
+
+#define CR3_SOFTRST_SHIFT (0)
+#define CR3_SOFTRST_MASK (0x1 << CR3_SOFTRST_SHIFT)
+
+/*modulation frequency of LED driver*/
+#define CR10_FREQ_DIV2 0x0
+#define CR10_FREQ_DIV4 0x1
+#define CR10_FREQ_DIV8 0x2
+#define CR10_FREQ_DIV16 0x3
+
+#define CR10_FREQ_SHIFT (1)
+#define CR10_FREQ_MASK (0x3 << CR10_FREQ_SHIFT)
+
+/*50/60 Rejection enable*/
+#define CR10_REJ_5060_DIS 0x00
+#define CR10_REJ_5060_EN 0x01
+
+#define CR10_REJ_5060_SHIFT (0)
+#define CR10_REJ_5060_MASK (0x1 << CR10_REJ_5060_SHIFT)
+
+#define us5152_NUM_CACHABLE_REGS 0x12
+
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ //struct sensor_private_data *sensor =
+ // (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+ int i = 0;
+
+ for(i=0; i<3; i++)
+ {
+ if(!enable)
+ {
+ value = sensor_read_reg(client, REGS_CR0);
+ value |= PWR_MODE_DOWN_MASK; //ShutDown_EN=1
+ result = sensor_write_reg(client, REGS_CR0, value);
+ if(result)
+ return result;
+ }
+ else
+ {
+ value = sensor_read_reg(client, REGS_CR0);
+ value &= PWR_MODE_OPERATE_MASK ; //Operation_EN=0
+ result = sensor_write_reg(client, REGS_CR0, value);
+ if(result)
+ return result;
+ }
+
+ if(!result)
+ break;
+ }
+
+ if(i>1)
+ printk("%s:set %d times",__func__,i);
+
+
+ //TODO:? function to be added here
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ value = sensor_read_reg(client, REGS_CHIP_ID); //read chip ids
+ printk("us5152 chip id is %x!\n", value);
+
+ value = 0x01;//word accessing
+
+ result = sensor_write_reg(client, REGS_CR0, value);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ return result;
+}
+
+
+static int us5152_value_report(struct input_dev *input, int data)
+{
+ unsigned char index = 0;
+ if(data <= 10){
+ index = 0;goto report;
+ }
+ else if(data <= 160){
+ index = 1;goto report;
+ }
+ else if(data <= 225){
+ index = 2;goto report;
+ }
+ else if(data <= 320){
+ index = 3;goto report;
+ }
+ else if(data <= 640){
+ index = 4;goto report;
+ }
+ else if(data <= 1280){
+ index = 5;goto report;
+ }
+ else if(data <= 2600){
+ index = 6;goto report;
+ }
+ else{
+ index = 7;goto report;
+ }
+
+report:
+ input_report_abs(input, ABS_MISC, index);
+ input_sync(input);
+ return index;
+}
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int value = 0;
+ char index = 0;
+ char buffer[2]= { 0 } ;
+ int ret=0;
+
+ if(sensor->pdata->irq_enable)
+ {
+ if(sensor->ops->int_status_reg >= 0)
+ {
+ value = sensor_read_reg(client, sensor->ops->int_status_reg);
+ }
+
+ }
+
+ //value = sensor_read_reg(client, sensor->ops->read_reg); //TODO:? to be changed
+ if(sensor->ops->read_len< 2) //12bit
+ {
+ printk("us5152 data read para num error ; len = %d\n ",sensor->ops->read_len);
+ return -1;
+ }
+ memset(buffer , 0 , 2);
+ do
+ {
+ *buffer = sensor->ops->read_reg;
+ ret=sensor_rx_data(client,buffer,sensor->ops->read_len);
+ if(ret<0)
+ return ret;
+ }
+ while(0);
+ value=buffer[1];
+ value =((value << 8) | buffer[0]) & 0xffff;
+ index = us5152_value_report(sensor->input_dev, value); //now is 12bit
+
+ //printk("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
+ DBG("%s:%s result=%d,index=%d buffer[1]=0x%x , buffer[0]=0x%x \n",__func__,sensor->ops->name, value,index,buffer[1],buffer[0]);
+
+ return result;
+}
+
+
+struct sensor_operate light_us5152_ops = {
+ .name = "ls_us5152",
+ .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
+ .id_i2c = LIGHT_ID_US5152, //i2c id number
+ .read_reg = REGS_LBS_SENSOR, //read data
+ .read_len = 2, //data length
+ .id_reg = REGS_CHIP_ID, //read device id from this register
+ .id_data = 0x26, //device id
+ .precision = 12, //12 bits
+ .ctrl_reg = REGS_CR0, //enable or disable
+ .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
+ .range = {0,10}, //range
+ .brightness = {10,4095}, // brightness
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT ,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *light_get_ops(void)
+{
+ return &light_us5152_ops;
+}
+
+
+static int __init us5152_init(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, light_get_ops);
+
+ return result;
+}
+
+static void __exit us5152_exit(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, light_get_ops);
+}
+
+MODULE_AUTHOR("Finley Huang finley_huang@upi-semi.com");
+MODULE_DESCRIPTION("us5152 ambient light sensor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(us5152_init);
+module_exit(us5152_exit);
+