1 /* drivers/input/sensors/access/kxtik.c
3 * Copyright (C) 2012-2015 ROCKCHIP.
4 * Author: luowei <lw@rock-chips.com>
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.
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.
16 #include <linux/interrupt.h>
17 #include <linux/i2c.h>
18 #include <linux/slab.h>
19 #include <linux/irq.h>
20 #include <linux/miscdevice.h>
21 #include <linux/gpio.h>
22 #include <asm/uaccess.h>
23 #include <asm/atomic.h>
24 #include <linux/delay.h>
25 #include <linux/input.h>
26 #include <linux/workqueue.h>
27 #include <linux/freezer.h>
28 #include <linux/of_gpio.h>
29 #ifdef CONFIG_HAS_EARLYSUSPEND
30 #include <linux/earlysuspend.h>
32 #include <linux/sensor-dev.h>
35 #define CONFIG_REG (0x00)
36 #define TIM_CTL_REG (0x01)
37 #define ALS_CTL_REG (0x02)
38 #define INT_STATUS_REG (0x03)
39 #define PS_CTL_REG (0x04)
40 #define PS_ALS_DATA_REG (0x05)
41 #define ALS_WINDOWS_REG (0x08)
43 //enable bit[ 0-1], in register CONFIG_REG
44 #define ONLY_ALS_EN (0x00)
45 #define ONLY_PROX_EN (0x01)
46 #define ALL_PROX_ALS_EN (0x02)
47 #define ALL_IDLE (0x03)
49 #define POWER_MODE_MASK (0x0C)
50 #define POWER_UP_MODE (0x00)
51 #define POWER_DOWN_MODE (0x08)
52 #define POWER_RESET_MODE (0x0C)
54 static int sensor_power_updown(struct i2c_client *client, int on)
63 value = sensor_read_reg(client, CONFIG_REG);
64 value &= ~POWER_MODE_MASK;
65 value |= POWER_DOWN_MODE;
66 result = sensor_write_reg(client, CONFIG_REG, value);
72 value = sensor_read_reg(client, CONFIG_REG);
73 value &= ~POWER_MODE_MASK;
74 value |= POWER_UP_MODE;
75 result = sensor_write_reg(client, CONFIG_REG, value);
85 printk("%s:set %d times",__func__,i);
90 /****************operate according to sensor chip:start************/
92 static int sensor_active(struct i2c_client *client, int enable, int rate)
94 struct sensor_private_data *sensor =
95 (struct sensor_private_data *) i2c_get_clientdata(client);
100 sensor_power_updown(client, 1);
102 value = sensor_read_reg(client, sensor->ops->ctrl_reg);
104 //register setting according to chip datasheet
107 if( (value & 0x03) == ONLY_PROX_EN )
110 value |= ALL_PROX_ALS_EN;
112 else if((value & 0x03) == ALL_IDLE )
115 value |= ONLY_ALS_EN;
121 if( (value & 0x03) == ONLY_ALS_EN )
126 else if((value & 0x03) == ALL_PROX_ALS_EN )
129 value |= ONLY_PROX_EN;
134 sensor->ops->ctrl_data = value;
136 DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
137 result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
139 printk("%s:fail to active sensor\n",__func__);
146 static int sensor_init(struct i2c_client *client)
148 struct sensor_private_data *sensor =
149 (struct sensor_private_data *) i2c_get_clientdata(client);
153 sensor_power_updown(client, 0);
155 result = sensor->ops->active(client,0,0);
158 printk("%s:line=%d,error\n",__func__,__LINE__);
162 sensor->status_cur = SENSOR_OFF;
164 value = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
165 //value = 0x69; //The ADC effective resolution = 17; Low lux threshold level = 9;
166 result = sensor_write_reg(client, ALS_CTL_REG, value);
169 printk("%s:line=%d,error\n",__func__,__LINE__);
173 //value = 0x04;//0x01-0x0f; 17%->93.5% if value = 0x04,then Compensate Loss 52%
174 value = 0x02;//0x01-0x0f; 17%->93.5% if value = 0x02,then Compensate Loss 31%
175 result = sensor_write_reg(client, ALS_WINDOWS_REG, value);
178 printk("%s:line=%d,error\n",__func__,__LINE__);
186 static int light_report_value(struct input_dev *input, int data)
188 unsigned char index = 0;
190 index = 0;goto report;
193 index = 1;goto report;
196 index = 2;goto report;
199 index = 3;goto report;
202 index = 4;goto report;
205 index = 5;goto report;
208 index = 6;goto report;
211 index = 7;goto report;
215 input_report_abs(input, ABS_MISC, index);
222 static int sensor_report_value(struct i2c_client *client)
224 struct sensor_private_data *sensor =
225 (struct sensor_private_data *) i2c_get_clientdata(client);
230 if(sensor->pdata->irq_enable)
232 if(sensor->ops->int_status_reg)
234 value = sensor_read_reg(client, sensor->ops->int_status_reg);
239 value = sensor_read_reg(client, sensor->ops->read_reg);
240 index = light_report_value(sensor->input_dev, value&0x3f); // bit0-5 is ls data;
242 DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
247 struct sensor_operate light_al3006_ops = {
249 .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
250 .id_i2c = LIGHT_ID_AL3006, //i2c id number
251 .read_reg = PS_ALS_DATA_REG, //read data
252 .read_len = 1, //data length
253 .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
254 .id_data = SENSOR_UNKNOW_DATA, //device id
255 .precision = 8, //8 bits
256 .ctrl_reg = CONFIG_REG, //enable or disable
257 .int_status_reg = INT_STATUS_REG, //intterupt status register
258 .range = {100,65535}, //range
259 .brightness ={10,255}, // brightness
260 .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
261 .active = sensor_active,
263 .report = sensor_report_value,
266 /****************operate according to sensor chip:end************/
268 //function name should not be changed
269 static struct sensor_operate *light_get_ops(void)
271 return &light_al3006_ops;
275 static int __init light_al3006_init(void)
277 struct sensor_operate *ops = light_get_ops();
279 int type = ops->type;
280 result = sensor_register_slave(type, NULL, NULL, light_get_ops);
284 static void __exit light_al3006_exit(void)
286 struct sensor_operate *ops = light_get_ops();
287 int type = ops->type;
288 sensor_unregister_slave(type, NULL, NULL, light_get_ops);
292 module_init(light_al3006_init);
293 module_exit(light_al3006_exit);