From 7782f5cb2ba42add2c4b2d8aa0dab68d1da93832 Mon Sep 17 00:00:00 2001 From: luowei Date: Mon, 18 Feb 2013 16:23:38 +0800 Subject: [PATCH] add light sensor cm3232 support --- drivers/input/sensors/lsensor/Kconfig | 4 + drivers/input/sensors/lsensor/Makefile | 1 + drivers/input/sensors/lsensor/cm3232.c | 245 +++++++++++++++++++++++++ drivers/input/sensors/sensor-dev.c | 3 +- include/linux/sensor-dev.h | 3 +- 5 files changed, 254 insertions(+), 2 deletions(-) create mode 100755 drivers/input/sensors/lsensor/cm3232.c diff --git a/drivers/input/sensors/lsensor/Kconfig b/drivers/input/sensors/lsensor/Kconfig index 0e6cf2ff9181..8db41c71ba5f 100755 --- a/drivers/input/sensors/lsensor/Kconfig +++ b/drivers/input/sensors/lsensor/Kconfig @@ -11,6 +11,10 @@ config LS_CM3217 bool "light sensor cm3217" default n +config LS_CM3232 + bool "light sensor cm3232" + default n + config LS_AL3006 bool "light sensor al3006" default n diff --git a/drivers/input/sensors/lsensor/Makefile b/drivers/input/sensors/lsensor/Makefile index 48531def826d..093018796925 100755 --- a/drivers/input/sensors/lsensor/Makefile +++ b/drivers/input/sensors/lsensor/Makefile @@ -1,6 +1,7 @@ # gsensor drivers obj-$(CONFIG_LS_CM3217) += cm3217.o +obj-$(CONFIG_LS_CM3232) += cm3232.o obj-$(CONFIG_LS_AL3006) += ls_al3006.o obj-$(CONFIG_LS_STK3171) += ls_stk3171.o obj-$(CONFIG_LS_ISL29023) += isl29023.o diff --git a/drivers/input/sensors/lsensor/cm3232.c b/drivers/input/sensors/lsensor/cm3232.c new file mode 100755 index 000000000000..bb9cf997a7cf --- /dev/null +++ b/drivers/input/sensors/lsensor/cm3232.c @@ -0,0 +1,245 @@ +/* drivers/input/sensors/access/kxtik.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + +#if 0 +#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT +#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x) +#else +#define DBG(x...) +#endif + +#define CM3232_CLOSE 0x01 + + +#define CM3232_ADDR_COM 0 +#define CM3232_ADDR_DATA 50 + +#define CM3232_DRV_NAME "cm3232" +//command code +#define COMMAND_CTRL 0 +#define COMMAND_ALS_DATA 50 //ALS: 15:8 MSB 8bits data + //7:0 LSB 8bits data + +//ctrl bit +#define ALS_RESET(x) (((x)&1)<<6) //0 = Reset disable; 1 = Reset enable +#define ALS_IT(x) (((x)&7)<<2) //ALS integration time setting +#define HIGH_SENSITIVITY(x) (((x)&1)<<1) //0 = Normal mode; 1 = High sensitivity mode +#define SHUT_DOWN(x) (((x)&1)<<0) //ALS shut down setting: 0 = ALS Power on ; 1 = ALS Shut down + +#define ALS_IT100MS 0 //100ms +#define ALS_IT200MS 1 //200ms +#define ALS_IT400MS 2 //400ms +#define ALS_IT800MS 3 //800ms +#define ALS_IT1600MS 4 //1600ms +#define ALS_IT3200MS 5 //3200ms + + +/****************operate according to sensor chip:start************/ + +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; + int status = 0; + + //sensor->client->addr = sensor->ops->ctrl_reg; + //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); + //printk("%s: client addr = %#x\n\n", __func__, client->addr); + //register setting according to chip datasheet + if (enable) { + sensor->ops->ctrl_data = ALS_RESET(1); + result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); + if(result) { + printk("%s:fail to active sensor\n",__func__); + return -1; + } + } + + if(enable) + { + sensor->ops->ctrl_data = ALS_IT(ALS_IT200MS) | HIGH_SENSITIVITY(1); + } + else + { + sensor->ops->ctrl_data = SHUT_DOWN(1); + } + + DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable); + + result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); + if(result) + printk("%s:fail to active sensor\n",__func__); + + 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; + + result = sensor->ops->active(client,0,0); + if(result) + { + printk("%s:line=%d,error\n",__func__,__LINE__); + return result; + } + + sensor->status_cur = SENSOR_OFF; + return result; +} + + +static void light_report_value(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: + DBG("cm3232 report data=%d,index = %d\n",data,index); + printk("cm3232 report data=%d,index = %d\n",data,index); + input_report_abs(input, ABS_MISC, index); + input_sync(input); +} + + +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; + char msb = 0, lsb = 0; + char data[2] = {0}; + unsigned short value = 0; + + //sensor->client->addr = CM3232_ADDR_DATA; + data[0] = CM3232_ADDR_DATA; + sensor_rx_data(sensor->client, data, 2); + value = (data[1] << 8) | data[0] ; + + DBG("%s:result=%d\n",__func__,value); + //printk("%s:result=%d\n",__func__,value); + light_report_value(sensor->input_dev, value); + + if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register + { + + result= sensor_read_reg(client, sensor->ops->int_status_reg); + if(result) + { + printk("%s:fail to clear sensor int status,ret=0x%x\n",__func__,result); + } + } + + return result; +} + + +struct sensor_operate light_cm3232_ops = { + .name = "cm3232", + .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct + .id_i2c = LIGHT_ID_CM3232, //i2c id number + .read_reg = CM3232_ADDR_DATA, //read data + .read_len = 2, //data length + .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register + .id_data = SENSOR_UNKNOW_DATA, //device id + .precision = 8, //8 bits + .ctrl_reg = CM3232_ADDR_COM, //enable or disable + .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register + .range = {100,65535}, //range + .brightness = {10,255}, // brightness + .trig = SENSOR_UNKNOW_DATA, + .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_cm3232_ops; +} + + +static int __init light_cm3232_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); + //printk("%s: >>>>>>>>>>>>>>>>>>>\n\n\n",__func__); + return result; +} + +static void __exit light_cm3232_exit(void) +{ + struct sensor_operate *ops = light_get_ops(); + int type = ops->type; + sensor_unregister_slave(type, NULL, NULL, light_get_ops); +} + + +module_init(light_cm3232_init); +module_exit(light_cm3232_exit); + + diff --git a/drivers/input/sensors/sensor-dev.c b/drivers/input/sensors/sensor-dev.c index db8438acb637..10e43614724d 100755 --- a/drivers/input/sensors/sensor-dev.c +++ b/drivers/input/sensors/sensor-dev.c @@ -1415,11 +1415,12 @@ static const struct i2c_device_id sensor_id[] = { /*light sensor*/ {"lightsensor", LIGHT_ID_ALL}, {"light_cm3217", LIGHT_ID_CM3217}, + {"light_cm3232", LIGHT_ID_CM3232}, {"light_al3006", LIGHT_ID_AL3006}, {"ls_stk3171", LIGHT_ID_STK3171}, {"ls_isl29023", LIGHT_ID_ISL29023}, {"ls_ap321xx", LIGHT_ID_AP321XX}, - {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR}, + {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR}, /*proximity sensor*/ {"psensor", PROXIMITY_ID_ALL}, {"proximity_al3006", PROXIMITY_ID_AL3006}, diff --git a/include/linux/sensor-dev.h b/include/linux/sensor-dev.h index 5711d3efb2ee..24c568e2d3c8 100755 --- a/include/linux/sensor-dev.h +++ b/include/linux/sensor-dev.h @@ -76,11 +76,12 @@ enum sensor_id { LIGHT_ID_ALL, LIGHT_ID_CM3217, + LIGHT_ID_CM3232, LIGHT_ID_AL3006, LIGHT_ID_STK3171, LIGHT_ID_ISL29023, LIGHT_ID_AP321XX, - LIGHT_ID_PHOTORESISTOR, + LIGHT_ID_PHOTORESISTOR, PROXIMITY_ID_ALL, PROXIMITY_ID_AL3006, -- 2.34.1