input: sensors: fromdos and remove trailing whitespace

Change-Id: I6799f2538f95953d1565ac805497161ce6043855
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
This commit is contained in:
Huang, Tao
2016-11-16 10:25:18 +08:00
parent 7df2b3aa6a
commit 7e8031c929
25 changed files with 9674 additions and 9674 deletions

View File

@@ -1,14 +1,14 @@
# sensor drivers
obj-$(CONFIG_ANGLE_DEVICE) += angle/
obj-$(CONFIG_GSENSOR_DEVICE) += accel/
obj-$(CONFIG_COMPASS_DEVICE) += compass/
obj-$(CONFIG_GYROSCOPE_DEVICE) += gyro/
obj-$(CONFIG_LIGHT_DEVICE) += lsensor/
obj-$(CONFIG_PROXIMITY_DEVICE) += psensor/
obj-$(CONFIG_TEMPERATURE_DEVICE) += temperature/
obj-$(CONFIG_PRESSURE_DEVICE) += pressure/
obj-$(CONFIG_HALL_DEVICE) += hall/
obj-$(CONFIG_SENSOR_DEVICE) += sensor-i2c.o
obj-$(CONFIG_SENSOR_DEVICE) += sensor-dev.o
# sensor drivers
obj-$(CONFIG_ANGLE_DEVICE) += angle/
obj-$(CONFIG_GSENSOR_DEVICE) += accel/
obj-$(CONFIG_COMPASS_DEVICE) += compass/
obj-$(CONFIG_GYROSCOPE_DEVICE) += gyro/
obj-$(CONFIG_LIGHT_DEVICE) += lsensor/
obj-$(CONFIG_PROXIMITY_DEVICE) += psensor/
obj-$(CONFIG_TEMPERATURE_DEVICE) += temperature/
obj-$(CONFIG_PRESSURE_DEVICE) += pressure/
obj-$(CONFIG_HALL_DEVICE) += hall/
obj-$(CONFIG_SENSOR_DEVICE) += sensor-i2c.o
obj-$(CONFIG_SENSOR_DEVICE) += sensor-dev.o

View File

@@ -1,483 +1,483 @@
/* drivers/input/sensors/access/dmard10.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: guoyi <gy@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
/* Default register settings */
#define RBUFF_SIZE 12 /* Rx buffer size */
#define REG_ACTR 0x00
#define REG_WDAL 0x01
#define REG_TAPNS 0x0f
#define REG_MISC2 0x1f
#define REG_AFEM 0x0c
#define REG_CKSEL 0x0d
#define REG_INTC 0x0e
#define REG_STADR 0x12
#define REG_STAINT 0x1C
#define REG_PD 0x21
#define REG_TCGYZ 0x26
#define REG_X_OUT 0x41
#define MODE_Off 0x00
#define MODE_ResetAtOff 0x01
#define MODE_Standby 0x02
#define MODE_ResetAtStandby 0x03
#define MODE_Active 0x06
#define MODE_Trigger 0x0a
#define MODE_ReadOTP 0x12
#define MODE_WriteOTP 0x22
#define MODE_WriteOTPBuf 0x42
#define MODE_ResetDataPath 0x82
#define VALUE_STADR 0x55
#define VALUE_STAINT 0xAA
#define VALUE_AFEM_AFEN_Normal 0x8f// AFEN set 1 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
#define VALUE_AFEM_Normal 0x0f// AFEN set 0 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
#define VALUE_INTC 0x00// INTC[6:5]=b'00
#define VALUE_INTC_Interrupt_En 0x20// INTC[6:5]=b'01 (Data ready interrupt enable, active high at INT0)
#define VALUE_CKSEL_ODR_0_204 0x04// ODR[3:0]=b'0000 (0.78125Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_1_204 0x14// ODR[3:0]=b'0001 (1.5625Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_3_204 0x24// ODR[3:0]=b'0010 (3.125Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_6_204 0x34// ODR[3:0]=b'0011 (6.25Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_12_204 0x44// ODR[3:0]=b'0100 (12.5Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_25_204 0x54// ODR[3:0]=b'0101 (25Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_50_204 0x64// ODR[3:0]=b'0110 (50Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_100_204 0x74// ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_TAPNS_NoFilter 0x00 // TAP1/TAP2 NO FILTER
#define VALUE_TAPNS_Ave_2 0x11 // TAP1/TAP2 Average 2
#define VALUE_TAPNS_Ave_4 0x22 // TAP1/TAP2 Average 4
#define VALUE_TAPNS_Ave_8 0x33 // TAP1/TAP2 Average 8
#define VALUE_TAPNS_Ave_16 0x44 // TAP1/TAP2 Average 16
#define VALUE_TAPNS_Ave_32 0x55 // TAP1/TAP2 Average 32
#define VALUE_MISC2_OSCA_EN 0x08
#define VALUE_PD_RST 0x52
//#define DMARD10_REG_INTSU 0x47
//#define DMARD10_REG_MODE 0x44
//#define DMARD10_REG_SR 0x44
#define DMARD10_REG_DS 0X49
#define DMARD10_REG_ID 0X0F
#define DMARD10_REG_IT 0X4D
#define DMARD10_REG_INTSRC1_C 0X4A
#define DMARD10_REG_INTSRC1_S 0X4B
#define MMAIO 0xA1
// IOCTLs for DMARD10 library
#define ECS_IOCTL_INIT _IO(MMAIO, 0x01)
#define ECS_IOCTL_RESET _IO(MMAIO, 0x04)
#define ECS_IOCTL_CLOSE _IO(MMAIO, 0x02)
#define ECS_IOCTL_START _IO(MMAIO, 0x03)
#define ECS_IOCTL_GETDATA _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])
#define SENSOR_CALIBRATION _IOWR(MMAIO, 0x05 , int[SENSOR_DATA_SIZE])
// IOCTLs for APPs
#define ECS_IOCTL_APP_SET_RATE _IOW(MMAIO, 0x10, char)
//rate
#define DMARD10_RANGE 2000000
#define DMARD10_RATE_32 32
/*
#define DMARD10_RATE_64 64
#define DMARD10_RATE_120 128
#define DMARD10_RATE_MIN DMARD10_RATE_1
#define DMARD10_RATE_MAX DMARD10_RATE_120
*/
/*status*/
#define DMARD10_OPEN 1
#define DMARD10_CLOSE 0
#define DMARD10_NORMAL 2
#define DMARD10_LOWPOWER 3
#define DMARD10_IIC_ADDR 0x18
#define DMARD10_REG_LEN 11
#define DMARD10_FATOR 15
#define DMARD10_X_OUT 0x41
#define SENSOR_DATA_SIZE 3
#define DMARD10_SENSOR_RATE_1 0
#define DMARD10_SENSOR_RATE_2 1
#define DMARD10_SENSOR_RATE_3 2
#define DMARD10_SENSOR_RATE_4 3
#define POWER_OR_RATE 1
#define SW_RESET 1
#define DMARD10_INTERRUPUT 1
#define DMARD10_POWERDOWN 0
#define DMARD10_POWERON 1
//g-senor layout configuration, choose one of the following configuration
#define AVG_NUM 16
#define SENSOR_DATA_SIZE 3
#define DEFAULT_SENSITIVITY 1024
#define DMARD10_ENABLE 1
#define DMARD10_REG_X_OUT 0x12
#define DMARD10_REG_Y_OUT 0x1
#define DMARD10_REG_Z_OUT 0x2
#define DMARD10_REG_TILT 0x3
#define DMARD10_REG_SRST 0x4
#define DMARD10_REG_SPCNT 0x5
#define DMARD10_REG_INTSU 0x6
#define DMARD10_REG_MODE 0x7
#define DMARD10_REG_SR 0x8
#define DMARD10_REG_PDET 0x9
#define DMARD10_REG_PD 0xa
#define DMARD10_RANGE 4000000
#define DMARD10_PRECISION 10
#define DMARD10_BOUNDARY (0x1 << (DMARD10_PRECISION - 1))
#define DMARD10_GRAVITY_STEP (DMARD10_RANGE / DMARD10_BOUNDARY)
struct sensor_axis_average {
int x_average;
int y_average;
int z_average;
int count;
};
static struct sensor_axis_average axis_average;
int gsensor_reset(struct i2c_client *client){
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
char buffer[7], buffer2[2];
/* 1. check D10 , VALUE_STADR = 0x55 , VALUE_STAINT = 0xAA */
buffer[0] = REG_STADR;
buffer2[0] = REG_STAINT;
sensor_rx_data(client, buffer, 2);
sensor_rx_data(client, buffer2, 2);
if( buffer[0] == VALUE_STADR || buffer2[0] == VALUE_STAINT){
DBG(KERN_INFO " REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d\n", buffer[0], buffer2[0]);
DBG(KERN_INFO " %s DMT_DEVICE_NAME registered I2C driver!\n",__FUNCTION__);
}
else{
DBG(KERN_INFO " %s gsensor I2C err @@@ REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d \n", __func__, buffer[0], buffer2[0]);
return -1;
}
/* 2. Powerdown reset */
buffer[0] = REG_PD;
buffer[1] = VALUE_PD_RST;
sensor_tx_data(client, buffer, 2);
/* 3. ACTR => Standby mode => Download OTP to parameter reg => Standby mode => Reset data path => Standby mode */
buffer[0] = REG_ACTR;
buffer[1] = MODE_Standby;
buffer[2] = MODE_ReadOTP;
buffer[3] = MODE_Standby;
buffer[4] = MODE_ResetDataPath;
buffer[5] = MODE_Standby;
sensor_tx_data(client, buffer, 6);
/* 4. OSCA_EN = 1 ,TSTO = b'000(INT1 = normal, TEST0 = normal) */
buffer[0] = REG_MISC2;
buffer[1] = VALUE_MISC2_OSCA_EN;
sensor_tx_data(client, buffer, 2);
/* 5. AFEN = 1(AFE will powerdown after ADC) */
buffer[0] = REG_AFEM;
buffer[1] = VALUE_AFEM_AFEN_Normal;
buffer[2] = VALUE_CKSEL_ODR_100_204;
buffer[3] = VALUE_INTC;
buffer[4] = VALUE_TAPNS_Ave_2;
buffer[5] = 0x00; // DLYC, no delay timing
buffer[6] = 0x07; // INTD=1 (push-pull), INTA=1 (active high), AUTOT=1 (enable T)
sensor_tx_data(client, buffer, 7);
/* 6. write TCGYZ & TCGX */
buffer[0] = REG_WDAL; // REG:0x01
buffer[1] = 0x00; // set TC of Y,Z gain value
buffer[2] = 0x00; // set TC of X gain value
buffer[3] = 0x03; // Temperature coefficient of X,Y,Z gain
sensor_tx_data(client, buffer, 4);
buffer[0] = REG_ACTR; // REG:0x00
buffer[1] = MODE_Standby; // Standby
buffer[2] = MODE_WriteOTPBuf; // WriteOTPBuf
buffer[3] = MODE_Standby; // Standby
/* 7. Activation mode */
buffer[0] = REG_ACTR;
buffer[1] = MODE_Active;
sensor_tx_data(client, buffer, 2);
printk("\n dmard10 gsensor _reset SUCCESS!!\n");
return 0;
}
/****************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;
gsensor_reset(client);
sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
status = DMARD10_ENABLE; //dmard10
sensor->ops->ctrl_data |= status;
}
else
{
status = ~DMARD10_ENABLE; //dmard10
sensor->ops->ctrl_data &= status;
}
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;
DBG("%s:DMARD10_REG_TILT=0x%x\n",__func__,sensor_read_reg(client, DMARD10_REG_TILT));
result = sensor_write_reg(client, DMARD10_REG_SR, (0x01<<5)| 0x02); //32 Samples/Second Active and Auto-Sleep Mode
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
if(sensor->pdata->irq_enable) //open interrupt
{
result = sensor_write_reg(client, DMARD10_REG_INTSU, 1<<4);//enable int,GINT=1
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
sensor->ops->ctrl_data = 1<<6; //Interrupt output INT is push-pull
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
memset(&axis_average, 0, sizeof(struct sensor_axis_average));
return result;
}
static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
{
s64 result;
result = ((int)high_byte << 8)|((int)low_byte);
if (result < DMARD10_BOUNDARY){
result = result* DMARD10_GRAVITY_STEP;
}else{
result = ~( ((~result & (0x7fff>>(16-DMARD10_PRECISION)) ) + 1)* DMARD10_GRAVITY_STEP) + 1;
}
return result;
}
static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report acceleration sensor information */
input_report_abs(sensor->input_dev, ABS_X, axis->x);
input_report_abs(sensor->input_dev, ABS_Y, axis->y);
input_report_abs(sensor->input_dev, ABS_Z, axis->z);
input_sync(sensor->input_dev);
DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
#define DMARD10_COUNT_AVERAGE 2
#define GSENSOR_MIN 2
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x,y,z;
struct sensor_axis axis;
char buffer[8] = {0};
char value = 0;
if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 8);
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
*buffer = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
//this gsensor need 6 bytes buffer
x = sensor_convert_data(sensor->client, buffer[3], buffer[2]); //buffer[1]:high bit
y = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
z = sensor_convert_data(sensor->client, buffer[7], buffer[6]);
axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
axis_average.x_average += axis.x;
axis_average.y_average += axis.y;
axis_average.z_average += axis.z;
axis_average.count++;
if(axis_average.count >= DMARD10_COUNT_AVERAGE)
{
axis.x = axis_average.x_average / axis_average.count;
axis.y = axis_average.y_average / axis_average.count;
axis.z = axis_average.z_average / axis_average.count;
DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
memset(&axis_average, 0, sizeof(struct sensor_axis_average));
//Report event only while value is changed to save some power
if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
{
gsensor_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
struct sensor_operate gsensor_dmard10_ops = {
.name = "gs_dmard10",
.type = SENSOR_TYPE_ACCEL, //sensor type and it should be correct
.id_i2c = ACCEL_ID_DMARD10, //i2c id number
.read_reg = DMARD10_REG_X_OUT, //read data
.read_len = 8, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = DMARD10_PRECISION, //12 bit
.ctrl_reg = DMARD10_REG_MODE, //enable or disable
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
.range = {-DMARD10_RANGE,DMARD10_RANGE}, //range
.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 *gsensor_get_ops(void)
{
return &gsensor_dmard10_ops;
}
static int __init gsensor_dmard10_init(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
return result;
}
static void __exit gsensor_dmard10_exit(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);
}
module_init(gsensor_dmard10_init);
module_exit(gsensor_dmard10_exit);
/* drivers/input/sensors/access/dmard10.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: guoyi <gy@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
/* Default register settings */
#define RBUFF_SIZE 12 /* Rx buffer size */
#define REG_ACTR 0x00
#define REG_WDAL 0x01
#define REG_TAPNS 0x0f
#define REG_MISC2 0x1f
#define REG_AFEM 0x0c
#define REG_CKSEL 0x0d
#define REG_INTC 0x0e
#define REG_STADR 0x12
#define REG_STAINT 0x1C
#define REG_PD 0x21
#define REG_TCGYZ 0x26
#define REG_X_OUT 0x41
#define MODE_Off 0x00
#define MODE_ResetAtOff 0x01
#define MODE_Standby 0x02
#define MODE_ResetAtStandby 0x03
#define MODE_Active 0x06
#define MODE_Trigger 0x0a
#define MODE_ReadOTP 0x12
#define MODE_WriteOTP 0x22
#define MODE_WriteOTPBuf 0x42
#define MODE_ResetDataPath 0x82
#define VALUE_STADR 0x55
#define VALUE_STAINT 0xAA
#define VALUE_AFEM_AFEN_Normal 0x8f// AFEN set 1 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
#define VALUE_AFEM_Normal 0x0f// AFEN set 0 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
#define VALUE_INTC 0x00// INTC[6:5]=b'00
#define VALUE_INTC_Interrupt_En 0x20// INTC[6:5]=b'01 (Data ready interrupt enable, active high at INT0)
#define VALUE_CKSEL_ODR_0_204 0x04// ODR[3:0]=b'0000 (0.78125Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_1_204 0x14// ODR[3:0]=b'0001 (1.5625Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_3_204 0x24// ODR[3:0]=b'0010 (3.125Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_6_204 0x34// ODR[3:0]=b'0011 (6.25Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_12_204 0x44// ODR[3:0]=b'0100 (12.5Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_25_204 0x54// ODR[3:0]=b'0101 (25Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_50_204 0x64// ODR[3:0]=b'0110 (50Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_CKSEL_ODR_100_204 0x74// ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ)
#define VALUE_TAPNS_NoFilter 0x00 // TAP1/TAP2 NO FILTER
#define VALUE_TAPNS_Ave_2 0x11 // TAP1/TAP2 Average 2
#define VALUE_TAPNS_Ave_4 0x22 // TAP1/TAP2 Average 4
#define VALUE_TAPNS_Ave_8 0x33 // TAP1/TAP2 Average 8
#define VALUE_TAPNS_Ave_16 0x44 // TAP1/TAP2 Average 16
#define VALUE_TAPNS_Ave_32 0x55 // TAP1/TAP2 Average 32
#define VALUE_MISC2_OSCA_EN 0x08
#define VALUE_PD_RST 0x52
//#define DMARD10_REG_INTSU 0x47
//#define DMARD10_REG_MODE 0x44
//#define DMARD10_REG_SR 0x44
#define DMARD10_REG_DS 0X49
#define DMARD10_REG_ID 0X0F
#define DMARD10_REG_IT 0X4D
#define DMARD10_REG_INTSRC1_C 0X4A
#define DMARD10_REG_INTSRC1_S 0X4B
#define MMAIO 0xA1
// IOCTLs for DMARD10 library
#define ECS_IOCTL_INIT _IO(MMAIO, 0x01)
#define ECS_IOCTL_RESET _IO(MMAIO, 0x04)
#define ECS_IOCTL_CLOSE _IO(MMAIO, 0x02)
#define ECS_IOCTL_START _IO(MMAIO, 0x03)
#define ECS_IOCTL_GETDATA _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])
#define SENSOR_CALIBRATION _IOWR(MMAIO, 0x05 , int[SENSOR_DATA_SIZE])
// IOCTLs for APPs
#define ECS_IOCTL_APP_SET_RATE _IOW(MMAIO, 0x10, char)
//rate
#define DMARD10_RANGE 2000000
#define DMARD10_RATE_32 32
/*
#define DMARD10_RATE_64 64
#define DMARD10_RATE_120 128
#define DMARD10_RATE_MIN DMARD10_RATE_1
#define DMARD10_RATE_MAX DMARD10_RATE_120
*/
/*status*/
#define DMARD10_OPEN 1
#define DMARD10_CLOSE 0
#define DMARD10_NORMAL 2
#define DMARD10_LOWPOWER 3
#define DMARD10_IIC_ADDR 0x18
#define DMARD10_REG_LEN 11
#define DMARD10_FATOR 15
#define DMARD10_X_OUT 0x41
#define SENSOR_DATA_SIZE 3
#define DMARD10_SENSOR_RATE_1 0
#define DMARD10_SENSOR_RATE_2 1
#define DMARD10_SENSOR_RATE_3 2
#define DMARD10_SENSOR_RATE_4 3
#define POWER_OR_RATE 1
#define SW_RESET 1
#define DMARD10_INTERRUPUT 1
#define DMARD10_POWERDOWN 0
#define DMARD10_POWERON 1
//g-senor layout configuration, choose one of the following configuration
#define AVG_NUM 16
#define SENSOR_DATA_SIZE 3
#define DEFAULT_SENSITIVITY 1024
#define DMARD10_ENABLE 1
#define DMARD10_REG_X_OUT 0x12
#define DMARD10_REG_Y_OUT 0x1
#define DMARD10_REG_Z_OUT 0x2
#define DMARD10_REG_TILT 0x3
#define DMARD10_REG_SRST 0x4
#define DMARD10_REG_SPCNT 0x5
#define DMARD10_REG_INTSU 0x6
#define DMARD10_REG_MODE 0x7
#define DMARD10_REG_SR 0x8
#define DMARD10_REG_PDET 0x9
#define DMARD10_REG_PD 0xa
#define DMARD10_RANGE 4000000
#define DMARD10_PRECISION 10
#define DMARD10_BOUNDARY (0x1 << (DMARD10_PRECISION - 1))
#define DMARD10_GRAVITY_STEP (DMARD10_RANGE / DMARD10_BOUNDARY)
struct sensor_axis_average {
int x_average;
int y_average;
int z_average;
int count;
};
static struct sensor_axis_average axis_average;
int gsensor_reset(struct i2c_client *client){
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
char buffer[7], buffer2[2];
/* 1. check D10 , VALUE_STADR = 0x55 , VALUE_STAINT = 0xAA */
buffer[0] = REG_STADR;
buffer2[0] = REG_STAINT;
sensor_rx_data(client, buffer, 2);
sensor_rx_data(client, buffer2, 2);
if( buffer[0] == VALUE_STADR || buffer2[0] == VALUE_STAINT){
DBG(KERN_INFO " REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d\n", buffer[0], buffer2[0]);
DBG(KERN_INFO " %s DMT_DEVICE_NAME registered I2C driver!\n",__FUNCTION__);
}
else{
DBG(KERN_INFO " %s gsensor I2C err @@@ REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d \n", __func__, buffer[0], buffer2[0]);
return -1;
}
/* 2. Powerdown reset */
buffer[0] = REG_PD;
buffer[1] = VALUE_PD_RST;
sensor_tx_data(client, buffer, 2);
/* 3. ACTR => Standby mode => Download OTP to parameter reg => Standby mode => Reset data path => Standby mode */
buffer[0] = REG_ACTR;
buffer[1] = MODE_Standby;
buffer[2] = MODE_ReadOTP;
buffer[3] = MODE_Standby;
buffer[4] = MODE_ResetDataPath;
buffer[5] = MODE_Standby;
sensor_tx_data(client, buffer, 6);
/* 4. OSCA_EN = 1 ,TSTO = b'000(INT1 = normal, TEST0 = normal) */
buffer[0] = REG_MISC2;
buffer[1] = VALUE_MISC2_OSCA_EN;
sensor_tx_data(client, buffer, 2);
/* 5. AFEN = 1(AFE will powerdown after ADC) */
buffer[0] = REG_AFEM;
buffer[1] = VALUE_AFEM_AFEN_Normal;
buffer[2] = VALUE_CKSEL_ODR_100_204;
buffer[3] = VALUE_INTC;
buffer[4] = VALUE_TAPNS_Ave_2;
buffer[5] = 0x00; // DLYC, no delay timing
buffer[6] = 0x07; // INTD=1 (push-pull), INTA=1 (active high), AUTOT=1 (enable T)
sensor_tx_data(client, buffer, 7);
/* 6. write TCGYZ & TCGX */
buffer[0] = REG_WDAL; // REG:0x01
buffer[1] = 0x00; // set TC of Y,Z gain value
buffer[2] = 0x00; // set TC of X gain value
buffer[3] = 0x03; // Temperature coefficient of X,Y,Z gain
sensor_tx_data(client, buffer, 4);
buffer[0] = REG_ACTR; // REG:0x00
buffer[1] = MODE_Standby; // Standby
buffer[2] = MODE_WriteOTPBuf; // WriteOTPBuf
buffer[3] = MODE_Standby; // Standby
/* 7. Activation mode */
buffer[0] = REG_ACTR;
buffer[1] = MODE_Active;
sensor_tx_data(client, buffer, 2);
printk("\n dmard10 gsensor _reset SUCCESS!!\n");
return 0;
}
/****************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;
gsensor_reset(client);
sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
status = DMARD10_ENABLE; //dmard10
sensor->ops->ctrl_data |= status;
}
else
{
status = ~DMARD10_ENABLE; //dmard10
sensor->ops->ctrl_data &= status;
}
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;
DBG("%s:DMARD10_REG_TILT=0x%x\n",__func__,sensor_read_reg(client, DMARD10_REG_TILT));
result = sensor_write_reg(client, DMARD10_REG_SR, (0x01<<5)| 0x02); //32 Samples/Second Active and Auto-Sleep Mode
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
if(sensor->pdata->irq_enable) //open interrupt
{
result = sensor_write_reg(client, DMARD10_REG_INTSU, 1<<4);//enable int,GINT=1
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
sensor->ops->ctrl_data = 1<<6; //Interrupt output INT is push-pull
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
memset(&axis_average, 0, sizeof(struct sensor_axis_average));
return result;
}
static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
{
s64 result;
result = ((int)high_byte << 8)|((int)low_byte);
if (result < DMARD10_BOUNDARY){
result = result* DMARD10_GRAVITY_STEP;
}else{
result = ~( ((~result & (0x7fff>>(16-DMARD10_PRECISION)) ) + 1)* DMARD10_GRAVITY_STEP) + 1;
}
return result;
}
static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report acceleration sensor information */
input_report_abs(sensor->input_dev, ABS_X, axis->x);
input_report_abs(sensor->input_dev, ABS_Y, axis->y);
input_report_abs(sensor->input_dev, ABS_Z, axis->z);
input_sync(sensor->input_dev);
DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
#define DMARD10_COUNT_AVERAGE 2
#define GSENSOR_MIN 2
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x,y,z;
struct sensor_axis axis;
char buffer[8] = {0};
char value = 0;
if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 8);
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
*buffer = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
//this gsensor need 6 bytes buffer
x = sensor_convert_data(sensor->client, buffer[3], buffer[2]); //buffer[1]:high bit
y = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
z = sensor_convert_data(sensor->client, buffer[7], buffer[6]);
axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
axis_average.x_average += axis.x;
axis_average.y_average += axis.y;
axis_average.z_average += axis.z;
axis_average.count++;
if(axis_average.count >= DMARD10_COUNT_AVERAGE)
{
axis.x = axis_average.x_average / axis_average.count;
axis.y = axis_average.y_average / axis_average.count;
axis.z = axis_average.z_average / axis_average.count;
DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
memset(&axis_average, 0, sizeof(struct sensor_axis_average));
//Report event only while value is changed to save some power
if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
{
gsensor_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
struct sensor_operate gsensor_dmard10_ops = {
.name = "gs_dmard10",
.type = SENSOR_TYPE_ACCEL, //sensor type and it should be correct
.id_i2c = ACCEL_ID_DMARD10, //i2c id number
.read_reg = DMARD10_REG_X_OUT, //read data
.read_len = 8, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = DMARD10_PRECISION, //12 bit
.ctrl_reg = DMARD10_REG_MODE, //enable or disable
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
.range = {-DMARD10_RANGE,DMARD10_RANGE}, //range
.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 *gsensor_get_ops(void)
{
return &gsensor_dmard10_ops;
}
static int __init gsensor_dmard10_init(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
return result;
}
static void __exit gsensor_dmard10_exit(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);
}
module_init(gsensor_dmard10_init);
module_exit(gsensor_dmard10_exit);

View File

@@ -1,366 +1,366 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: Bruins <xwj@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define LSM303D_WHO_AM_I (0x0F)
/* full scale setting - register & mask */
#define LSM303D_CTRL_REG0 (0x1F)
#define LSM303D_CTRL_REG1 (0x20)
#define LSM303D_CTRL_REG2 (0x21)
#define LSM303D_CTRL_REG3 (0x22)
#define LSM303D_CTRL_REG4 (0x23)
#define LSM303D_CTRL_REG5 (0x24)
#define LSM303D_CTRL_REG6 (0x25)
#define LSM303D_CTRL_REG7 (0x26)
#define LSM303D_STATUS_REG (0x27)
#define LSM303D_OUT_X_L (0x28)
#define LSM303D_OUT_X_H (0x29)
#define LSM303D_OUT_Y_L (0x2a)
#define LSM303D_OUT_Y_H (0x2b)
#define LSM303D_OUT_Z_L (0x2c)
#define LSM303D_OUT_Z_H (0x2d)
#define LSM303D_FIFO_CTRL_REG (0x2E)
#define LSM303D_FIFO_SRC_REG (0X2F)
#define LSM303D_IG_CFG1 (0x30)
#define LSM303D_IG_SRC1 (0x31)
#define LSM303D_IG_THS1 (0x32)
#define LSM303D_IG_DURATION1 (0x33)
#define LSM303D_IG_CFG2 (0x34)
#define LSM303D_IG_SRC2 (0x35)
#define LSM303D_IG_THS2 (0x36)
#define LSM303D_IG_DURATION2 (0x37)
#define LSM303D_DEVID (0x49) //chip id
#define LSM303D_ACC_DISABLE (0x08)
#define LSM303D_RANGE 2000000
/* LSM303D */
#define LSM303D_PRECISION 16
#define LSM303D_BOUNDARY (0x1 << (LSM303D_PRECISION - 1))
#define LSM303D_GRAVITY_STEP (LSM303D_RANGE / LSM303D_BOUNDARY)
#define ODR3P25 0x10 /* 3.25Hz output data rate */
#define ODR6P25 0x20 /* 6.25Hz output data rate */
#define ODR12P5 0x30 /* 12.5Hz output data rate */
#define ODR25 0x40 /* 25Hz output data rate */
#define ODR50 0x50 /* 50Hz output data rate */
#define ODR100 0x60 /* 100Hz output data rate */
#define ODR200 0x70 /* 200Hz output data rate */
#define ODR400 0x80 /* 400Hz output data rate */
#define ODR800 0x90 /* 800Hz output data rate */
#define ODR1600 0xA0 /* 1600Hz output data rate */
struct sensor_reg_data {
char reg;
char data;
};
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
sensor->ops->ctrl_data |= ODR100; //100HZ,if 0 then power down
//register setting according to chip datasheet
if(!enable)
{
status = LSM303D_ACC_DISABLE; //lis3dh
sensor->ops->ctrl_data |= status;
}
else
{
status = ~LSM303D_ACC_DISABLE; //lis3dh
sensor->ops->ctrl_data &= status;
}
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;
int i;
struct sensor_reg_data reg_data[] =
{
{LSM303D_CTRL_REG0,0x00},
{LSM303D_CTRL_REG1,0x07},
{LSM303D_CTRL_REG2,0x00},
{LSM303D_CTRL_REG3,0x00},
{LSM303D_CTRL_REG4,0x00},
{LSM303D_CTRL_REG5,0x78}, //High resolution output mode:11,
{LSM303D_CTRL_REG6,0x20},
{LSM303D_CTRL_REG7,0x00},
{LSM303D_FIFO_CTRL_REG,0x00},
{LSM303D_IG_CFG1,0xFF}, //6 direction position recognition
{LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold
{LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f
/*
{LSM303D_CTRL_REG7,0x00},
{LSM303D_CTRL_REG4,0x08}, //High resolution output mode: 1, Normal mode
{LSM303D_CTRL_REG6,0x40},
{LSM303D_FIFO_CTRL_REG,0x00}, //
{LSM303D_IG_CFG1,0xFF}, //6 direction position recognition
{LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold
{LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f
*/
};
result = sensor->ops->active(client,0,0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->status_cur = SENSOR_OFF;
for(i=0;i<(sizeof(reg_data)/sizeof(struct sensor_reg_data));i++)
{
result = sensor_write_reg(client, reg_data[i].reg, reg_data[i].data);
if(result)
{
printk("%s:line=%d,i=%d,error\n",__func__,__LINE__,i);
return result;
}
}
if(sensor->pdata->irq_enable)
{
result = sensor_write_reg(client, LSM303D_CTRL_REG3, 0x20);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
i = sensor_read_reg(client,LSM303D_CTRL_REG5);
result = sensor_write_reg(client, LSM303D_CTRL_REG5, (i|0x01));
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
return result;
}
static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
{
s64 result;
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
switch (sensor->devid) {
case LSM303D_DEVID:
result = ((int)high_byte << 8) | (int)low_byte;
if (result < LSM303D_BOUNDARY)
result = result* LSM303D_GRAVITY_STEP;
else
result = ~( ((~result & (0x7fff>>(16-LSM303D_PRECISION)) ) + 1)
* LSM303D_GRAVITY_STEP) + 1;
break;
default:
printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);
return -EFAULT;
}
return (int)result;
}
static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report acceleration sensor information */
input_report_abs(sensor->input_dev, ABS_X, axis->x);
input_report_abs(sensor->input_dev, ABS_Y, axis->y);
input_report_abs(sensor->input_dev, ABS_Z, axis->z);
input_sync(sensor->input_dev);
DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
#define GSENSOR_MIN 10
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x,y,z;
struct sensor_axis axis;
char buffer[6] = {0};
char value = 0;
if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 6);
value = sensor_read_reg(client, LSM303D_STATUS_REG);
if((value & 0x0f) == 0)
{
printk("%s:line=%d,value=0x%x,data is not ready\n",__func__,__LINE__,value);
return -1;
}
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
*buffer = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
//this gsensor need 6 bytes buffer
x = sensor_convert_data(sensor->client, buffer[1], buffer[0]); //buffer[1]:high bit
y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);
z = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
//printk( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
//Report event only while value is changed to save some power
if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
{
gsensor_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
struct sensor_operate gsensor_lsm303d_ops = {
.name = "lsm303d",
.type = SENSOR_TYPE_ACCEL, //sensor type and it should be correct
.id_i2c = ACCEL_ID_LSM303D, //i2c id number
.read_reg = (LSM303D_OUT_X_L | 0x80), //read data
.read_len = 6, //data length
.id_reg = LSM303D_WHO_AM_I, //read device id from this register
.id_data = LSM303D_DEVID, //device id
.precision = LSM303D_PRECISION, //16 bits
.ctrl_reg = LSM303D_CTRL_REG1, //enable or disable
.int_status_reg = LSM303D_IG_SRC1, //intterupt status register
.range = {-LSM303D_RANGE,LSM303D_RANGE}, //range
.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 *gsensor_get_ops(void)
{
return &gsensor_lsm303d_ops;
}
static int __init gsensor_lis3dh_init(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
return result;
}
static void __exit gsensor_lis3dh_exit(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);
}
module_init(gsensor_lis3dh_init);
module_exit(gsensor_lis3dh_exit);
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: Bruins <xwj@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define LSM303D_WHO_AM_I (0x0F)
/* full scale setting - register & mask */
#define LSM303D_CTRL_REG0 (0x1F)
#define LSM303D_CTRL_REG1 (0x20)
#define LSM303D_CTRL_REG2 (0x21)
#define LSM303D_CTRL_REG3 (0x22)
#define LSM303D_CTRL_REG4 (0x23)
#define LSM303D_CTRL_REG5 (0x24)
#define LSM303D_CTRL_REG6 (0x25)
#define LSM303D_CTRL_REG7 (0x26)
#define LSM303D_STATUS_REG (0x27)
#define LSM303D_OUT_X_L (0x28)
#define LSM303D_OUT_X_H (0x29)
#define LSM303D_OUT_Y_L (0x2a)
#define LSM303D_OUT_Y_H (0x2b)
#define LSM303D_OUT_Z_L (0x2c)
#define LSM303D_OUT_Z_H (0x2d)
#define LSM303D_FIFO_CTRL_REG (0x2E)
#define LSM303D_FIFO_SRC_REG (0X2F)
#define LSM303D_IG_CFG1 (0x30)
#define LSM303D_IG_SRC1 (0x31)
#define LSM303D_IG_THS1 (0x32)
#define LSM303D_IG_DURATION1 (0x33)
#define LSM303D_IG_CFG2 (0x34)
#define LSM303D_IG_SRC2 (0x35)
#define LSM303D_IG_THS2 (0x36)
#define LSM303D_IG_DURATION2 (0x37)
#define LSM303D_DEVID (0x49) //chip id
#define LSM303D_ACC_DISABLE (0x08)
#define LSM303D_RANGE 2000000
/* LSM303D */
#define LSM303D_PRECISION 16
#define LSM303D_BOUNDARY (0x1 << (LSM303D_PRECISION - 1))
#define LSM303D_GRAVITY_STEP (LSM303D_RANGE / LSM303D_BOUNDARY)
#define ODR3P25 0x10 /* 3.25Hz output data rate */
#define ODR6P25 0x20 /* 6.25Hz output data rate */
#define ODR12P5 0x30 /* 12.5Hz output data rate */
#define ODR25 0x40 /* 25Hz output data rate */
#define ODR50 0x50 /* 50Hz output data rate */
#define ODR100 0x60 /* 100Hz output data rate */
#define ODR200 0x70 /* 200Hz output data rate */
#define ODR400 0x80 /* 400Hz output data rate */
#define ODR800 0x90 /* 800Hz output data rate */
#define ODR1600 0xA0 /* 1600Hz output data rate */
struct sensor_reg_data {
char reg;
char data;
};
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
sensor->ops->ctrl_data |= ODR100; //100HZ,if 0 then power down
//register setting according to chip datasheet
if(!enable)
{
status = LSM303D_ACC_DISABLE; //lis3dh
sensor->ops->ctrl_data |= status;
}
else
{
status = ~LSM303D_ACC_DISABLE; //lis3dh
sensor->ops->ctrl_data &= status;
}
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;
int i;
struct sensor_reg_data reg_data[] =
{
{LSM303D_CTRL_REG0,0x00},
{LSM303D_CTRL_REG1,0x07},
{LSM303D_CTRL_REG2,0x00},
{LSM303D_CTRL_REG3,0x00},
{LSM303D_CTRL_REG4,0x00},
{LSM303D_CTRL_REG5,0x78}, //High resolution output mode:11,
{LSM303D_CTRL_REG6,0x20},
{LSM303D_CTRL_REG7,0x00},
{LSM303D_FIFO_CTRL_REG,0x00},
{LSM303D_IG_CFG1,0xFF}, //6 direction position recognition
{LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold
{LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f
/*
{LSM303D_CTRL_REG7,0x00},
{LSM303D_CTRL_REG4,0x08}, //High resolution output mode: 1, Normal mode
{LSM303D_CTRL_REG6,0x40},
{LSM303D_FIFO_CTRL_REG,0x00}, //
{LSM303D_IG_CFG1,0xFF}, //6 direction position recognition
{LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold
{LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f
*/
};
result = sensor->ops->active(client,0,0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->status_cur = SENSOR_OFF;
for(i=0;i<(sizeof(reg_data)/sizeof(struct sensor_reg_data));i++)
{
result = sensor_write_reg(client, reg_data[i].reg, reg_data[i].data);
if(result)
{
printk("%s:line=%d,i=%d,error\n",__func__,__LINE__,i);
return result;
}
}
if(sensor->pdata->irq_enable)
{
result = sensor_write_reg(client, LSM303D_CTRL_REG3, 0x20);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
i = sensor_read_reg(client,LSM303D_CTRL_REG5);
result = sensor_write_reg(client, LSM303D_CTRL_REG5, (i|0x01));
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
return result;
}
static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
{
s64 result;
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
switch (sensor->devid) {
case LSM303D_DEVID:
result = ((int)high_byte << 8) | (int)low_byte;
if (result < LSM303D_BOUNDARY)
result = result* LSM303D_GRAVITY_STEP;
else
result = ~( ((~result & (0x7fff>>(16-LSM303D_PRECISION)) ) + 1)
* LSM303D_GRAVITY_STEP) + 1;
break;
default:
printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);
return -EFAULT;
}
return (int)result;
}
static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report acceleration sensor information */
input_report_abs(sensor->input_dev, ABS_X, axis->x);
input_report_abs(sensor->input_dev, ABS_Y, axis->y);
input_report_abs(sensor->input_dev, ABS_Z, axis->z);
input_sync(sensor->input_dev);
DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
#define GSENSOR_MIN 10
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x,y,z;
struct sensor_axis axis;
char buffer[6] = {0};
char value = 0;
if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 6);
value = sensor_read_reg(client, LSM303D_STATUS_REG);
if((value & 0x0f) == 0)
{
printk("%s:line=%d,value=0x%x,data is not ready\n",__func__,__LINE__,value);
return -1;
}
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
*buffer = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
//this gsensor need 6 bytes buffer
x = sensor_convert_data(sensor->client, buffer[1], buffer[0]); //buffer[1]:high bit
y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);
z = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
//printk( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
//Report event only while value is changed to save some power
if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
{
gsensor_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
struct sensor_operate gsensor_lsm303d_ops = {
.name = "lsm303d",
.type = SENSOR_TYPE_ACCEL, //sensor type and it should be correct
.id_i2c = ACCEL_ID_LSM303D, //i2c id number
.read_reg = (LSM303D_OUT_X_L | 0x80), //read data
.read_len = 6, //data length
.id_reg = LSM303D_WHO_AM_I, //read device id from this register
.id_data = LSM303D_DEVID, //device id
.precision = LSM303D_PRECISION, //16 bits
.ctrl_reg = LSM303D_CTRL_REG1, //enable or disable
.int_status_reg = LSM303D_IG_SRC1, //intterupt status register
.range = {-LSM303D_RANGE,LSM303D_RANGE}, //range
.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 *gsensor_get_ops(void)
{
return &gsensor_lsm303d_ops;
}
static int __init gsensor_lis3dh_init(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
return result;
}
static void __exit gsensor_lis3dh_exit(void)
{
struct sensor_operate *ops = gsensor_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);
}
module_init(gsensor_lis3dh_init);
module_exit(gsensor_lis3dh_exit);

View File

@@ -1,2 +1,2 @@
obj-$(CONFIG_ANGLE_KXTIK) += angle_kxtik.o
obj-$(CONFIG_ANGLE_LIS3DH) += angle_lis3dh.o
obj-$(CONFIG_ANGLE_KXTIK) += angle_kxtik.o
obj-$(CONFIG_ANGLE_LIS3DH) += angle_lis3dh.o

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,460 +1,460 @@
/* drivers/input/sensors/gyro/Ewtsa.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: zhangaihui <zah@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
/** This define controls compilation of the master device interface */
/*#define EWTSA_MASTER_DEVICE*/
/* configurable */
#define GYRO_MOUNT_SWAP_XY 0 /* swap X, Y */
#define GYRO_MOUNT_REVERSE_X 0 /* reverse X */
#define GYRO_MOUNT_REVERSE_Y 0 /* reverse Y */
#define GYRO_MOUNT_REVERSE_Z 0 /* reverse Z */
/* macro defines */
/*#define CHIP_ID 0x68*/
#define DEVICE_NAME "ewtsa"
#define EWTSA_ON 1
#define EWTSA_OFF 0
#define SLEEP_PIN 14
#define DRDY_PIN 12
#define DIAG_PIN 11
#define MAX_VALUE 32768
/* ewtsa_delay parameter */
#define DELAY_THRES_MIN 1
#define DELAY_THRES_1 4
#define DELAY_THRES_2 9 /* msec x 90% */
#define DELAY_THRES_3 18
#define DELAY_THRES_4 45
#define DELAY_THRES_5 90
#define DELAY_THRES_6 128
#define DELAY_THRES_MAX 255
#define DELAY_DLPF_2 2
#define DELAY_DLPF_3 3
#define DELAY_DLPF_4 4
#define DELAY_DLPF_5 5
#define DELAY_DLPF_6 6
#define DELAY_INTMIN_THRES 9
#define DATA_RATE_1 0x01
/* ewtsa_sleep parameter */
#define SLEEP_OFF 0
#define SLEEP_ON 1
/* event mode */
#define EWTSA_POLLING_MODE 0
#define EWTSA_INTERUPT_MODE 1
/* ewtsa register address */
#define REG_SMPL 0x15
#define REG_FS_DLPF 0x16
#define REG_INT_CFG 0x17
#define REG_INT_STATUS 0x1A
#define REG_SELF_O_C 0x29
#define REG_PWR_MGM 0x3E
#define REG_MBURST_ALL 0xFF
#define GYRO_DATA_REG 0x1D
/* ewtsa register param */
#define SELF_O_C_ENABLE 0x00
#define SELF_O_C_DISABLE 0x01
#define SLEEP_CTRL_ACTIVATE 0x40
#define SLEEP_CTRL_SLEEP 0x00
#define INT_CFG_INT_ENABLE 0x01
#define INT_CFG_INT_DISABLE 0x00
/* ewtsa interrupt control */
#define EWSTA_INT_CLEAR 0x00
#define EWSTA_INT_SKIP 0x01
/* wait time(ms)*/
#define EWTSA_BOOST_TIME_0 500
/* sleep setting range */
#define EWTSA_SLP_MIN 0
#define EWTSA_SLP_MAX 1
/* delay setting range */
#define EWTSA_DLY_MIN 1
#define EWTSA_DLY_MAX 255
/* range setting range */
#define EWTSA_RNG_MIN 0
#define EWTSA_RNG_MAX 3
/* soc setting range */
#define EWTSA_SOC_MIN 0
#define EWTSA_SOC_MAX 1
/* event setting range */
#define EWTSA_EVE_MIN 0
#define EWTSA_EVE_MAX 1
/* init param */
#define SLEEP_INIT_VAL (SLEEP_ON)
#define DELAY_INIT_VAL 10
#define RANGE_INIT_VAL 2 /*range 1000*/
#define DLPF_INIT_VAL (DELAY_DLPF_2)
#define CALIB_FUNC_INIT_VAL (EWTSA_ON)
/*config store counter num*/
#define CONFIG_COUNTER_MIN (6+9)
#define CONFIG_COUNTER_MAX (32+9)
/*command name */
#define COMMAND_NAME_SOC 0
#define COMMAND_NAME_DLY 1
#define COMMAND_NAME_RNG 2
#define COMMAND_NAME_EVE 3
#define COMMAND_NAME_SLP 4
#define COMMAND_NAME_NUM 5
#define EWTSA_delay DELAY_INIT_VAL
#define EWTSA_range RANGE_INIT_VAL
#define EWTSA_calib EWTSA_ON
/****************operate according to sensor chip:start************/
static int i2c_read_byte(struct i2c_client *thisClient, unsigned char regAddr, char *pReadData)
/* drivers/input/sensors/gyro/Ewtsa.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: zhangaihui <zah@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
/** This define controls compilation of the master device interface */
/*#define EWTSA_MASTER_DEVICE*/
/* configurable */
#define GYRO_MOUNT_SWAP_XY 0 /* swap X, Y */
#define GYRO_MOUNT_REVERSE_X 0 /* reverse X */
#define GYRO_MOUNT_REVERSE_Y 0 /* reverse Y */
#define GYRO_MOUNT_REVERSE_Z 0 /* reverse Z */
/* macro defines */
/*#define CHIP_ID 0x68*/
#define DEVICE_NAME "ewtsa"
#define EWTSA_ON 1
#define EWTSA_OFF 0
#define SLEEP_PIN 14
#define DRDY_PIN 12
#define DIAG_PIN 11
#define MAX_VALUE 32768
/* ewtsa_delay parameter */
#define DELAY_THRES_MIN 1
#define DELAY_THRES_1 4
#define DELAY_THRES_2 9 /* msec x 90% */
#define DELAY_THRES_3 18
#define DELAY_THRES_4 45
#define DELAY_THRES_5 90
#define DELAY_THRES_6 128
#define DELAY_THRES_MAX 255
#define DELAY_DLPF_2 2
#define DELAY_DLPF_3 3
#define DELAY_DLPF_4 4
#define DELAY_DLPF_5 5
#define DELAY_DLPF_6 6
#define DELAY_INTMIN_THRES 9
#define DATA_RATE_1 0x01
/* ewtsa_sleep parameter */
#define SLEEP_OFF 0
#define SLEEP_ON 1
/* event mode */
#define EWTSA_POLLING_MODE 0
#define EWTSA_INTERUPT_MODE 1
/* ewtsa register address */
#define REG_SMPL 0x15
#define REG_FS_DLPF 0x16
#define REG_INT_CFG 0x17
#define REG_INT_STATUS 0x1A
#define REG_SELF_O_C 0x29
#define REG_PWR_MGM 0x3E
#define REG_MBURST_ALL 0xFF
#define GYRO_DATA_REG 0x1D
/* ewtsa register param */
#define SELF_O_C_ENABLE 0x00
#define SELF_O_C_DISABLE 0x01
#define SLEEP_CTRL_ACTIVATE 0x40
#define SLEEP_CTRL_SLEEP 0x00
#define INT_CFG_INT_ENABLE 0x01
#define INT_CFG_INT_DISABLE 0x00
/* ewtsa interrupt control */
#define EWSTA_INT_CLEAR 0x00
#define EWSTA_INT_SKIP 0x01
/* wait time(ms)*/
#define EWTSA_BOOST_TIME_0 500
/* sleep setting range */
#define EWTSA_SLP_MIN 0
#define EWTSA_SLP_MAX 1
/* delay setting range */
#define EWTSA_DLY_MIN 1
#define EWTSA_DLY_MAX 255
/* range setting range */
#define EWTSA_RNG_MIN 0
#define EWTSA_RNG_MAX 3
/* soc setting range */
#define EWTSA_SOC_MIN 0
#define EWTSA_SOC_MAX 1
/* event setting range */
#define EWTSA_EVE_MIN 0
#define EWTSA_EVE_MAX 1
/* init param */
#define SLEEP_INIT_VAL (SLEEP_ON)
#define DELAY_INIT_VAL 10
#define RANGE_INIT_VAL 2 /*range 1000*/
#define DLPF_INIT_VAL (DELAY_DLPF_2)
#define CALIB_FUNC_INIT_VAL (EWTSA_ON)
/*config store counter num*/
#define CONFIG_COUNTER_MIN (6+9)
#define CONFIG_COUNTER_MAX (32+9)
/*command name */
#define COMMAND_NAME_SOC 0
#define COMMAND_NAME_DLY 1
#define COMMAND_NAME_RNG 2
#define COMMAND_NAME_EVE 3
#define COMMAND_NAME_SLP 4
#define COMMAND_NAME_NUM 5
#define EWTSA_delay DELAY_INIT_VAL
#define EWTSA_range RANGE_INIT_VAL
#define EWTSA_calib EWTSA_ON
/****************operate according to sensor chip:start************/
static int i2c_read_byte(struct i2c_client *thisClient, unsigned char regAddr, char *pReadData)
{
int ret = 0;
ret = i2c_master_send( thisClient, (char*)&regAddr, 1);
if(ret < 0)
{
printk("EWTSA send cAddress=0x%x error!\n", regAddr);
printk("EWTSA send cAddress=0x%x error!\n", regAddr);
return ret;
}
ret = i2c_master_recv( thisClient, (char*)pReadData, 1);
if(ret < 0)
{
printk("EWTSAread *pReadData=0x%x error!\n", *pReadData);
printk("EWTSAread *pReadData=0x%x error!\n", *pReadData);
return ret;
}
return 1;
}
static int i2c_write_byte(struct i2c_client *thisClient, unsigned char regAddr, unsigned char writeData)
}
static int i2c_write_byte(struct i2c_client *thisClient, unsigned char regAddr, unsigned char writeData)
{
char write_data[2] = {0};
int ret=0;
write_data[0] = regAddr;
write_data[1] = writeData;
ret = i2c_master_send(thisClient, write_data, 2);
if (ret < 0)
if (ret < 0)
{
ret = i2c_master_send(thisClient, write_data, 2);
if (ret < 0)
if (ret < 0)
{
printk("EWTSA send regAddr=0x%x error!\n", regAddr);
printk("EWTSA send regAddr=0x%x error!\n", regAddr);
return ret;
}
return 1;
}
return 1;
}
static int ewtsa_system_restart(struct i2c_client *client)
}
static int ewtsa_system_restart(struct i2c_client *client)
{
int err;
char reg;
char smpl , dlpf;
err = i2c_write_byte(client, ( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_DISABLE);
char reg;
char smpl , dlpf;
err = i2c_write_byte(client, ( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_DISABLE);
if (err < 0) {
return err;
}
///Set SMPL register
if (EWTSA_delay <= ( unsigned char)DELAY_THRES_2) {
smpl = ( unsigned char)DELAY_INTMIN_THRES;
if (EWTSA_delay <= ( unsigned char)DELAY_THRES_2) {
smpl = ( unsigned char)DELAY_INTMIN_THRES;
}else{
smpl = ( unsigned char)(EWTSA_delay - ( unsigned char)1);
}
err = i2c_write_byte(client, ( unsigned char)REG_SMPL, ( unsigned char)smpl);
smpl = ( unsigned char)(EWTSA_delay - ( unsigned char)1);
}
err = i2c_write_byte(client, ( unsigned char)REG_SMPL, ( unsigned char)smpl);
if (err < 0) {
return err;
}
///Set DLPF register
if (EWTSA_delay >= ( unsigned char)DELAY_THRES_6){
dlpf = ( unsigned char)DELAY_DLPF_6;
}else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_5) {
dlpf = ( unsigned char)DELAY_DLPF_5;
}else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_4){
dlpf = ( unsigned char)DELAY_DLPF_4;
}else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_3) {
dlpf = ( unsigned char)DELAY_DLPF_3;
if (EWTSA_delay >= ( unsigned char)DELAY_THRES_6){
dlpf = ( unsigned char)DELAY_DLPF_6;
}else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_5) {
dlpf = ( unsigned char)DELAY_DLPF_5;
}else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_4){
dlpf = ( unsigned char)DELAY_DLPF_4;
}else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_3) {
dlpf = ( unsigned char)DELAY_DLPF_3;
}else{
dlpf = ( unsigned char)DELAY_DLPF_2;
dlpf = ( unsigned char)DELAY_DLPF_2;
}
reg = ( unsigned char)(( unsigned char)(EWTSA_range << 3) | dlpf | ( unsigned char)0x80 ) ;
err = i2c_write_byte(client, REG_FS_DLPF, reg);
reg = ( unsigned char)(( unsigned char)(EWTSA_range << 3) | dlpf | ( unsigned char)0x80 ) ;
err = i2c_write_byte(client, REG_FS_DLPF, reg);
if (err < 0) {
return err;
}
if (EWTSA_calib== EWTSA_ON) {
printk("EWTSA_set_calibration() start \n");
err = i2c_write_byte(client,( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_ENABLE);
if (err < 0) {
return err;
}
mdelay(500);
printk("EWTSA_set_calibration() end \n");
if (EWTSA_calib== EWTSA_ON) {
printk("EWTSA_set_calibration() start \n");
err = i2c_write_byte(client,( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_ENABLE);
if (err < 0) {
return err;
}
mdelay(500);
printk("EWTSA_set_calibration() end \n");
}
return 0;
return 0;
}
static int ewtsa_disable(struct i2c_client *client)
static int ewtsa_disable(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_HIGH);
DBG("%s: end \n",__func__);
return 0;
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_HIGH);
DBG("%s: end \n",__func__);
return 0;
}
static int ewtsa_enable(struct i2c_client *client)
static int ewtsa_enable(struct i2c_client *client)
{
int err;
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_LOW);
err = i2c_write_byte(client, ( unsigned char)REG_PWR_MGM, ( unsigned char)SLEEP_CTRL_ACTIVATE);////0x44
if (err < 0){
//return err;
err = ewtsa_system_restart(client);///restart; only when i2c error
if (err < 0){
return err;
}
}
err = i2c_write_byte(client, ( unsigned char) REG_INT_CFG, ( unsigned char)INT_CFG_INT_ENABLE);
if (err < 0) {
return err;
}
DBG("%s: end \n",__func__);
return 0;
int err;
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_LOW);
err = i2c_write_byte(client, ( unsigned char)REG_PWR_MGM, ( unsigned char)SLEEP_CTRL_ACTIVATE);////0x44
if (err < 0){
//return err;
err = ewtsa_system_restart(client);///restart; only when i2c error
if (err < 0){
return err;
}
}
err = i2c_write_byte(client, ( unsigned char) REG_INT_CFG, ( unsigned char)INT_CFG_INT_ENABLE);
if (err < 0) {
return err;
}
DBG("%s: end \n",__func__);
return 0;
}
void gyro_dev_reset(struct i2c_client *client)
void gyro_dev_reset(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
DBG("%s\n",__func__);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_HIGH);
msleep(100);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_LOW);
msleep(100);
}
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);
DBG("%s\n",__func__);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_HIGH);
msleep(100);
gpio_direction_output(sensor->pdata->standby_pin, GPIO_LOW);
msleep(100);
}
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 status = 0;
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int status = 0;
*/
int result = 0;
if(enable)
{
result=ewtsa_enable(client);
}
else
{
result=ewtsa_disable(client);
}
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;
/*
unsigned char buf[5];
unsigned char data = 0;
int i = 0;
char pReadData=0;
*/
sensor->status_cur = SENSOR_OFF;
gyro_dev_reset(client);
ewtsa_system_restart(client);
return result;
}
static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report GYRO information */
input_report_rel(sensor->input_dev, ABS_RX, axis->x);
input_report_rel(sensor->input_dev, ABS_RY, axis->y);
input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
input_sync(sensor->input_dev);
DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x = 0, y = 0, z = 0;
struct sensor_axis axis;
char buffer[6] = {0};
int i = 0;
/* int value = 0; */
memset(buffer, 0, 6);
#if 0
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
buffer[0] = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
#else
for(i=0; i<6; i++)
if(enable)
{
i2c_read_byte(client, sensor->ops->read_reg + i,&buffer[i]);
}
#endif
x = (short) (((buffer[0]) << 8) | buffer[1]);
y = (short) (((buffer[2]) << 8) | buffer[3]);
z = (short) (((buffer[4]) << 8) | buffer[5]);
result=ewtsa_enable(client);
}
else
{
result=ewtsa_disable(client);
}
//printk("%s: x=%d y=%d z=%d \n",__func__, x,y,z);
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;
/*
unsigned char buf[5];
unsigned char data = 0;
int i = 0;
char pReadData=0;
*/
sensor->status_cur = SENSOR_OFF;
gyro_dev_reset(client);
ewtsa_system_restart(client);
return result;
}
static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report GYRO information */
input_report_rel(sensor->input_dev, ABS_RX, axis->x);
input_report_rel(sensor->input_dev, ABS_RY, axis->y);
input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
input_sync(sensor->input_dev);
DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x = 0, y = 0, z = 0;
struct sensor_axis axis;
char buffer[6] = {0};
int i = 0;
/* int value = 0; */
memset(buffer, 0, 6);
#if 0
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
buffer[0] = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
#else
for(i=0; i<6; i++)
{
i2c_read_byte(client, sensor->ops->read_reg + i,&buffer[i]);
}
#endif
x = (short) (((buffer[0]) << 8) | buffer[1]);
y = (short) (((buffer[2]) << 8) | buffer[3]);
z = (short) (((buffer[4]) << 8) | buffer[5]);
//printk("%s: x=%d y=%d z=%d \n",__func__, x,y,z);
if(pdata && pdata->orientation)
{
axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
}
else
{
axis.x = x;
axis.x = x;
axis.y = y;
axis.z = z;
axis.z = z;
}
//filter gyro data
if((abs(axis.x) > pdata->x_min)||(abs(axis.y) > pdata->y_min)||(abs(axis.z) > pdata->z_min))
{
gyro_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
return ret;
}
struct sensor_operate gyro_ewtsa_ops = {
.name = "ewtsa",
.type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct
.id_i2c = GYRO_ID_EWTSA, //i2c id number
.read_reg = GYRO_DATA_REG, //read data
.read_len = 6, //data length
.id_reg = -1, //read device id from this register
.id_data = -1, //device id
.precision = 8, //8 bits
.ctrl_reg = REG_PWR_MGM, //enable or disable
.int_status_reg = REG_INT_STATUS, //intterupt status register,if no exist then -1
.range = {-32768,32768}, //range
.trig = IRQF_TRIGGER_HIGH|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 *gyro_get_ops(void)
{
return &gyro_ewtsa_ops;
}
static int __init gyro_ewtsa_init(void)
{
struct sensor_operate *ops = gyro_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
return result;
}
static void __exit gyro_ewtsa_exit(void)
{
struct sensor_operate *ops = gyro_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);
}
module_init(gyro_ewtsa_init);
module_exit(gyro_ewtsa_exit);
if((abs(axis.x) > pdata->x_min)||(abs(axis.y) > pdata->y_min)||(abs(axis.z) > pdata->z_min))
{
gyro_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
return ret;
}
struct sensor_operate gyro_ewtsa_ops = {
.name = "ewtsa",
.type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct
.id_i2c = GYRO_ID_EWTSA, //i2c id number
.read_reg = GYRO_DATA_REG, //read data
.read_len = 6, //data length
.id_reg = -1, //read device id from this register
.id_data = -1, //device id
.precision = 8, //8 bits
.ctrl_reg = REG_PWR_MGM, //enable or disable
.int_status_reg = REG_INT_STATUS, //intterupt status register,if no exist then -1
.range = {-32768,32768}, //range
.trig = IRQF_TRIGGER_HIGH|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 *gyro_get_ops(void)
{
return &gyro_ewtsa_ops;
}
static int __init gyro_ewtsa_init(void)
{
struct sensor_operate *ops = gyro_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
return result;
}
static void __exit gyro_ewtsa_exit(void)
{
struct sensor_operate *ops = gyro_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);
}
module_init(gyro_ewtsa_init);
module_exit(gyro_ewtsa_exit);

View File

@@ -1,256 +1,256 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/l3g4200d.h>
#include <linux/sensor-dev.h>
#define L3G4200D_ENABLE 0x08
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
status = L3G4200D_ENABLE; //l3g20d
sensor->ops->ctrl_data |= status;
}
else
{
status = ~L3G4200D_ENABLE; //l3g20d
sensor->ops->ctrl_data &= status;
}
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;
unsigned char buf[5];
unsigned char data = 0;
int i = 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;
buf[0] = 0x07; //27
buf[1] = 0x00;
buf[2] = 0x00;
buf[3] = 0x20; //0x00
buf[4] = 0x00;
for(i=0; i<5; i++)
{
result = sensor_write_reg(client, sensor->ops->ctrl_reg+i, buf[i]);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
result = sensor_read_reg(client, sensor->ops->ctrl_reg);
if (result >= 0)
data = result & 0x000F;
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/l3g4200d.h>
#include <linux/sensor-dev.h>
sensor->ops->ctrl_data = data + ODR100_BW12_5;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report GYRO information */
input_report_rel(sensor->input_dev, ABS_RX, axis->x);
input_report_rel(sensor->input_dev, ABS_RY, axis->y);
input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
input_sync(sensor->input_dev);
DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x = 0, y = 0, z = 0;
struct sensor_axis axis;
char buffer[6] = {0};
int i = 0;
int value = 0;
if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 6);
#if 0
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
buffer[0] = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
#else
for(i=0; i<6; i++)
#define L3G4200D_ENABLE 0x08
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
//buffer[i] = sensor->ops->read_reg + i;
buffer[i] = sensor_read_reg(client, sensor->ops->read_reg + i);
}
#endif
x = (short) (((buffer[1]) << 8) | buffer[0]);
y = (short) (((buffer[3]) << 8) | buffer[2]);
z = (short) (((buffer[5]) << 8) | buffer[4]);
status = L3G4200D_ENABLE; //l3g20d
sensor->ops->ctrl_data |= status;
}
else
{
status = ~L3G4200D_ENABLE; //l3g20d
sensor->ops->ctrl_data &= status;
}
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;
unsigned char buf[5];
unsigned char data = 0;
int i = 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;
buf[0] = 0x07; //27
buf[1] = 0x00;
buf[2] = 0x00;
buf[3] = 0x20; //0x00
buf[4] = 0x00;
for(i=0; i<5; i++)
{
result = sensor_write_reg(client, sensor->ops->ctrl_reg+i, buf[i]);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
result = sensor_read_reg(client, sensor->ops->ctrl_reg);
if (result >= 0)
data = result & 0x000F;
sensor->ops->ctrl_data = data + ODR100_BW12_5;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report GYRO information */
input_report_rel(sensor->input_dev, ABS_RX, axis->x);
input_report_rel(sensor->input_dev, ABS_RY, axis->y);
input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
input_sync(sensor->input_dev);
DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x = 0, y = 0, z = 0;
struct sensor_axis axis;
char buffer[6] = {0};
int i = 0;
int value = 0;
if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 6);
#if 0
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
buffer[0] = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
#else
for(i=0; i<6; i++)
{
//buffer[i] = sensor->ops->read_reg + i;
buffer[i] = sensor_read_reg(client, sensor->ops->read_reg + i);
}
#endif
x = (short) (((buffer[1]) << 8) | buffer[0]);
y = (short) (((buffer[3]) << 8) | buffer[2]);
z = (short) (((buffer[5]) << 8) | buffer[4]);
DBG("%s: x=%d y=%d z=%d \n",__func__, x,y,z);
if(pdata && pdata->orientation)
{
axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
}
else
{
axis.x = x;
axis.x = x;
axis.y = y;
axis.z = z;
axis.z = z;
}
//filter gyro data
if((abs(axis.x) > pdata->x_min)||(abs(axis.y) > pdata->y_min)||(abs(axis.z) > pdata->z_min))
{
gyro_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
static struct sensor_operate gyro_l3g20d_ops = {
.name = "l3g20d",
.type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct
.id_i2c = GYRO_ID_L3G20D, //i2c id number
.read_reg = GYRO_DATA_REG, //read data
.read_len = 6, //data length
.id_reg = GYRO_WHO_AM_I, //read device id from this register
.id_data = GYRO_DEVID_L3G20D, //device id
.precision = 8, //8 bits
.ctrl_reg = GYRO_CTRL_REG1, //enable or disable
.int_status_reg = GYRO_INT_SRC, //intterupt status register,if no exist then -1
.range = {-32768,32768}, //range
.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 *gyro_get_ops(void)
{
return &gyro_l3g20d_ops;
}
static int __init gyro_l3g20d_init(void)
{
struct sensor_operate *ops = gyro_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
return result;
}
static void __exit gyro_l3g20d_exit(void)
{
struct sensor_operate *ops = gyro_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);
}
module_init(gyro_l3g20d_init);
module_exit(gyro_l3g20d_exit);
if((abs(axis.x) > pdata->x_min)||(abs(axis.y) > pdata->y_min)||(abs(axis.z) > pdata->z_min))
{
gyro_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
static struct sensor_operate gyro_l3g20d_ops = {
.name = "l3g20d",
.type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct
.id_i2c = GYRO_ID_L3G20D, //i2c id number
.read_reg = GYRO_DATA_REG, //read data
.read_len = 6, //data length
.id_reg = GYRO_WHO_AM_I, //read device id from this register
.id_data = GYRO_DEVID_L3G20D, //device id
.precision = 8, //8 bits
.ctrl_reg = GYRO_CTRL_REG1, //enable or disable
.int_status_reg = GYRO_INT_SRC, //intterupt status register,if no exist then -1
.range = {-32768,32768}, //range
.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 *gyro_get_ops(void)
{
return &gyro_l3g20d_ops;
}
static int __init gyro_l3g20d_init(void)
{
struct sensor_operate *ops = gyro_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
return result;
}
static void __exit gyro_l3g20d_exit(void)
{
struct sensor_operate *ops = gyro_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);
}
module_init(gyro_l3g20d_init);
module_exit(gyro_l3g20d_exit);

View File

@@ -1,256 +1,256 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/l3g4200d.h>
#include <linux/sensor-dev.h>
#define L3G4200D_ENABLE 0x08
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
status = L3G4200D_ENABLE; //l3g4200d
sensor->ops->ctrl_data |= status;
}
else
{
status = ~L3G4200D_ENABLE; //l3g4200d
sensor->ops->ctrl_data &= status;
}
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;
unsigned char buf[5];
unsigned char data = 0;
int i = 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;
buf[0] = 0x07; //27
buf[1] = 0x00;
buf[2] = 0x00;
buf[3] = 0x20; //0x00
buf[4] = 0x00;
for(i=0; i<5; i++)
{
result = sensor_write_reg(client, sensor->ops->ctrl_reg+i, buf[i]);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
result = sensor_read_reg(client, sensor->ops->ctrl_reg);
if (result >= 0)
data = result & 0x000F;
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/l3g4200d.h>
#include <linux/sensor-dev.h>
sensor->ops->ctrl_data = data + ODR100_BW12_5;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report GYRO information */
input_report_rel(sensor->input_dev, ABS_RX, axis->x);
input_report_rel(sensor->input_dev, ABS_RY, axis->y);
input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
input_sync(sensor->input_dev);
DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x = 0, y = 0, z = 0;
struct sensor_axis axis;
char buffer[6] = {0};
int i = 0;
int value = 0;
if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 6);
#if 0
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
buffer[0] = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
#else
for(i=0; i<6; i++)
#define L3G4200D_ENABLE 0x08
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
//buffer[i] = sensor->ops->read_reg + i;
buffer[i] = sensor_read_reg(client, sensor->ops->read_reg + i);
}
#endif
x = (short) (((buffer[1]) << 8) | buffer[0]);
y = (short) (((buffer[3]) << 8) | buffer[2]);
z = (short) (((buffer[5]) << 8) | buffer[4]);
status = L3G4200D_ENABLE; //l3g4200d
sensor->ops->ctrl_data |= status;
}
else
{
status = ~L3G4200D_ENABLE; //l3g4200d
sensor->ops->ctrl_data &= status;
}
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;
unsigned char buf[5];
unsigned char data = 0;
int i = 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;
buf[0] = 0x07; //27
buf[1] = 0x00;
buf[2] = 0x00;
buf[3] = 0x20; //0x00
buf[4] = 0x00;
for(i=0; i<5; i++)
{
result = sensor_write_reg(client, sensor->ops->ctrl_reg+i, buf[i]);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
result = sensor_read_reg(client, sensor->ops->ctrl_reg);
if (result >= 0)
data = result & 0x000F;
sensor->ops->ctrl_data = data + ODR100_BW12_5;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
/* Report GYRO information */
input_report_rel(sensor->input_dev, ABS_RX, axis->x);
input_report_rel(sensor->input_dev, ABS_RY, axis->y);
input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
input_sync(sensor->input_dev);
DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
return 0;
}
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
int ret = 0;
int x = 0, y = 0, z = 0;
struct sensor_axis axis;
char buffer[6] = {0};
int i = 0;
int value = 0;
if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 6);
#if 0
/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
do {
buffer[0] = sensor->ops->read_reg;
ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
if (ret < 0)
return ret;
} while (0);
#else
for(i=0; i<6; i++)
{
//buffer[i] = sensor->ops->read_reg + i;
buffer[i] = sensor_read_reg(client, sensor->ops->read_reg + i);
}
#endif
x = (short) (((buffer[1]) << 8) | buffer[0]);
y = (short) (((buffer[3]) << 8) | buffer[2]);
z = (short) (((buffer[5]) << 8) | buffer[4]);
DBG("%s: x=%d y=%d z=%d \n",__func__, x,y,z);
if(pdata && pdata->orientation)
{
axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
}
else
{
axis.x = x;
axis.x = x;
axis.y = y;
axis.z = z;
axis.z = z;
}
//filter gyro data
if((abs(axis.x) > pdata->x_min)||(abs(axis.y) > pdata->y_min)||(abs(axis.z) > pdata->z_min))
{
gyro_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
struct sensor_operate gyro_l3g4200d_ops = {
.name = "l3g4200d",
.type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct
.id_i2c = GYRO_ID_L3G4200D, //i2c id number
.read_reg = GYRO_DATA_REG, //read data
.read_len = 6, //data length
.id_reg = GYRO_WHO_AM_I, //read device id from this register
.id_data = GYRO_DEVID_L3G4200D, //device id
.precision = 8, //8 bits
.ctrl_reg = GYRO_CTRL_REG1, //enable or disable
.int_status_reg = GYRO_INT_SRC, //intterupt status register,if no exist then -1
.range = {-32768,32768}, //range
.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 *gyro_get_ops(void)
{
return &gyro_l3g4200d_ops;
}
static int __init gyro_l3g4200d_init(void)
{
struct sensor_operate *ops = gyro_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
return result;
}
static void __exit gyro_l3g4200d_exit(void)
{
struct sensor_operate *ops = gyro_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);
}
module_init(gyro_l3g4200d_init);
module_exit(gyro_l3g4200d_exit);
if((abs(axis.x) > pdata->x_min)||(abs(axis.y) > pdata->y_min)||(abs(axis.z) > pdata->z_min))
{
gyro_report_value(client, &axis);
/* <20><><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. */
mutex_lock(&(sensor->data_mutex) );
sensor->axis = axis;
mutex_unlock(&(sensor->data_mutex) );
}
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
DBG("%s:sensor int status :0x%x\n",__func__,value);
}
return ret;
}
struct sensor_operate gyro_l3g4200d_ops = {
.name = "l3g4200d",
.type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct
.id_i2c = GYRO_ID_L3G4200D, //i2c id number
.read_reg = GYRO_DATA_REG, //read data
.read_len = 6, //data length
.id_reg = GYRO_WHO_AM_I, //read device id from this register
.id_data = GYRO_DEVID_L3G4200D, //device id
.precision = 8, //8 bits
.ctrl_reg = GYRO_CTRL_REG1, //enable or disable
.int_status_reg = GYRO_INT_SRC, //intterupt status register,if no exist then -1
.range = {-32768,32768}, //range
.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 *gyro_get_ops(void)
{
return &gyro_l3g4200d_ops;
}
static int __init gyro_l3g4200d_init(void)
{
struct sensor_operate *ops = gyro_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
return result;
}
static void __exit gyro_l3g4200d_exit(void)
{
struct sensor_operate *ops = gyro_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);
}
module_init(gyro_l3g4200d_init);
module_exit(gyro_l3g4200d_exit);

View File

@@ -1,233 +1,233 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CM3217_ADDR_COM1 0x10
#define CM3217_ADDR_COM2 0x11
#define CM3217_ADDR_DATA_MSB 0x10
#define CM3217_ADDR_DATA_LSB 0x11
#define CM3217_COM1_VALUE 0xA7 // (GAIN1:GAIN0)=10, (IT_T1:IT_TO)=01,WMD=1,SD=1,
#define CM3217_COM2_VALUE 0xA0 //100ms
#define CM3217_CLOSE 0x01
/****************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_normal(client);
//register setting according to chip datasheet
if(!enable)
{
status = CM3217_CLOSE; //cm3217
sensor->ops->ctrl_data |= status;
}
else
{
status = ~CM3217_CLOSE; //cm3217
sensor->ops->ctrl_data &= status;
}
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_normal(client, 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;
sensor->client->addr = sensor->ops->ctrl_reg;
sensor->ops->ctrl_data = CM3217_COM1_VALUE;
result = sensor_write_reg_normal(client, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->client->addr = CM3217_ADDR_COM2;
result = sensor_write_reg_normal(client, CM3217_COM2_VALUE);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int 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:
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;
char msb = 0, lsb = 0;
int index = 0;
sensor->client->addr = CM3217_ADDR_DATA_LSB;
sensor_rx_data_normal(sensor->client, &lsb, 1);
sensor->client->addr = CM3217_ADDR_DATA_MSB;
sensor_rx_data_normal(sensor->client, &msb, 1);
result = ((msb << 8) | lsb) & 0xffff;
index = light_report_value(sensor->input_dev, result);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, result,index);
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_cm3217_ops = {
.name = "cm3217",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_CM3217, //i2c id number
.read_reg = CM3217_ADDR_DATA_LSB, //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 = CM3217_ADDR_COM1, //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_cm3217_ops;
}
static int __init light_cm3217_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 light_cm3217_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_cm3217_init);
module_exit(light_cm3217_exit);
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CM3217_ADDR_COM1 0x10
#define CM3217_ADDR_COM2 0x11
#define CM3217_ADDR_DATA_MSB 0x10
#define CM3217_ADDR_DATA_LSB 0x11
#define CM3217_COM1_VALUE 0xA7 // (GAIN1:GAIN0)=10, (IT_T1:IT_TO)=01,WMD=1,SD=1,
#define CM3217_COM2_VALUE 0xA0 //100ms
#define CM3217_CLOSE 0x01
/****************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_normal(client);
//register setting according to chip datasheet
if(!enable)
{
status = CM3217_CLOSE; //cm3217
sensor->ops->ctrl_data |= status;
}
else
{
status = ~CM3217_CLOSE; //cm3217
sensor->ops->ctrl_data &= status;
}
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_normal(client, 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;
sensor->client->addr = sensor->ops->ctrl_reg;
sensor->ops->ctrl_data = CM3217_COM1_VALUE;
result = sensor_write_reg_normal(client, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->client->addr = CM3217_ADDR_COM2;
result = sensor_write_reg_normal(client, CM3217_COM2_VALUE);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int 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:
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;
char msb = 0, lsb = 0;
int index = 0;
sensor->client->addr = CM3217_ADDR_DATA_LSB;
sensor_rx_data_normal(sensor->client, &lsb, 1);
sensor->client->addr = CM3217_ADDR_DATA_MSB;
sensor_rx_data_normal(sensor->client, &msb, 1);
result = ((msb << 8) | lsb) & 0xffff;
index = light_report_value(sensor->input_dev, result);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, result,index);
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_cm3217_ops = {
.name = "cm3217",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_CM3217, //i2c id number
.read_reg = CM3217_ADDR_DATA_LSB, //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 = CM3217_ADDR_COM1, //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_cm3217_ops;
}
static int __init light_cm3217_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 light_cm3217_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_cm3217_init);
module_exit(light_cm3217_exit);

View File

@@ -1,240 +1,240 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#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 int 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:
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;
//char msb = 0, lsb = 0;
char data[2] = {0};
unsigned short value = 0;
int index = 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);
index = light_report_value(sensor->input_dev, value);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
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);
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);
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#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 int 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:
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;
//char msb = 0, lsb = 0;
char data[2] = {0};
unsigned short value = 0;
int index = 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);
index = light_report_value(sensor->input_dev, value);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
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);
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);

View File

@@ -1,268 +1,268 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define ISL29023_REG_ADD_COMMAND1 0x00
#define COMMMAND1_OPMODE_SHIFT 5
#define COMMMAND1_OPMODE_MASK (7 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_POWER_DOWN (0 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_ALS_ONCE (1 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_IR_ONCE (2 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_ALS_CONTINUE (5 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_IR_CONTINUE (6 << COMMMAND1_OPMODE_SHIFT)
#define ISL29023_REG_ADD_COMMANDII 0x01
#define COMMANDII_RESOLUTION_SHIFT 2
#define COMMANDII_RESOLUTION_65536 (0x0 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_4096 (0x1 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_256 (0x2 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_16 (0x3 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_MASK (0x3 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RANGE_SHIFT 0
#define COMMANDII_RANGE_1000 (0x0 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_4000 (0x1 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_16000 (0x2 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_64000 (0x3 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_SCHEME_SHIFT 7
#define COMMANDII_SCHEME_MASK (0x1 << COMMANDII_SCHEME_SHIFT)
#define ISL29023_REG_ADD_DATA_LSB 0x02
#define ISL29023_REG_ADD_DATA_MSB 0x03
#define ISL29023_MAX_REGS ISL29023_REG_ADD_DATA_MSB
#define ISL29023_REG_LT_LSB 0x04
#define ISL29023_REG_LT_MSB 0x05
#define ISL29023_REG_HT_LSB 0x06
#define ISL29023_REG_HT_MSB 0x07
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
sensor->ops->ctrl_data &= 0x1f;
sensor->ops->ctrl_data |= COMMMAND1_OPMODE_ALS_CONTINUE;
}
else
{
sensor->ops->ctrl_data &= 0x1f;
//sensor->ops->ctrl_data |= COMMMAND1_OPMODE_POWER_DOWN;
}
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__);
if(enable)
sensor->ops->report(sensor->client);
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;
result = sensor_write_reg(client, ISL29023_REG_ADD_COMMANDII, COMMANDII_RANGE_4000 | COMMANDII_RESOLUTION_4096);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 2){
index = 0;goto report;
}
else if(data <= 3){
index = 2;goto report;
}
else if(data <= 5){
index = 3;goto report;
}
else if(data <= 8){
index = 4;goto report;
}
else if(data <= 11){
index = 5;goto report;
}
else if(data <= 14){
index = 6;goto report;
}
else if(data <= 17){
index = 7;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 buffer[2] = {0};
char index = 0;
if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 2);
buffer[0] = sensor->ops->read_reg;
result = sensor_rx_data(client, buffer, sensor->ops->read_len);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
value = (buffer[1] << 8) | buffer[0];
index = light_report_value(sensor->input_dev, value);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
}
return result;
}
struct sensor_operate light_isl29023_ops = {
.name = "ls_isl29023",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_ISL29023, //i2c id number
.read_reg = ISL29023_REG_ADD_DATA_LSB, //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 = 16, //8 bits
.ctrl_reg = ISL29023_REG_ADD_COMMAND1, //enable or disable
.int_status_reg = ISL29023_REG_ADD_COMMAND1, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, //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_isl29023_ops;
}
static int __init light_isl29023_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 light_isl29023_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_isl29023_init);
module_exit(light_isl29023_exit);
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define ISL29023_REG_ADD_COMMAND1 0x00
#define COMMMAND1_OPMODE_SHIFT 5
#define COMMMAND1_OPMODE_MASK (7 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_POWER_DOWN (0 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_ALS_ONCE (1 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_IR_ONCE (2 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_ALS_CONTINUE (5 << COMMMAND1_OPMODE_SHIFT)
#define COMMMAND1_OPMODE_IR_CONTINUE (6 << COMMMAND1_OPMODE_SHIFT)
#define ISL29023_REG_ADD_COMMANDII 0x01
#define COMMANDII_RESOLUTION_SHIFT 2
#define COMMANDII_RESOLUTION_65536 (0x0 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_4096 (0x1 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_256 (0x2 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_16 (0x3 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RESOLUTION_MASK (0x3 << COMMANDII_RESOLUTION_SHIFT)
#define COMMANDII_RANGE_SHIFT 0
#define COMMANDII_RANGE_1000 (0x0 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_4000 (0x1 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_16000 (0x2 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_64000 (0x3 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)
#define COMMANDII_SCHEME_SHIFT 7
#define COMMANDII_SCHEME_MASK (0x1 << COMMANDII_SCHEME_SHIFT)
#define ISL29023_REG_ADD_DATA_LSB 0x02
#define ISL29023_REG_ADD_DATA_MSB 0x03
#define ISL29023_MAX_REGS ISL29023_REG_ADD_DATA_MSB
#define ISL29023_REG_LT_LSB 0x04
#define ISL29023_REG_LT_MSB 0x05
#define ISL29023_REG_HT_LSB 0x06
#define ISL29023_REG_HT_MSB 0x07
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
sensor->ops->ctrl_data &= 0x1f;
sensor->ops->ctrl_data |= COMMMAND1_OPMODE_ALS_CONTINUE;
}
else
{
sensor->ops->ctrl_data &= 0x1f;
//sensor->ops->ctrl_data |= COMMMAND1_OPMODE_POWER_DOWN;
}
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__);
if(enable)
sensor->ops->report(sensor->client);
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;
result = sensor_write_reg(client, ISL29023_REG_ADD_COMMANDII, COMMANDII_RANGE_4000 | COMMANDII_RESOLUTION_4096);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 2){
index = 0;goto report;
}
else if(data <= 3){
index = 2;goto report;
}
else if(data <= 5){
index = 3;goto report;
}
else if(data <= 8){
index = 4;goto report;
}
else if(data <= 11){
index = 5;goto report;
}
else if(data <= 14){
index = 6;goto report;
}
else if(data <= 17){
index = 7;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 buffer[2] = {0};
char index = 0;
if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 2);
buffer[0] = sensor->ops->read_reg;
result = sensor_rx_data(client, buffer, sensor->ops->read_len);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
value = (buffer[1] << 8) | buffer[0];
index = light_report_value(sensor->input_dev, value);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
}
return result;
}
struct sensor_operate light_isl29023_ops = {
.name = "ls_isl29023",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_ISL29023, //i2c id number
.read_reg = ISL29023_REG_ADD_DATA_LSB, //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 = 16, //8 bits
.ctrl_reg = ISL29023_REG_ADD_COMMAND1, //enable or disable
.int_status_reg = ISL29023_REG_ADD_COMMAND1, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, //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_isl29023_ops;
}
static int __init light_isl29023_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 light_isl29023_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_isl29023_init);
module_exit(light_isl29023_exit);

View File

@@ -1,295 +1,295 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CONFIG_REG (0x00)
#define TIM_CTL_REG (0x01)
#define ALS_CTL_REG (0x02)
#define INT_STATUS_REG (0x03)
#define PS_CTL_REG (0x04)
#define PS_ALS_DATA_REG (0x05)
#define ALS_WINDOWS_REG (0x08)
//enable bit[ 0-1], in register CONFIG_REG
#define ONLY_ALS_EN (0x00)
#define ONLY_PROX_EN (0x01)
#define ALL_PROX_ALS_EN (0x02)
#define ALL_IDLE (0x03)
#define POWER_MODE_MASK (0x0C)
#define POWER_UP_MODE (0x00)
#define POWER_DOWN_MODE (0x08)
#define POWER_RESET_MODE (0x0C)
static int sensor_power_updown(struct i2c_client *client, int on)
{
int result = 0;
char value = 0;
int i = 0;
for(i=0; i<3; i++)
{
if(!on)
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_DOWN_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
else
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_UP_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
if(!result)
break;
}
if(i>1)
printk("%s:set %d times",__func__,i);
return result;
}
/****************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;
char value = 0;
if(enable)
sensor_power_updown(client, 1);
value = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
if( (value & 0x03) == ONLY_PROX_EN )
{
value &= ~0x03;
value |= ALL_PROX_ALS_EN;
}
else if((value & 0x03) == ALL_IDLE )
{
value &= ~0x03;
value |= ONLY_ALS_EN;
}
}
else
{
if( (value & 0x03) == ONLY_ALS_EN )
{
value &= ~0x03;
value |= ALL_IDLE;
}
else if((value & 0x03) == ALL_PROX_ALS_EN )
{
value &= ~0x03;
value |= ONLY_PROX_EN;
}
}
sensor->ops->ctrl_data = value;
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;
char value = 0;
sensor_power_updown(client, 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 = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CONFIG_REG (0x00)
#define TIM_CTL_REG (0x01)
#define ALS_CTL_REG (0x02)
#define INT_STATUS_REG (0x03)
#define PS_CTL_REG (0x04)
#define PS_ALS_DATA_REG (0x05)
#define ALS_WINDOWS_REG (0x08)
//enable bit[ 0-1], in register CONFIG_REG
#define ONLY_ALS_EN (0x00)
#define ONLY_PROX_EN (0x01)
#define ALL_PROX_ALS_EN (0x02)
#define ALL_IDLE (0x03)
#define POWER_MODE_MASK (0x0C)
#define POWER_UP_MODE (0x00)
#define POWER_DOWN_MODE (0x08)
#define POWER_RESET_MODE (0x0C)
static int sensor_power_updown(struct i2c_client *client, int on)
{
int result = 0;
char value = 0;
int i = 0;
for(i=0; i<3; i++)
{
if(!on)
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_DOWN_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
else
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_UP_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
if(!result)
break;
}
if(i>1)
printk("%s:set %d times",__func__,i);
return result;
}
/****************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;
char value = 0;
if(enable)
sensor_power_updown(client, 1);
value = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
if( (value & 0x03) == ONLY_PROX_EN )
{
value &= ~0x03;
value |= ALL_PROX_ALS_EN;
}
else if((value & 0x03) == ALL_IDLE )
{
value &= ~0x03;
value |= ONLY_ALS_EN;
}
}
else
{
if( (value & 0x03) == ONLY_ALS_EN )
{
value &= ~0x03;
value |= ALL_IDLE;
}
else if((value & 0x03) == ALL_PROX_ALS_EN )
{
value &= ~0x03;
value |= ONLY_PROX_EN;
}
}
sensor->ops->ctrl_data = value;
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;
char value = 0;
sensor_power_updown(client, 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 = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
//value = 0x69; //The ADC effective resolution = 17; Low lux threshold level = 9;
result = sensor_write_reg(client, ALS_CTL_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
result = sensor_write_reg(client, ALS_CTL_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
//value = 0x04;//0x01-0x0f; 17%->93.5% if value = 0x04,then Compensate Loss 52%
value = 0x02;//0x01-0x0f; 17%->93.5% if value = 0x02,then Compensate Loss 31%
result = sensor_write_reg(client, ALS_WINDOWS_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 0){
index = 0;goto report;
}
else if(data <= 2){
index = 1;goto report;
}
else if(data <= 4){
index = 2;goto report;
}
else if(data <= 8){
index = 3;goto report;
}
else if(data <= 14){
index = 4;goto report;
}
else if(data <= 20){
index = 5;goto report;
}
else if(data <= 26){
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;
char value = 0;
char index = 0;
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
}
value = sensor_read_reg(client, sensor->ops->read_reg);
index = light_report_value(sensor->input_dev, value&0x3f); // bit0-5 is ls data;
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
return result;
}
struct sensor_operate light_al3006_ops = {
.name = "ls_al3006",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_AL3006, //i2c id number
.read_reg = PS_ALS_DATA_REG, //read data
.read_len = 1, //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 = CONFIG_REG, //enable or disable
.int_status_reg = INT_STATUS_REG, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, // brightness
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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_al3006_ops;
}
static int __init light_al3006_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 light_al3006_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_al3006_init);
module_exit(light_al3006_exit);
value = 0x02;//0x01-0x0f; 17%->93.5% if value = 0x02,then Compensate Loss 31%
result = sensor_write_reg(client, ALS_WINDOWS_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 0){
index = 0;goto report;
}
else if(data <= 2){
index = 1;goto report;
}
else if(data <= 4){
index = 2;goto report;
}
else if(data <= 8){
index = 3;goto report;
}
else if(data <= 14){
index = 4;goto report;
}
else if(data <= 20){
index = 5;goto report;
}
else if(data <= 26){
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;
char value = 0;
char index = 0;
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
}
value = sensor_read_reg(client, sensor->ops->read_reg);
index = light_report_value(sensor->input_dev, value&0x3f); // bit0-5 is ls data;
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
return result;
}
struct sensor_operate light_al3006_ops = {
.name = "ls_al3006",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_AL3006, //i2c id number
.read_reg = PS_ALS_DATA_REG, //read data
.read_len = 1, //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 = CONFIG_REG, //enable or disable
.int_status_reg = INT_STATUS_REG, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, // brightness
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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_al3006_ops;
}
static int __init light_al3006_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 light_al3006_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_al3006_init);
module_exit(light_al3006_exit);

View File

@@ -1,58 +1,58 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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>
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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>
#define AP3212B_NUM_CACHABLE_REGS 23
#define AP3216C_NUM_CACHABLE_REGS 26
#define AP3216C_NUM_CACHABLE_REGS 26
#define AP3212B_RAN_COMMAND 0x10
#define AP3212B_RAN_MASK 0x30
#define AP3212B_RAN_SHIFT (4)
#define AP3212B_MODE_COMMAND 0x00
#define AP3212B_MODE_SHIFT (0)
#define AP3212B_MODE_MASK 0x07
#define AP3212B_MODE_MASK 0x07
#define AP3212B_INT_COMMAND 0x01
#define AP3212B_INT_SHIFT (0)
#define AP3212B_INT_MASK 0x03
#define AP3212B_INT_PMASK 0x02
#define AP3212B_INT_AMASK 0x01
#define AL3212_ADC_LSB 0x0c
#define AL3212_ADC_MSB 0x0d
#define AP3212B_ALS_LTHL 0x1a
#define AP3212B_ALS_LTHL_SHIFT (0)
#define AP3212B_ALS_LTHL_MASK 0xff
@@ -68,9 +68,9 @@
#define AP3212B_ALS_HTHH 0x1d
#define AP3212B_ALS_HTHH_SHIFT (0)
#define AP3212B_ALS_HTHH_MASK 0xff
static u16 ap321xx_threshole[8] = {28,444,625,888,1778,3555,7222,0xffff};
static u16 ap321xx_threshole[8] = {28,444,625,888,1778,3555,7222,0xffff};
/*
* register access helpers
*/
@@ -78,33 +78,33 @@ static u16 ap321xx_threshole[8] = {28,444,625,888,1778,3555,7222,0xffff};
static int __ap321xx_read_reg(struct i2c_client *client,
u32 reg, u8 mask, u8 shift)
{
u8 val;
val = i2c_smbus_read_byte_data(client, reg);
return (val & mask) >> shift;
u8 val;
val = i2c_smbus_read_byte_data(client, reg);
return (val & mask) >> shift;
}
static int __ap321xx_write_reg(struct i2c_client *client,
u32 reg, u8 mask, u8 shift, u8 val)
{
int ret = 0;
int ret = 0;
u8 tmp;
tmp = i2c_smbus_read_byte_data(client, reg);
tmp = i2c_smbus_read_byte_data(client, reg);
tmp &= ~mask;
tmp |= val << shift;
ret = i2c_smbus_write_byte_data(client, reg, tmp);
return ret;
ret = i2c_smbus_write_byte_data(client, reg, tmp);
return ret;
}
/*
* internally used functions
*/
*/
/* range */
static int ap321xx_set_range(struct i2c_client *client, int range)
static int ap321xx_set_range(struct i2c_client *client, int range)
{
return __ap321xx_write_reg(client, AP3212B_RAN_COMMAND,
AP3212B_RAN_MASK, AP3212B_RAN_SHIFT, range);;
@@ -114,51 +114,51 @@ static int ap321xx_set_range(struct i2c_client *client, int range)
/* mode */
static int ap321xx_get_mode(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int ret;
ret = __ap321xx_read_reg(client, sensor->ops->ctrl_reg,
ret = __ap321xx_read_reg(client, sensor->ops->ctrl_reg,
AP3212B_MODE_MASK, AP3212B_MODE_SHIFT);
return ret;
}
static int ap321xx_set_mode(struct i2c_client *client, int mode)
static int ap321xx_set_mode(struct i2c_client *client, int mode)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int ret;
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int ret;
ret = __ap321xx_write_reg(client, sensor->ops->ctrl_reg,
ret = __ap321xx_write_reg(client, sensor->ops->ctrl_reg,
AP3212B_MODE_MASK, AP3212B_MODE_SHIFT, mode);
return ret;
}
}
static int ap321xx_get_adc_value(struct i2c_client *client)
{
unsigned int lsb, msb, val;
unsigned char index=0;
unsigned char index=0;
lsb = i2c_smbus_read_byte_data(client, AL3212_ADC_LSB);
lsb = i2c_smbus_read_byte_data(client, AL3212_ADC_LSB);
if (lsb < 0) {
return lsb;
}
msb = i2c_smbus_read_byte_data(client, AL3212_ADC_MSB);
msb = i2c_smbus_read_byte_data(client, AL3212_ADC_MSB);
if (msb < 0)
return msb;
val = msb << 8 | lsb;
val = msb << 8 | lsb;
for(index = 0; index < 7 && val > ap321xx_threshole[index];index++)
;
return index;
}
/* ALS low threshold */
}
/* ALS low threshold */
static int ap321xx_set_althres(struct i2c_client *client, int val)
{
int lsb, msb, err;
msb = val >> 8;
lsb = val & AP3212B_ALS_LTHL_MASK;
@@ -173,14 +173,14 @@ static int ap321xx_set_althres(struct i2c_client *client, int val)
return err;
}
/* ALS high threshold */
/* ALS high threshold */
static int ap321xx_set_ahthres(struct i2c_client *client, int val)
{
int lsb, msb, err;
msb = val >> 8;
lsb = val & AP3212B_ALS_HTHL_MASK;
err = __ap321xx_write_reg(client, AP3212B_ALS_HTHL,
AP3212B_ALS_HTHL_MASK, AP3212B_ALS_HTHL_SHIFT, lsb);
if (err)
@@ -190,71 +190,71 @@ static int ap321xx_set_ahthres(struct i2c_client *client, int val)
AP3212B_ALS_HTHH_MASK, AP3212B_ALS_HTHH_SHIFT, msb);
return err;
}
}
static int ap321xx_get_intstat(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int val;
val = i2c_smbus_read_byte_data(client, sensor->ops->int_status_reg);
val = i2c_smbus_read_byte_data(client, sensor->ops->int_status_reg);
val &= AP3212B_INT_MASK;
return val >> AP3212B_INT_SHIFT;
}
static int ap321xx_product_detect(struct i2c_client *client)
}
static int ap321xx_product_detect(struct i2c_client *client)
{
int mid = i2c_smbus_read_byte_data(client, 0x03);
int pid = i2c_smbus_read_byte_data(client, 0x04);
int rid = i2c_smbus_read_byte_data(client, 0x05);
if ( mid == 0x01 && pid == 0x01 &&
if ( mid == 0x01 && pid == 0x01 &&
(rid == 0x03 || rid == 0x04) )
{
//printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
}
else if ( (mid == 0x01 && pid == 0x02 && rid == 0x00) ||
//printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
}
else if ( (mid == 0x01 && pid == 0x02 && rid == 0x00) ||
(mid == 0x02 && pid == 0x02 && rid == 0x01))
{
//printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
}
//printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
}
else
{
//printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
//printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
return -EIO;
}
return 0;
}
}
static int ap321xx_init_client(struct i2c_client *client)
{
/* set defaults */
/* set defaults */
ap321xx_set_range(client, 0);
ap321xx_set_mode(client, 0);
return 0;
}
}
static int ap321xx_lsensor_enable(struct i2c_client *client)
{
int ret = 0,mode;
mode = ap321xx_get_mode(client);
if((mode & 0x01) == 0){
mode |= 0x01;
ret = ap321xx_set_mode(client,mode);
}
return ret;
}
static int ap321xx_lsensor_disable(struct i2c_client *client)
{
int ret = 0,mode;
mode = ap321xx_get_mode(client);
if(mode & 0x01){
mode &= ~0x01;
@@ -262,18 +262,18 @@ static int ap321xx_lsensor_disable(struct i2c_client *client)
mode = 0;
ret = ap321xx_set_mode(client,mode);
}
return ret;
}
}
static void ap321xx_change_ls_threshold(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int value;
value = ap321xx_get_adc_value(client);
DBG("ALS lux index: %u\n", value);
DBG("ALS lux index: %u\n", value);
if(value > 0){
ap321xx_set_althres(client,ap321xx_threshole[value-1]);
ap321xx_set_ahthres(client,ap321xx_threshole[value]);
@@ -282,128 +282,128 @@ static void ap321xx_change_ls_threshold(struct i2c_client *client)
ap321xx_set_althres(client,0);
ap321xx_set_ahthres(client,ap321xx_threshole[value]);
}
input_report_abs(sensor->input_dev, ABS_MISC, value);
input_sync(sensor->input_dev);
}
/****************operate according to sensor chip:start************/
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
//register setting according to chip datasheet
if (enable){
result = ap321xx_lsensor_enable(client);
if(!result){
msleep(200);
ap321xx_change_ls_threshold(client);
}
}
else
result = ap321xx_lsensor_disable(client);
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 = ap321xx_product_detect(client);
if (result)
{
dev_err(&client->dev, "ret: %d, product version detect failed.\n",result);
return result;
}
/* initialize the AP3212B chip */
result = ap321xx_init_client(client);
if (result)
return result;
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 int sensor_report_value(struct i2c_client *client)
{
int result = 0;
u8 int_stat;
int_stat = ap321xx_get_intstat(client);
// ALS int
if (int_stat & AP3212B_INT_AMASK)
{
ap321xx_change_ls_threshold(client);
input_report_abs(sensor->input_dev, ABS_MISC, value);
input_sync(sensor->input_dev);
}
/****************operate according to sensor chip:start************/
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
//register setting according to chip datasheet
if (enable){
result = ap321xx_lsensor_enable(client);
if(!result){
msleep(200);
ap321xx_change_ls_threshold(client);
}
}
return result;
}
struct sensor_operate light_ap321xx_ops = {
.name = "ls_ap321xx",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_AP321XX, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data //there are two regs, we fix them in code.
.read_len = 1, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register //there are 3 regs, we fix them in code.
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 16, //8 bits
.ctrl_reg = AP3212B_MODE_COMMAND, //enable or disable
.int_status_reg = AP3212B_INT_COMMAND, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, // brightness
.trig = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED,
.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_ap321xx_ops;
}
static int __init light_ap321xx_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 light_ap321xx_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_ap321xx_init);
module_exit(light_ap321xx_exit);
else
result = ap321xx_lsensor_disable(client);
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 = ap321xx_product_detect(client);
if (result)
{
dev_err(&client->dev, "ret: %d, product version detect failed.\n",result);
return result;
}
/* initialize the AP3212B chip */
result = ap321xx_init_client(client);
if (result)
return result;
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 int sensor_report_value(struct i2c_client *client)
{
int result = 0;
u8 int_stat;
int_stat = ap321xx_get_intstat(client);
// ALS int
if (int_stat & AP3212B_INT_AMASK)
{
ap321xx_change_ls_threshold(client);
}
return result;
}
struct sensor_operate light_ap321xx_ops = {
.name = "ls_ap321xx",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_AP321XX, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data //there are two regs, we fix them in code.
.read_len = 1, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register //there are 3 regs, we fix them in code.
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 16, //8 bits
.ctrl_reg = AP3212B_MODE_COMMAND, //enable or disable
.int_status_reg = AP3212B_INT_COMMAND, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, // brightness
.trig = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED,
.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_ap321xx_ops;
}
static int __init light_ap321xx_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 light_ap321xx_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_ap321xx_init);
module_exit(light_ap321xx_exit);

View File

@@ -1,314 +1,314 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define ALS_CMD 0x01
#define ALS_DT1 0x02
#define ALS_DT2 0X03
#define ALS_THDH1 0X04
#define ALS_THDH2 0X05
#define ALS_THDL1 0X06
#define ALS_THDL2 0X07
#define STA_TUS 0X08
#define PS_CMD 0X09
#define PS_DT 0X0A
#define PS_THDH 0X0B
#define PS_THDL 0X0C
#define SW_RESET 0X80
//ALS_CMD
#define ALS_SD_ENABLE (0<<0)
#define ALS_SD_DISABLE (1<<0)
#define ALS_INT_DISABLE (0<<1)
#define ALS_INT_ENABLE (1<<1)
#define ALS_1T_100MS (0<<2)
#define ALS_2T_200MS (1<<2)
#define ALS_4T_400MS (2<<2)
#define ALS_8T_800MS (3<<2)
#define ALS_RANGE_57671 (0<<6)
#define ALS_RANGE_28836 (1<<6)
//PS_CMD
#define PS_SD_ENABLE (0<<0)
#define PS_SD_DISABLE (1<<0)
#define PS_INT_DISABLE (0<<1)
#define PS_INT_ENABLE (1<<1)
#define PS_10T_2MS (0<<2)
#define PS_15T_3MS (1<<2)
#define PS_20T_4MS (2<<2)
#define PS_25T_5MS (3<<2)
#define PS_CUR_100MA (0<<4)
#define PS_CUR_200MA (1<<4)
#define PS_SLP_10MS (0<<5)
#define PS_SLP_30MS (1<<5)
#define PS_SLP_90MS (2<<5)
#define PS_SLP_270MS (3<<5)
#define TRIG_PS_OR_LS (0<<7)
#define TRIG_PS_AND_LS (1<<7)
//STA_TUS
#define STA_PS_INT (1<<5)
#define STA_ALS_INT (1<<4)
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(!enable)
{
status = ALS_SD_DISABLE;
sensor->ops->ctrl_data |= status;
}
else
{
status = ~ALS_SD_DISABLE;
sensor->ops->ctrl_data &= status;
}
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__);
if(enable)
sensor->ops->report(sensor->client);
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;
result = sensor_write_reg(client, SW_RESET, 0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
result = sensor_write_reg(client, ALS_THDH1, 0);//it is important,if not then als can not trig intterupt
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
result = sensor_write_reg(client, ALS_THDH2, 0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->ops->ctrl_data |= ALS_1T_100MS;
if(sensor->pdata->irq_enable)
sensor->ops->ctrl_data |= ALS_INT_ENABLE;
else
sensor->ops->ctrl_data &= ~ALS_INT_ENABLE;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 100){
index = 0;goto report;
}
else if(data <= 1600){
index = 1;goto report;
}
else if(data <= 2250){
index = 2;goto report;
}
else if(data <= 3200){
index = 3;goto report;
}
else if(data <= 6400){
index = 4;goto report;
}
else if(data <= 12800){
index = 5;goto report;
}
else if(data <= 26000){
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 buffer[2] = {0};
char index = 0;
if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 2);
buffer[0] = sensor->ops->read_reg;
result = sensor_rx_data(client, buffer, sensor->ops->read_len);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
value = (buffer[0] << 8) | buffer[1];
index = light_report_value(sensor->input_dev, value);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
if(value & STA_ALS_INT)
{
value &= ~STA_ALS_INT;
result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
}
return result;
}
struct sensor_operate light_stk3171_ops = {
.name = "ls_stk3171",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_STK3171, //i2c id number
.read_reg = ALS_DT1, //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 = 16, //8 bits
.ctrl_reg = ALS_CMD, //enable or disable
.int_status_reg = STA_TUS, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, //brightness
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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_stk3171_ops;
}
static int __init light_stk3171_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 light_stk3171_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_stk3171_init);
module_exit(light_stk3171_exit);
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define ALS_CMD 0x01
#define ALS_DT1 0x02
#define ALS_DT2 0X03
#define ALS_THDH1 0X04
#define ALS_THDH2 0X05
#define ALS_THDL1 0X06
#define ALS_THDL2 0X07
#define STA_TUS 0X08
#define PS_CMD 0X09
#define PS_DT 0X0A
#define PS_THDH 0X0B
#define PS_THDL 0X0C
#define SW_RESET 0X80
//ALS_CMD
#define ALS_SD_ENABLE (0<<0)
#define ALS_SD_DISABLE (1<<0)
#define ALS_INT_DISABLE (0<<1)
#define ALS_INT_ENABLE (1<<1)
#define ALS_1T_100MS (0<<2)
#define ALS_2T_200MS (1<<2)
#define ALS_4T_400MS (2<<2)
#define ALS_8T_800MS (3<<2)
#define ALS_RANGE_57671 (0<<6)
#define ALS_RANGE_28836 (1<<6)
//PS_CMD
#define PS_SD_ENABLE (0<<0)
#define PS_SD_DISABLE (1<<0)
#define PS_INT_DISABLE (0<<1)
#define PS_INT_ENABLE (1<<1)
#define PS_10T_2MS (0<<2)
#define PS_15T_3MS (1<<2)
#define PS_20T_4MS (2<<2)
#define PS_25T_5MS (3<<2)
#define PS_CUR_100MA (0<<4)
#define PS_CUR_200MA (1<<4)
#define PS_SLP_10MS (0<<5)
#define PS_SLP_30MS (1<<5)
#define PS_SLP_90MS (2<<5)
#define PS_SLP_270MS (3<<5)
#define TRIG_PS_OR_LS (0<<7)
#define TRIG_PS_AND_LS (1<<7)
//STA_TUS
#define STA_PS_INT (1<<5)
#define STA_ALS_INT (1<<4)
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(!enable)
{
status = ALS_SD_DISABLE;
sensor->ops->ctrl_data |= status;
}
else
{
status = ~ALS_SD_DISABLE;
sensor->ops->ctrl_data &= status;
}
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__);
if(enable)
sensor->ops->report(sensor->client);
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;
result = sensor_write_reg(client, SW_RESET, 0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
result = sensor_write_reg(client, ALS_THDH1, 0);//it is important,if not then als can not trig intterupt
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
result = sensor_write_reg(client, ALS_THDH2, 0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->ops->ctrl_data |= ALS_1T_100MS;
if(sensor->pdata->irq_enable)
sensor->ops->ctrl_data |= ALS_INT_ENABLE;
else
sensor->ops->ctrl_data &= ~ALS_INT_ENABLE;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 100){
index = 0;goto report;
}
else if(data <= 1600){
index = 1;goto report;
}
else if(data <= 2250){
index = 2;goto report;
}
else if(data <= 3200){
index = 3;goto report;
}
else if(data <= 6400){
index = 4;goto report;
}
else if(data <= 12800){
index = 5;goto report;
}
else if(data <= 26000){
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 buffer[2] = {0};
char index = 0;
if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 2);
buffer[0] = sensor->ops->read_reg;
result = sensor_rx_data(client, buffer, sensor->ops->read_len);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
value = (buffer[0] << 8) | buffer[1];
index = light_report_value(sensor->input_dev, value);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
if(value & STA_ALS_INT)
{
value &= ~STA_ALS_INT;
result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
}
return result;
}
struct sensor_operate light_stk3171_ops = {
.name = "ls_stk3171",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_STK3171, //i2c id number
.read_reg = ALS_DT1, //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 = 16, //8 bits
.ctrl_reg = ALS_CMD, //enable or disable
.int_status_reg = STA_TUS, //intterupt status register
.range = {100,65535}, //range
.brightness ={10,255}, //brightness
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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_stk3171_ops;
}
static int __init light_stk3171_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 light_stk3171_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_stk3171_init);
module_exit(light_stk3171_exit);

View File

@@ -1,438 +1,438 @@
#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);
#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);

View File

@@ -1,292 +1,292 @@
/* drivers/input/sensors/pressure/ms5607.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC OSR=256
#define CMD_ADC_512 0x02 // ADC OSR=512
#define CMD_ADC_1024 0x04 // ADC OSR=1024
#define CMD_ADC_2048 0x06 // ADC OSR=2048
#define CMD_ADC_4096 0x08 // ADC OSR=4096
#define CMD_PROM_RD 0xA0 // Prom read command
/****************operate according to sensor chip:start************/
static int C[8] = {0};
int g_ms5607_temp;
int g_ms5607_pr_status;
#if defined(CONFIG_TMP_MS5607)
extern int g_ms5607_temp_status;
#else
static int g_ms5607_temp_status = SENSOR_OFF;
#endif
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
int i = 0;
char prom[16];
if((enable) && (g_ms5607_temp_status == SENSOR_OFF))
{
result = sensor_write_reg_normal(client, CMD_RESET);
if(result)
printk("%s:line=%d,error\n",__func__,__LINE__);
//Read PROM (128 bit of calibration words)
memset(prom, 0, 16);
prom[0]= CMD_PROM_RD;//CMD_PROM_RD;
for(i=0; i<8; i++)
{
prom[i*2]= CMD_PROM_RD + i*2;
result = sensor_rx_data(client, &prom[i*2], 2);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
for (i=0;i<8;i++)
{
C[i] = prom[2*i] << 8 | prom[2*i + 1];
//printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
//printk("\nC[%d]=%d,",i+1,C[i]);
}
}
g_ms5607_pr_status = enable;
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;
g_ms5607_pr_status = sensor->status_cur;
//Reset
//result = sensor_write_reg_normal(client, CMD_RESET);
//if(result)
//printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
static int pressure_report_value(struct input_dev *input, int data)
{
//get pressure, high and temperature from register data
input_report_abs(input, ABS_PRESSURE, data);
input_sync(input);
return 0;
}
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 buffer[3];
char index = 0;
unsigned int D1=0, D2=0;
int T2 = 0;
long long OFF = 0; // offset at actual temperature
long long SENS = 0; // sensitivity at actual temperature
int dT = 0; // difference between actual and measured temperature
long long OFF2 = 0;
long long SENS2 = 0;
int P = 0; // compensated pressure value
memset(buffer, 0, 3);
if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
//D1 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);
//D2 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);
dT = D2 - ((unsigned int)C[5] << 8);
g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));
OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);
SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);
/*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/
if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)
{
printk("%s:temperature is error\n",__func__);
return -1;
}
if (g_ms5607_temp < 2000)
{
int tmp;
tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);
T2 = (int)((long long)(dT * dT) >> 31);
OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;
SENS2 = (long long)((tmp*tmp) << 1);
if (g_ms5607_temp < -1500)
{
tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);
OFF2 += 15 * tmp;
SENS2 += 8 * tmp;
}
}
else
{
T2=0;
OFF2 = 0;
SENS2 = 0;
}
g_ms5607_temp -= T2;
OFF -= OFF2;
SENS -= SENS2;
P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);
index = pressure_report_value(sensor->input_dev, P);
DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
return result;
}
struct sensor_operate pressure_ms5607_ops = {
.name = "pr_ms5607",
.type = SENSOR_TYPE_PRESSURE, //sensor type and it should be correct
.id_i2c = PRESSURE_ID_MS5607, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data
.read_len = 3, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 24, //8 bits
.ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
.range = {100,65535}, //range
.brightness = {10,255}, //brightness
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *pressure_get_ops(void)
{
return &pressure_ms5607_ops;
}
static int __init pressure_ms5607_init(void)
{
struct sensor_operate *ops = pressure_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, pressure_get_ops);
return result;
}
static void __exit pressure_ms5607_exit(void)
{
struct sensor_operate *ops = pressure_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, pressure_get_ops);
}
module_init(pressure_ms5607_init);
module_exit(pressure_ms5607_exit);
/* drivers/input/sensors/pressure/ms5607.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC OSR=256
#define CMD_ADC_512 0x02 // ADC OSR=512
#define CMD_ADC_1024 0x04 // ADC OSR=1024
#define CMD_ADC_2048 0x06 // ADC OSR=2048
#define CMD_ADC_4096 0x08 // ADC OSR=4096
#define CMD_PROM_RD 0xA0 // Prom read command
/****************operate according to sensor chip:start************/
static int C[8] = {0};
int g_ms5607_temp;
int g_ms5607_pr_status;
#if defined(CONFIG_TMP_MS5607)
extern int g_ms5607_temp_status;
#else
static int g_ms5607_temp_status = SENSOR_OFF;
#endif
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
int i = 0;
char prom[16];
if((enable) && (g_ms5607_temp_status == SENSOR_OFF))
{
result = sensor_write_reg_normal(client, CMD_RESET);
if(result)
printk("%s:line=%d,error\n",__func__,__LINE__);
//Read PROM (128 bit of calibration words)
memset(prom, 0, 16);
prom[0]= CMD_PROM_RD;//CMD_PROM_RD;
for(i=0; i<8; i++)
{
prom[i*2]= CMD_PROM_RD + i*2;
result = sensor_rx_data(client, &prom[i*2], 2);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
for (i=0;i<8;i++)
{
C[i] = prom[2*i] << 8 | prom[2*i + 1];
//printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
//printk("\nC[%d]=%d,",i+1,C[i]);
}
}
g_ms5607_pr_status = enable;
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;
g_ms5607_pr_status = sensor->status_cur;
//Reset
//result = sensor_write_reg_normal(client, CMD_RESET);
//if(result)
//printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
static int pressure_report_value(struct input_dev *input, int data)
{
//get pressure, high and temperature from register data
input_report_abs(input, ABS_PRESSURE, data);
input_sync(input);
return 0;
}
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 buffer[3];
char index = 0;
unsigned int D1=0, D2=0;
int T2 = 0;
long long OFF = 0; // offset at actual temperature
long long SENS = 0; // sensitivity at actual temperature
int dT = 0; // difference between actual and measured temperature
long long OFF2 = 0;
long long SENS2 = 0;
int P = 0; // compensated pressure value
memset(buffer, 0, 3);
if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
//D1 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);
//D2 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);
dT = D2 - ((unsigned int)C[5] << 8);
g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));
OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);
SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);
/*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/
if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)
{
printk("%s:temperature is error\n",__func__);
return -1;
}
if (g_ms5607_temp < 2000)
{
int tmp;
tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);
T2 = (int)((long long)(dT * dT) >> 31);
OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;
SENS2 = (long long)((tmp*tmp) << 1);
if (g_ms5607_temp < -1500)
{
tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);
OFF2 += 15 * tmp;
SENS2 += 8 * tmp;
}
}
else
{
T2=0;
OFF2 = 0;
SENS2 = 0;
}
g_ms5607_temp -= T2;
OFF -= OFF2;
SENS -= SENS2;
P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);
index = pressure_report_value(sensor->input_dev, P);
DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
return result;
}
struct sensor_operate pressure_ms5607_ops = {
.name = "pr_ms5607",
.type = SENSOR_TYPE_PRESSURE, //sensor type and it should be correct
.id_i2c = PRESSURE_ID_MS5607, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data
.read_len = 3, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 24, //8 bits
.ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
.range = {100,65535}, //range
.brightness = {10,255}, //brightness
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *pressure_get_ops(void)
{
return &pressure_ms5607_ops;
}
static int __init pressure_ms5607_init(void)
{
struct sensor_operate *ops = pressure_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, pressure_get_ops);
return result;
}
static void __exit pressure_ms5607_exit(void)
{
struct sensor_operate *ops = pressure_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, pressure_get_ops);
}
module_init(pressure_ms5607_init);
module_exit(pressure_ms5607_exit);

View File

@@ -1,256 +1,256 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CONFIG_REG (0x00)
#define TIM_CTL_REG (0x01)
#define ALS_CTL_REG (0x02)
#define INT_STATUS_REG (0x03)
#define PS_CTL_REG (0x04)
#define PS_ALS_DATA_REG (0x05)
#define ALS_WINDOWS_REG (0x08)
//enable bit[ 0-1], in register CONFIG_REG
#define ONLY_ALS_EN (0x00)
#define ONLY_PROX_EN (0x01)
#define ALL_PROX_ALS_EN (0x02)
#define ALL_IDLE (0x03)
#define POWER_MODE_MASK (0x0C)
#define POWER_UP_MODE (0x00)
#define POWER_DOWN_MODE (0x08)
#define POWER_RESET_MODE (0x0C)
static int sensor_power_updown(struct i2c_client *client, int on)
{
int result = 0;
char value = 0;
int i = 0;
for(i=0; i<3; i++)
{
if(!on)
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_DOWN_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
else
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_UP_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
if(!result)
break;
}
if(i>1)
printk("%s:set %d times",__func__,i);
return result;
}
/****************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;
char value = 0;
if(enable)
sensor_power_updown(client, 1);
value = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
if( (value & 0x03) == ONLY_ALS_EN )
{
value &= ~0x03;
value |= ALL_PROX_ALS_EN;
}
else if((value & 0x03) == ALL_IDLE )
{
value &= ~0x03;
value |= ONLY_PROX_EN;
}
}
else
{
if( (value & 0x03) == ONLY_PROX_EN )
{
value &= ~0x03;
value |= ALL_IDLE;
}
else if((value & 0x03) == ALL_PROX_ALS_EN )
{
value &= ~0x03;
value |= ONLY_ALS_EN;
}
}
sensor->ops->ctrl_data = value;
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;
char value = 0;
sensor_power_updown(client, 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 = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CONFIG_REG (0x00)
#define TIM_CTL_REG (0x01)
#define ALS_CTL_REG (0x02)
#define INT_STATUS_REG (0x03)
#define PS_CTL_REG (0x04)
#define PS_ALS_DATA_REG (0x05)
#define ALS_WINDOWS_REG (0x08)
//enable bit[ 0-1], in register CONFIG_REG
#define ONLY_ALS_EN (0x00)
#define ONLY_PROX_EN (0x01)
#define ALL_PROX_ALS_EN (0x02)
#define ALL_IDLE (0x03)
#define POWER_MODE_MASK (0x0C)
#define POWER_UP_MODE (0x00)
#define POWER_DOWN_MODE (0x08)
#define POWER_RESET_MODE (0x0C)
static int sensor_power_updown(struct i2c_client *client, int on)
{
int result = 0;
char value = 0;
int i = 0;
for(i=0; i<3; i++)
{
if(!on)
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_DOWN_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
else
{
value = sensor_read_reg(client, CONFIG_REG);
value &= ~POWER_MODE_MASK;
value |= POWER_UP_MODE;
result = sensor_write_reg(client, CONFIG_REG, value);
if(result)
return result;
}
if(!result)
break;
}
if(i>1)
printk("%s:set %d times",__func__,i);
return result;
}
/****************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;
char value = 0;
if(enable)
sensor_power_updown(client, 1);
value = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(enable)
{
if( (value & 0x03) == ONLY_ALS_EN )
{
value &= ~0x03;
value |= ALL_PROX_ALS_EN;
}
else if((value & 0x03) == ALL_IDLE )
{
value &= ~0x03;
value |= ONLY_PROX_EN;
}
}
else
{
if( (value & 0x03) == ONLY_PROX_EN )
{
value &= ~0x03;
value |= ALL_IDLE;
}
else if((value & 0x03) == ALL_PROX_ALS_EN )
{
value &= ~0x03;
value |= ONLY_ALS_EN;
}
}
sensor->ops->ctrl_data = value;
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;
char value = 0;
sensor_power_updown(client, 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 = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
//value = 0x69; //The ADC effective resolution = 17; Low lux threshold level = 9;
result = sensor_write_reg(client, ALS_CTL_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
result = sensor_write_reg(client, ALS_CTL_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
//value = 0x04;//0x01-0x0f; 17%->93.5% if value = 0x04,then Compensate Loss 52%
value = 0x02;//0x01-0x0f; 17%->93.5% if value = 0x02,then Compensate Loss 31%
result = sensor_write_reg(client, ALS_WINDOWS_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
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 value = 0;
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
}
value = sensor_read_reg(client, sensor->ops->read_reg);
input_report_abs(sensor->input_dev, ABS_DISTANCE, (value>>7)?0:1);
input_sync(sensor->input_dev);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,(value>>7)?0:1);
return result;
}
struct sensor_operate proximity_al3006_ops = {
.name = "ps_al3006",
.type = SENSOR_TYPE_PROXIMITY,//sensor type and it should be correct
.id_i2c = PROXIMITY_ID_AL3006, //i2c id number
.read_reg = PS_ALS_DATA_REG, //read data
.read_len = 1, //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 = CONFIG_REG, //enable or disable
.int_status_reg = INT_STATUS_REG, //intterupt status register
.range = {0,10}, //range
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *proximity_get_ops(void)
{
return &proximity_al3006_ops;
}
static int __init proximity_al3006_init(void)
{
struct sensor_operate *ops = proximity_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
return result;
}
static void __exit proximity_al3006_exit(void)
{
struct sensor_operate *ops = proximity_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);
}
module_init(proximity_al3006_init);
module_exit(proximity_al3006_exit);
value = 0x02;//0x01-0x0f; 17%->93.5% if value = 0x02,then Compensate Loss 31%
result = sensor_write_reg(client, ALS_WINDOWS_REG, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
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 value = 0;
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
}
value = sensor_read_reg(client, sensor->ops->read_reg);
input_report_abs(sensor->input_dev, ABS_DISTANCE, (value>>7)?0:1);
input_sync(sensor->input_dev);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,(value>>7)?0:1);
return result;
}
struct sensor_operate proximity_al3006_ops = {
.name = "ps_al3006",
.type = SENSOR_TYPE_PROXIMITY,//sensor type and it should be correct
.id_i2c = PROXIMITY_ID_AL3006, //i2c id number
.read_reg = PS_ALS_DATA_REG, //read data
.read_len = 1, //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 = CONFIG_REG, //enable or disable
.int_status_reg = INT_STATUS_REG, //intterupt status register
.range = {0,10}, //range
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *proximity_get_ops(void)
{
return &proximity_al3006_ops;
}
static int __init proximity_al3006_init(void)
{
struct sensor_operate *ops = proximity_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
return result;
}
static void __exit proximity_al3006_exit(void)
{
struct sensor_operate *ops = proximity_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);
}
module_init(proximity_al3006_init);
module_exit(proximity_al3006_exit);

View File

@@ -1,60 +1,60 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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>
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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>
#define AP3212B_NUM_CACHABLE_REGS 23
#define AP3216C_NUM_CACHABLE_REGS 26
#define AP3216C_NUM_CACHABLE_REGS 26
#define AP3212B_RAN_COMMAND 0x10
#define AP3212B_RAN_MASK 0x30
#define AP3212B_RAN_SHIFT (4)
#define AP3212B_MODE_COMMAND 0x00
#define AP3212B_MODE_SHIFT (0)
#define AP3212B_MODE_MASK 0x07
#define AP3212B_MODE_MASK 0x07
#define AP3212B_INT_COMMAND 0x01
#define AP3212B_INT_SHIFT (0)
#define AP3212B_INT_MASK 0x03
#define AP3212B_INT_PMASK 0x02
#define AP3212B_INT_AMASK 0x01
#define AP3212B_OBJ_COMMAND 0x0f
#define AP3212B_OBJ_MASK 0x80
#define AP3212B_OBJ_SHIFT (7)
#define AP3212B_OBJ_SHIFT (7)
/*
* register access helpers
*/
@@ -62,16 +62,16 @@
static int __ap321xx_read_reg(struct i2c_client *client,
u32 reg, u8 mask, u8 shift)
{
u8 val;
u8 val;
val = i2c_smbus_read_byte_data(client, reg);
return (val & mask) >> shift;
return (val & mask) >> shift;
}
static int __ap321xx_write_reg(struct i2c_client *client,
u32 reg, u8 mask, u8 shift, u8 val)
{
int ret = 0;
int ret = 0;
u8 tmp;
tmp = i2c_smbus_read_byte_data(client, reg);
@@ -79,16 +79,16 @@ static int __ap321xx_write_reg(struct i2c_client *client,
tmp |= val << shift;
ret = i2c_smbus_write_byte_data(client, reg, tmp);
return ret;
}
/*
* internally used functions
*/
*/
/* range */
static int ap321xx_set_range(struct i2c_client *client, int range)
static int ap321xx_set_range(struct i2c_client *client, int range)
{
return __ap321xx_write_reg(client, AP3212B_RAN_COMMAND,
AP3212B_RAN_MASK, AP3212B_RAN_SHIFT, range);;
@@ -98,36 +98,36 @@ static int ap321xx_set_range(struct i2c_client *client, int range)
/* mode */
static int ap321xx_get_mode(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int ret;
ret = __ap321xx_read_reg(client, sensor->ops->ctrl_reg,
AP3212B_MODE_MASK, AP3212B_MODE_SHIFT);
return ret;
}
static int ap321xx_set_mode(struct i2c_client *client, int mode)
static int ap321xx_set_mode(struct i2c_client *client, int mode)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int ret;
ret = __ap321xx_write_reg(client, sensor->ops->ctrl_reg,
AP3212B_MODE_MASK, AP3212B_MODE_SHIFT, mode);
return ret;
}
}
static int ap321xx_get_intstat(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int val;
val = i2c_smbus_read_byte_data(client, sensor->ops->int_status_reg);
val &= AP3212B_INT_MASK;
return val >> AP3212B_INT_SHIFT;
}
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int val;
val = i2c_smbus_read_byte_data(client, sensor->ops->int_status_reg);
val &= AP3212B_INT_MASK;
return val >> AP3212B_INT_SHIFT;
}
static int ap321xx_get_object(struct i2c_client *client)
{
int val;
@@ -137,33 +137,33 @@ static int ap321xx_get_object(struct i2c_client *client)
return val >> AP3212B_OBJ_SHIFT;
}
static int ap321xx_product_detect(struct i2c_client *client)
static int ap321xx_product_detect(struct i2c_client *client)
{
int mid = i2c_smbus_read_byte_data(client, 0x03);
int pid = i2c_smbus_read_byte_data(client, 0x04);
int rid = i2c_smbus_read_byte_data(client, 0x05);
if ( mid == 0x01 && pid == 0x01 &&
if ( mid == 0x01 && pid == 0x01 &&
(rid == 0x03 || rid == 0x04) )
{
//printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
//printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
}
else if ( (mid == 0x01 && pid == 0x02 && rid == 0x00) ||
else if ( (mid == 0x01 && pid == 0x02 && rid == 0x00) ||
(mid == 0x02 && pid == 0x02 && rid == 0x01))
{
//printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
//printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
}
else
{
printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
return -EIO;
}
return 0;
}
}
static int ap321xx_init_client(struct i2c_client *client)
{
/* set defaults */
@@ -171,25 +171,25 @@ static int ap321xx_init_client(struct i2c_client *client)
ap321xx_set_mode(client, 0);
return 0;
}
}
static int ap321xx_psensor_enable(struct i2c_client *client)
{
int ret = 0,mode;
mode = ap321xx_get_mode(client);
if((mode & 0x02) == 0){
mode |= 0x02;
ret = ap321xx_set_mode(client,mode);
}
return ret;
}
static int ap321xx_psensor_disable(struct i2c_client *client)
{
int ret = 0,mode;
mode = ap321xx_get_mode(client);
if(mode & 0x02){
mode &= ~0x02;
@@ -198,125 +198,125 @@ static int ap321xx_psensor_disable(struct i2c_client *client)
ret = ap321xx_set_mode(client,mode);
}
return ret;
}
/****************operate according to sensor chip:start************/
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
//register setting according to chip datasheet
if (enable){
result = ap321xx_psensor_enable(client);
}
else
result = ap321xx_psensor_disable(client);
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 = ap321xx_product_detect(client);
if (result)
{
dev_err(&client->dev, "ret: %d, product version detect failed.\n",result);
return result;
}
/* initialize the AP3212B chip */
result = ap321xx_init_client(client);
if (result)
return result;
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 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 value = 0;
u8 int_stat;
int_stat = ap321xx_get_intstat(client);
// ALS int
if (int_stat & AP3212B_INT_PMASK)
{
value = ap321xx_get_object(client);
input_report_abs(sensor->input_dev, ABS_DISTANCE, value);
input_sync(sensor->input_dev);
}
/****************operate according to sensor chip:start************/
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
//register setting according to chip datasheet
if (enable){
result = ap321xx_psensor_enable(client);
}
return result;
}
struct sensor_operate proximity_ap321xx_ops = {
.name = "ps_ap321xx",
.type = SENSOR_TYPE_PROXIMITY, //sensor type and it should be correct
.id_i2c = PROXIMITY_ID_AP321XX, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data //there are two regs, we fix them in code.
.read_len = 1, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register //there are 3 regs, we fix them in code.
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 8, //8 bits
.ctrl_reg = AP3212B_MODE_COMMAND, //enable or disable
.int_status_reg = AP3212B_INT_COMMAND, //intterupt status register
.range = {0,10}, //range
.brightness ={10,255}, // brightness
.trig = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED,
.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 *proximity_get_ops(void)
{
return &proximity_ap321xx_ops;
}
static int __init proximity_ap321xx_init(void)
{
struct sensor_operate *ops = proximity_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
return result;
}
static void __exit proximity_ap321xx_exit(void)
{
struct sensor_operate *ops = proximity_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);
}
module_init(proximity_ap321xx_init);
module_exit(proximity_ap321xx_exit);
else
result = ap321xx_psensor_disable(client);
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 = ap321xx_product_detect(client);
if (result)
{
dev_err(&client->dev, "ret: %d, product version detect failed.\n",result);
return result;
}
/* initialize the AP3212B chip */
result = ap321xx_init_client(client);
if (result)
return result;
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 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 value = 0;
u8 int_stat;
int_stat = ap321xx_get_intstat(client);
// ALS int
if (int_stat & AP3212B_INT_PMASK)
{
value = ap321xx_get_object(client);
input_report_abs(sensor->input_dev, ABS_DISTANCE, value);
input_sync(sensor->input_dev);
}
return result;
}
struct sensor_operate proximity_ap321xx_ops = {
.name = "ps_ap321xx",
.type = SENSOR_TYPE_PROXIMITY, //sensor type and it should be correct
.id_i2c = PROXIMITY_ID_AP321XX, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data //there are two regs, we fix them in code.
.read_len = 1, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register //there are 3 regs, we fix them in code.
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 8, //8 bits
.ctrl_reg = AP3212B_MODE_COMMAND, //enable or disable
.int_status_reg = AP3212B_INT_COMMAND, //intterupt status register
.range = {0,10}, //range
.brightness ={10,255}, // brightness
.trig = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED,
.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 *proximity_get_ops(void)
{
return &proximity_ap321xx_ops;
}
static int __init proximity_ap321xx_init(void)
{
struct sensor_operate *ops = proximity_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
return result;
}
static void __exit proximity_ap321xx_exit(void)
{
struct sensor_operate *ops = proximity_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);
}
module_init(proximity_ap321xx_init);
module_exit(proximity_ap321xx_exit);

View File

@@ -1,262 +1,262 @@
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define ALS_CMD 0x01
#define ALS_DT1 0x02
#define ALS_DT2 0X03
#define ALS_THDH1 0X04
#define ALS_THDH2 0X05
#define ALS_THDL1 0X06
#define ALS_THDL2 0X07
#define STA_TUS 0X08
#define PS_CMD 0X09
#define PS_DT 0X0A
#define PS_THDH 0X0B
#define PS_THDL 0X0C
#define SW_RESET 0X80
//ALS_CMD
#define ALS_SD_ENABLE (0<<0)
#define ALS_SD_DISABLE (1<<0)
#define ALS_INT_DISABLE (0<<1)
#define ALS_INT_ENABLE (1<<1)
#define ALS_1T_100MS (0<<2)
#define ALS_2T_200MS (1<<2)
#define ALS_4T_400MS (2<<2)
#define ALS_8T_800MS (3<<2)
#define ALS_RANGE_57671 (0<<6)
#define ALS_RANGE_28836 (1<<6)
//PS_CMD
#define PS_SD_ENABLE (0<<0)
#define PS_SD_DISABLE (1<<0)
#define PS_INT_DISABLE (0<<1)
#define PS_INT_ENABLE (1<<1)
#define PS_10T_2MS (0<<2)
#define PS_15T_3MS (1<<2)
#define PS_20T_4MS (2<<2)
#define PS_25T_5MS (3<<2)
#define PS_CUR_100MA (0<<4)
#define PS_CUR_200MA (1<<4)
#define PS_SLP_10MS (0<<5)
#define PS_SLP_30MS (1<<5)
#define PS_SLP_90MS (2<<5)
#define PS_SLP_270MS (3<<5)
#define TRIG_PS_OR_LS (0<<7)
#define TRIG_PS_AND_LS (1<<7)
//STA_TUS
#define STA_PS_INT (1<<5)
#define STA_ALS_INT (1<<4)
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(!enable)
{
status = PS_SD_DISABLE;
sensor->ops->ctrl_data |= status;
}
else
{
status = ~PS_SD_DISABLE;
sensor->ops->ctrl_data &= status;
}
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__);
if(enable)
sensor->ops->report(sensor->client);
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;
result = sensor_write_reg(client, SW_RESET, 0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->ops->ctrl_data |= PS_15T_3MS| PS_SLP_90MS;
sensor->ops->ctrl_data &= ~TRIG_PS_AND_LS;
if(sensor->pdata->irq_enable)
sensor->ops->ctrl_data |= PS_INT_ENABLE;
else
sensor->ops->ctrl_data &= ~PS_INT_ENABLE;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
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 buffer[1] = {0};
if(sensor->ops->read_len < 1) //sensor->ops->read_len = 1
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 1);
buffer[0] = sensor->ops->read_reg;
result = sensor_rx_data(client, buffer, sensor->ops->read_len);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
value = buffer[0];
input_report_abs(sensor->input_dev, ABS_DISTANCE, (value>>2)?0:1);
input_sync(sensor->input_dev);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,(value>>2)?0:1);
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
if(value & STA_PS_INT)
{
value &= ~STA_PS_INT;
result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
}
return result;
}
struct sensor_operate proximity_stk3171_ops = {
.name = "ps_stk3171",
.type = SENSOR_TYPE_PROXIMITY, //sensor type and it should be correct
.id_i2c = PROXIMITY_ID_STK3171, //i2c id number
.read_reg = PS_DT, //read data
.read_len = 1, //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 = PS_CMD, //enable or disable
.int_status_reg = STA_TUS, //intterupt status register
.range = {0,1}, //range
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *proximity_get_ops(void)
{
return &proximity_stk3171_ops;
}
static int __init proximity_stk3171_init(void)
{
struct sensor_operate *ops = proximity_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
return result;
}
static void __exit proximity_stk3171_exit(void)
{
struct sensor_operate *ops = proximity_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);
}
module_init(proximity_stk3171_init);
module_exit(proximity_stk3171_exit);
/* drivers/input/sensors/access/kxtik.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define ALS_CMD 0x01
#define ALS_DT1 0x02
#define ALS_DT2 0X03
#define ALS_THDH1 0X04
#define ALS_THDH2 0X05
#define ALS_THDL1 0X06
#define ALS_THDL2 0X07
#define STA_TUS 0X08
#define PS_CMD 0X09
#define PS_DT 0X0A
#define PS_THDH 0X0B
#define PS_THDL 0X0C
#define SW_RESET 0X80
//ALS_CMD
#define ALS_SD_ENABLE (0<<0)
#define ALS_SD_DISABLE (1<<0)
#define ALS_INT_DISABLE (0<<1)
#define ALS_INT_ENABLE (1<<1)
#define ALS_1T_100MS (0<<2)
#define ALS_2T_200MS (1<<2)
#define ALS_4T_400MS (2<<2)
#define ALS_8T_800MS (3<<2)
#define ALS_RANGE_57671 (0<<6)
#define ALS_RANGE_28836 (1<<6)
//PS_CMD
#define PS_SD_ENABLE (0<<0)
#define PS_SD_DISABLE (1<<0)
#define PS_INT_DISABLE (0<<1)
#define PS_INT_ENABLE (1<<1)
#define PS_10T_2MS (0<<2)
#define PS_15T_3MS (1<<2)
#define PS_20T_4MS (2<<2)
#define PS_25T_5MS (3<<2)
#define PS_CUR_100MA (0<<4)
#define PS_CUR_200MA (1<<4)
#define PS_SLP_10MS (0<<5)
#define PS_SLP_30MS (1<<5)
#define PS_SLP_90MS (2<<5)
#define PS_SLP_270MS (3<<5)
#define TRIG_PS_OR_LS (0<<7)
#define TRIG_PS_AND_LS (1<<7)
//STA_TUS
#define STA_PS_INT (1<<5)
#define STA_ALS_INT (1<<4)
/****************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->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
//register setting according to chip datasheet
if(!enable)
{
status = PS_SD_DISABLE;
sensor->ops->ctrl_data |= status;
}
else
{
status = ~PS_SD_DISABLE;
sensor->ops->ctrl_data &= status;
}
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__);
if(enable)
sensor->ops->report(sensor->client);
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;
result = sensor_write_reg(client, SW_RESET, 0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->ops->ctrl_data |= PS_15T_3MS| PS_SLP_90MS;
sensor->ops->ctrl_data &= ~TRIG_PS_AND_LS;
if(sensor->pdata->irq_enable)
sensor->ops->ctrl_data |= PS_INT_ENABLE;
else
sensor->ops->ctrl_data &= ~PS_INT_ENABLE;
result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
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 buffer[1] = {0};
if(sensor->ops->read_len < 1) //sensor->ops->read_len = 1
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
memset(buffer, 0, 1);
buffer[0] = sensor->ops->read_reg;
result = sensor_rx_data(client, buffer, sensor->ops->read_len);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
value = buffer[0];
input_report_abs(sensor->input_dev, ABS_DISTANCE, (value>>2)?0:1);
input_sync(sensor->input_dev);
DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,(value>>2)?0:1);
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
if(value & STA_PS_INT)
{
value &= ~STA_PS_INT;
result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
}
return result;
}
struct sensor_operate proximity_stk3171_ops = {
.name = "ps_stk3171",
.type = SENSOR_TYPE_PROXIMITY, //sensor type and it should be correct
.id_i2c = PROXIMITY_ID_STK3171, //i2c id number
.read_reg = PS_DT, //read data
.read_len = 1, //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 = PS_CMD, //enable or disable
.int_status_reg = STA_TUS, //intterupt status register
.range = {0,1}, //range
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *proximity_get_ops(void)
{
return &proximity_stk3171_ops;
}
static int __init proximity_stk3171_init(void)
{
struct sensor_operate *ops = proximity_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
return result;
}
static void __exit proximity_stk3171_exit(void)
{
struct sensor_operate *ops = proximity_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);
}
module_init(proximity_stk3171_init);
module_exit(proximity_stk3171_exit);

File diff suppressed because it is too large Load Diff

View File

@@ -1,245 +1,245 @@
/* drivers/input/sensors/sensor-i2c.c - sensor i2c handle
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define SENSOR_I2C_RATE 200*1000
static int sensor_i2c_write(struct i2c_adapter *i2c_adap,
unsigned char address,
unsigned int len, unsigned char const *data)
{
struct i2c_msg msgs[1];
int res;
if (!data || !i2c_adap) {
printk("%s:line=%d,error\n",__func__,__LINE__);
return -EINVAL;
}
msgs[0].addr = address;
msgs[0].flags = 0; /* write */
msgs[0].buf = (unsigned char *)data;
msgs[0].len = len;
res = i2c_transfer(i2c_adap, msgs, 1);
if (res == 1)
return 0;
else if(res == 0)
return -EBUSY;
else
return res;
}
static int senosr_i2c_read(struct i2c_adapter *i2c_adap,
unsigned char address, unsigned char reg,
unsigned int len, unsigned char *data)
{
struct i2c_msg msgs[2];
int res;
if (!data || !i2c_adap) {
printk("%s:line=%d,error\n",__func__,__LINE__);
return -EINVAL;
}
msgs[0].addr = address;
msgs[0].flags = 0; /* write */
msgs[0].buf = &reg;
msgs[0].len = 1;
msgs[1].addr = address;
msgs[1].flags = I2C_M_RD;
msgs[1].buf = data;
msgs[1].len = len;
res = i2c_transfer(i2c_adap, msgs, 2);
if (res == 2)
return 0;
else if(res == 0)
return -EBUSY;
else
return res;
}
int sensor_rx_data(struct i2c_client *client, char *rxData, int length)
{
//struct sensor_private_data* sensor =
// (struct sensor_private_data *)i2c_get_clientdata(client);
int i = 0;
int ret = 0;
char reg = rxData[0];
ret = senosr_i2c_read(client->adapter, client->addr, reg, length, rxData);
DBG("addr=0x%x,len=%d,rxdata:",reg,length);
for(i=0; i<length; i++)
DBG("0x%x,",rxData[i]);
DBG("\n");
return ret;
}
EXPORT_SYMBOL(sensor_rx_data);
int sensor_tx_data(struct i2c_client *client, char *txData, int length)
{
//struct sensor_private_data* sensor =
//(struct sensor_private_data *)i2c_get_clientdata(client);
int i = 0;
int ret = 0;
DBG("addr=0x%x,len=%d,txdata:",txData[0],length);
for(i=1; i<length; i++)
DBG("0x%x,",txData[i]);
DBG("\n");
ret = sensor_i2c_write(client->adapter, client->addr, length, txData);
return ret;
}
EXPORT_SYMBOL(sensor_tx_data);
int sensor_write_reg(struct i2c_client *client, int addr, int value)
{
char buffer[2];
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
buffer[0] = addr;
buffer[1] = value;
ret = sensor_tx_data(client, &buffer[0], 2);
mutex_unlock(&sensor->i2c_mutex);
return ret;
}
EXPORT_SYMBOL(sensor_write_reg);
int sensor_read_reg(struct i2c_client *client, int addr)
{
char tmp[1] = {0};
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
tmp[0] = addr;
ret = sensor_rx_data(client, tmp, 1);
mutex_unlock(&sensor->i2c_mutex);
return tmp[0];
}
EXPORT_SYMBOL(sensor_read_reg);
static int i2c_master_normal_recv(const struct i2c_client *client, char *buf, int count, int scl_rate)
{
struct i2c_adapter *adap=client->adapter;
struct i2c_msg msg;
int ret;
msg.addr = client->addr;
msg.flags = client->flags | I2C_M_RD;
msg.len = count;
msg.buf = (char *)buf;
ret = i2c_transfer(adap, &msg, 1);
return (ret == 1) ? count : ret;
}
static int i2c_master_normal_send(const struct i2c_client *client, const char *buf, int count, int scl_rate)
{
int ret;
struct i2c_adapter *adap=client->adapter;
struct i2c_msg msg;
msg.addr = client->addr;
msg.flags = client->flags;
msg.len = count;
msg.buf = (char *)buf;
ret = i2c_transfer(adap, &msg, 1);
return (ret == 1) ? count : ret;
}
int sensor_tx_data_normal(struct i2c_client *client, char *buf, int num)
{
int ret = 0;
ret = i2c_master_normal_send(client, buf, num, SENSOR_I2C_RATE);
return (ret == num) ? 0 : ret;
}
EXPORT_SYMBOL(sensor_tx_data_normal);
int sensor_rx_data_normal(struct i2c_client *client, char *buf, int num)
{
int ret = 0;
ret = i2c_master_normal_recv(client, buf, num, SENSOR_I2C_RATE);
return (ret == num) ? 0 : ret;
}
EXPORT_SYMBOL(sensor_rx_data_normal);
int sensor_write_reg_normal(struct i2c_client *client, char value)
{
char buffer[2];
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
buffer[0] = value;
ret = sensor_tx_data_normal(client, &buffer[0], 1);
mutex_unlock(&sensor->i2c_mutex);
return ret;
}
EXPORT_SYMBOL(sensor_write_reg_normal);
int sensor_read_reg_normal(struct i2c_client *client)
{
char tmp[1] = {0};
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
ret = sensor_rx_data_normal(client, tmp, 1);
mutex_unlock(&sensor->i2c_mutex);
return tmp[0];
}
EXPORT_SYMBOL(sensor_read_reg_normal);
/* drivers/input/sensors/sensor-i2c.c - sensor i2c handle
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define SENSOR_I2C_RATE 200*1000
static int sensor_i2c_write(struct i2c_adapter *i2c_adap,
unsigned char address,
unsigned int len, unsigned char const *data)
{
struct i2c_msg msgs[1];
int res;
if (!data || !i2c_adap) {
printk("%s:line=%d,error\n",__func__,__LINE__);
return -EINVAL;
}
msgs[0].addr = address;
msgs[0].flags = 0; /* write */
msgs[0].buf = (unsigned char *)data;
msgs[0].len = len;
res = i2c_transfer(i2c_adap, msgs, 1);
if (res == 1)
return 0;
else if(res == 0)
return -EBUSY;
else
return res;
}
static int senosr_i2c_read(struct i2c_adapter *i2c_adap,
unsigned char address, unsigned char reg,
unsigned int len, unsigned char *data)
{
struct i2c_msg msgs[2];
int res;
if (!data || !i2c_adap) {
printk("%s:line=%d,error\n",__func__,__LINE__);
return -EINVAL;
}
msgs[0].addr = address;
msgs[0].flags = 0; /* write */
msgs[0].buf = &reg;
msgs[0].len = 1;
msgs[1].addr = address;
msgs[1].flags = I2C_M_RD;
msgs[1].buf = data;
msgs[1].len = len;
res = i2c_transfer(i2c_adap, msgs, 2);
if (res == 2)
return 0;
else if(res == 0)
return -EBUSY;
else
return res;
}
int sensor_rx_data(struct i2c_client *client, char *rxData, int length)
{
//struct sensor_private_data* sensor =
// (struct sensor_private_data *)i2c_get_clientdata(client);
int i = 0;
int ret = 0;
char reg = rxData[0];
ret = senosr_i2c_read(client->adapter, client->addr, reg, length, rxData);
DBG("addr=0x%x,len=%d,rxdata:",reg,length);
for(i=0; i<length; i++)
DBG("0x%x,",rxData[i]);
DBG("\n");
return ret;
}
EXPORT_SYMBOL(sensor_rx_data);
int sensor_tx_data(struct i2c_client *client, char *txData, int length)
{
//struct sensor_private_data* sensor =
//(struct sensor_private_data *)i2c_get_clientdata(client);
int i = 0;
int ret = 0;
DBG("addr=0x%x,len=%d,txdata:",txData[0],length);
for(i=1; i<length; i++)
DBG("0x%x,",txData[i]);
DBG("\n");
ret = sensor_i2c_write(client->adapter, client->addr, length, txData);
return ret;
}
EXPORT_SYMBOL(sensor_tx_data);
int sensor_write_reg(struct i2c_client *client, int addr, int value)
{
char buffer[2];
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
buffer[0] = addr;
buffer[1] = value;
ret = sensor_tx_data(client, &buffer[0], 2);
mutex_unlock(&sensor->i2c_mutex);
return ret;
}
EXPORT_SYMBOL(sensor_write_reg);
int sensor_read_reg(struct i2c_client *client, int addr)
{
char tmp[1] = {0};
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
tmp[0] = addr;
ret = sensor_rx_data(client, tmp, 1);
mutex_unlock(&sensor->i2c_mutex);
return tmp[0];
}
EXPORT_SYMBOL(sensor_read_reg);
static int i2c_master_normal_recv(const struct i2c_client *client, char *buf, int count, int scl_rate)
{
struct i2c_adapter *adap=client->adapter;
struct i2c_msg msg;
int ret;
msg.addr = client->addr;
msg.flags = client->flags | I2C_M_RD;
msg.len = count;
msg.buf = (char *)buf;
ret = i2c_transfer(adap, &msg, 1);
return (ret == 1) ? count : ret;
}
static int i2c_master_normal_send(const struct i2c_client *client, const char *buf, int count, int scl_rate)
{
int ret;
struct i2c_adapter *adap=client->adapter;
struct i2c_msg msg;
msg.addr = client->addr;
msg.flags = client->flags;
msg.len = count;
msg.buf = (char *)buf;
ret = i2c_transfer(adap, &msg, 1);
return (ret == 1) ? count : ret;
}
int sensor_tx_data_normal(struct i2c_client *client, char *buf, int num)
{
int ret = 0;
ret = i2c_master_normal_send(client, buf, num, SENSOR_I2C_RATE);
return (ret == num) ? 0 : ret;
}
EXPORT_SYMBOL(sensor_tx_data_normal);
int sensor_rx_data_normal(struct i2c_client *client, char *buf, int num)
{
int ret = 0;
ret = i2c_master_normal_recv(client, buf, num, SENSOR_I2C_RATE);
return (ret == num) ? 0 : ret;
}
EXPORT_SYMBOL(sensor_rx_data_normal);
int sensor_write_reg_normal(struct i2c_client *client, char value)
{
char buffer[2];
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
buffer[0] = value;
ret = sensor_tx_data_normal(client, &buffer[0], 1);
mutex_unlock(&sensor->i2c_mutex);
return ret;
}
EXPORT_SYMBOL(sensor_write_reg_normal);
int sensor_read_reg_normal(struct i2c_client *client)
{
char tmp[1] = {0};
int ret = 0;
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
mutex_lock(&sensor->i2c_mutex);
ret = sensor_rx_data_normal(client, tmp, 1);
mutex_unlock(&sensor->i2c_mutex);
return tmp[0];
}
EXPORT_SYMBOL(sensor_read_reg_normal);

View File

@@ -1,309 +1,309 @@
/* drivers/input/sensors/temperature/tmp_ms5607.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC OSR=256
#define CMD_ADC_512 0x02 // ADC OSR=512
#define CMD_ADC_1024 0x04 // ADC OSR=1024
#define CMD_ADC_2048 0x06 // ADC OSR=2048
#define CMD_ADC_4096 0x08 // ADC OSR=4096
#define CMD_PROM_RD 0xA0 // Prom read command
#if defined(CONFIG_PR_MS5607)
extern int g_ms5607_temp;
extern int g_ms5607_pr_status;
#else
static int g_ms5607_temp = 0;
static int g_ms5607_pr_status = SENSOR_OFF;
#endif
int g_ms5607_temp_status;
static int C[8] = {0};
/****************operate according to sensor chip:start************/
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
int i = 0;
char prom[16];
if((enable)&&(g_ms5607_pr_status == SENSOR_OFF))
{
result = sensor_write_reg_normal(client, CMD_RESET);
if(result)
printk("%s:line=%d,error\n",__func__,__LINE__);
//Read PROM (128 bit of calibration words)
memset(prom, 0, 16);
prom[0]= CMD_PROM_RD;//CMD_PROM_RD;
for(i=0; i<8; i++)
{
prom[i*2]= CMD_PROM_RD + i*2;
result = sensor_rx_data(client, &prom[i*2], 2);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
for (i=0;i<8;i++)
{
C[i] = prom[2*i] << 8 | prom[2*i + 1];
//printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
//printk("\nC[%d]=%d,",i+1,C[i]);
}
}
g_ms5607_temp_status = enable;
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;
g_ms5607_temp_status = sensor->status_cur;
//Reset
//result = sensor_write_reg_normal(client, CMD_RESET);
//if(result)
//printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
static int temperature_report_value(struct input_dev *input, int data)
{
//get temperature, high and temperature from register data
input_report_abs(input, ABS_THROTTLE, data);
input_sync(input);
return 0;
}
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 buffer[3];
char index = 0;
unsigned int D1=0, D2=0;
int T2 = 0;
long long OFF = 0; // offset at actual temperature
long long SENS = 0; // sensitivity at actual temperature
int dT = 0; // difference between actual and measured temperature
long long OFF2 = 0;
long long SENS2 = 0;
int P = 0; // compensated pressure value
memset(buffer, 0, 3);
if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
if(g_ms5607_pr_status == SENSOR_OFF)
{
//D1 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);
//D2 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);
dT = D2 - ((unsigned int)C[5] << 8);
g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));
OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);
SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);
/*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/
if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)
{
printk("%s:temperature is error\n",__func__);
return -1;
}
if (g_ms5607_temp < 2000)
{
int tmp;
tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);
T2 = (int)((long long)(dT * dT) >> 31);
OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;
SENS2 = (long long)((tmp*tmp) << 1);
if (g_ms5607_temp < -1500)
{
tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);
OFF2 += 15 * tmp;
SENS2 += 8 * tmp;
}
}
else
{
T2=0;
OFF2 = 0;
SENS2 = 0;
}
g_ms5607_temp -= T2;
OFF -= OFF2;
SENS -= SENS2;
P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);
index = temperature_report_value(sensor->input_dev, g_ms5607_temp);
DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
}
else
{
index = temperature_report_value(sensor->input_dev, g_ms5607_temp);
#if defined(CONFIG_PR_MS5607)
DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
#else
printk("%s:errror,need pr_ms5607\n",__func__);
#endif
}
return result;
}
struct sensor_operate temperature_ms5607_ops = {
.name = "tmp_ms5607",
.type = SENSOR_TYPE_TEMPERATURE, //sensor type and it should be correct
.id_i2c = TEMPERATURE_ID_MS5607, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data
.read_len = 3, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 24, //8 bits
.ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
.range = {100,65535}, //range
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *temperature_get_ops(void)
{
return &temperature_ms5607_ops;
}
static int __init temperature_ms5607_init(void)
{
struct sensor_operate *ops = temperature_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, temperature_get_ops);
return result;
}
static void __exit temperature_ms5607_exit(void)
{
struct sensor_operate *ops = temperature_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, temperature_get_ops);
}
module_init(temperature_ms5607_init);
module_exit(temperature_ms5607_exit);
/* drivers/input/sensors/temperature/tmp_ms5607.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* 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 <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 <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC OSR=256
#define CMD_ADC_512 0x02 // ADC OSR=512
#define CMD_ADC_1024 0x04 // ADC OSR=1024
#define CMD_ADC_2048 0x06 // ADC OSR=2048
#define CMD_ADC_4096 0x08 // ADC OSR=4096
#define CMD_PROM_RD 0xA0 // Prom read command
#if defined(CONFIG_PR_MS5607)
extern int g_ms5607_temp;
extern int g_ms5607_pr_status;
#else
static int g_ms5607_temp = 0;
static int g_ms5607_pr_status = SENSOR_OFF;
#endif
int g_ms5607_temp_status;
static int C[8] = {0};
/****************operate according to sensor chip:start************/
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int result = 0;
int i = 0;
char prom[16];
if((enable)&&(g_ms5607_pr_status == SENSOR_OFF))
{
result = sensor_write_reg_normal(client, CMD_RESET);
if(result)
printk("%s:line=%d,error\n",__func__,__LINE__);
//Read PROM (128 bit of calibration words)
memset(prom, 0, 16);
prom[0]= CMD_PROM_RD;//CMD_PROM_RD;
for(i=0; i<8; i++)
{
prom[i*2]= CMD_PROM_RD + i*2;
result = sensor_rx_data(client, &prom[i*2], 2);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
for (i=0;i<8;i++)
{
C[i] = prom[2*i] << 8 | prom[2*i + 1];
//printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
//printk("\nC[%d]=%d,",i+1,C[i]);
}
}
g_ms5607_temp_status = enable;
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;
g_ms5607_temp_status = sensor->status_cur;
//Reset
//result = sensor_write_reg_normal(client, CMD_RESET);
//if(result)
//printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
static int temperature_report_value(struct input_dev *input, int data)
{
//get temperature, high and temperature from register data
input_report_abs(input, ABS_THROTTLE, data);
input_sync(input);
return 0;
}
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 buffer[3];
char index = 0;
unsigned int D1=0, D2=0;
int T2 = 0;
long long OFF = 0; // offset at actual temperature
long long SENS = 0; // sensitivity at actual temperature
int dT = 0; // difference between actual and measured temperature
long long OFF2 = 0;
long long SENS2 = 0;
int P = 0; // compensated pressure value
memset(buffer, 0, 3);
if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
return -1;
}
if(g_ms5607_pr_status == SENSOR_OFF)
{
//D1 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);
//D2 conversion
sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);
msleep(10);
memset(buffer, 0, 3);
buffer[0] = CMD_ADC_READ;
result = sensor_rx_data(client, &buffer[0], 3);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);
dT = D2 - ((unsigned int)C[5] << 8);
g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));
OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);
SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);
/*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/
if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)
{
printk("%s:temperature is error\n",__func__);
return -1;
}
if (g_ms5607_temp < 2000)
{
int tmp;
tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);
T2 = (int)((long long)(dT * dT) >> 31);
OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;
SENS2 = (long long)((tmp*tmp) << 1);
if (g_ms5607_temp < -1500)
{
tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);
OFF2 += 15 * tmp;
SENS2 += 8 * tmp;
}
}
else
{
T2=0;
OFF2 = 0;
SENS2 = 0;
}
g_ms5607_temp -= T2;
OFF -= OFF2;
SENS -= SENS2;
P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);
index = temperature_report_value(sensor->input_dev, g_ms5607_temp);
DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
}
else
{
index = temperature_report_value(sensor->input_dev, g_ms5607_temp);
#if defined(CONFIG_PR_MS5607)
DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
#else
printk("%s:errror,need pr_ms5607\n",__func__);
#endif
}
return result;
}
struct sensor_operate temperature_ms5607_ops = {
.name = "tmp_ms5607",
.type = SENSOR_TYPE_TEMPERATURE, //sensor type and it should be correct
.id_i2c = TEMPERATURE_ID_MS5607, //i2c id number
.read_reg = SENSOR_UNKNOW_DATA, //read data
.read_len = 3, //data length
.id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
.id_data = SENSOR_UNKNOW_DATA, //device id
.precision = 24, //8 bits
.ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
.range = {100,65535}, //range
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
.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 *temperature_get_ops(void)
{
return &temperature_ms5607_ops;
}
static int __init temperature_ms5607_init(void)
{
struct sensor_operate *ops = temperature_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, temperature_get_ops);
return result;
}
static void __exit temperature_ms5607_exit(void)
{
struct sensor_operate *ops = temperature_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, temperature_get_ops);
}
module_init(temperature_ms5607_init);
module_exit(temperature_ms5607_exit);

View File

@@ -34,7 +34,7 @@ enum sensor_id {
ANGLE_ID_ALL,
ANGLE_ID_KXTIK,
ANGLE_ID_LIS3DH,
ACCEL_ID_ALL,
ACCEL_ID_LIS331,
ACCEL_ID_LSM303DLX,
@@ -89,15 +89,15 @@ enum sensor_id {
LIGHT_ID_STK3171,
LIGHT_ID_ISL29023,
LIGHT_ID_AP321XX,
LIGHT_ID_PHOTORESISTOR,
LIGHT_ID_PHOTORESISTOR,
LIGHT_ID_US5152,
PROXIMITY_ID_ALL,
PROXIMITY_ID_AL3006,
PROXIMITY_ID_STK3171,
PROXIMITY_ID_AP321XX,
TEMPERATURE_ID_ALL,
TEMPERATURE_ID_ALL,
TEMPERATURE_ID_MS5607,
PRESSURE_ID_ALL,
@@ -106,7 +106,7 @@ enum sensor_id {
HALL_ID_ALL,
HALL_ID_OCH165T,
SENSOR_NUM_ID,
};
@@ -118,12 +118,12 @@ struct sensor_axis {
};
struct sensor_flag {
atomic_t a_flag;
atomic_t m_flag;
atomic_t mv_flag;
atomic_t a_flag;
atomic_t m_flag;
atomic_t mv_flag;
atomic_t open_flag;
atomic_t debug_flag;
long long delay;
long long delay;
wait_queue_head_t open_wq;
};
@@ -133,7 +133,7 @@ struct sensor_operate {
int type;
int id_i2c;
int range[2];
int brightness[2];//backlight min_brightness max_brightness
int brightness[2];//backlight min_brightness max_brightness
int read_reg;
int read_len;
int id_reg;
@@ -144,8 +144,8 @@ struct sensor_operate {
int int_ctrl_reg;
int int_status_reg;
int trig; //intterupt trigger
int (*active)(struct i2c_client *client, int enable, int rate);
int (*init)(struct i2c_client *client);
int (*active)(struct i2c_client *client, int enable, int rate);
int (*init)(struct i2c_client *client);
int (*report)(struct i2c_client *client);
int (*suspend)(struct i2c_client *client);
int (*resume)(struct i2c_client *client);
@@ -157,16 +157,16 @@ struct sensor_operate {
/* Platform data for the sensor */
struct sensor_private_data {
int type;
struct i2c_client *client;
struct i2c_client *client;
struct input_dev *input_dev;
struct work_struct work;
struct delayed_work delaywork; /*report second event*/
struct sensor_axis axis;
char sensor_data[40]; //max support40 bytes data
atomic_t data_ready;
wait_queue_head_t data_ready_wq;
wait_queue_head_t data_ready_wq;
struct mutex data_mutex;
struct mutex operation_mutex;
struct mutex operation_mutex;
struct mutex sensor_mutex;
struct mutex i2c_mutex;
int status_cur;
@@ -175,7 +175,7 @@ struct sensor_private_data {
struct sensor_flag flags;
struct i2c_device_id *i2c_id;
struct sensor_platform_data *pdata;
struct sensor_operate *ops;
struct sensor_operate *ops;
struct file_operations fops;
struct miscdevice miscdev;
#ifdef CONFIG_HAS_EARLYSUSPEND
@@ -190,7 +190,7 @@ struct sensor_platform_data {
int power_pin;
int reset_pin;
int standby_pin;
int irq_enable; //if irq_enable=1 then use irq else use polling
int irq_enable; //if irq_enable=1 then use irq else use polling
int poll_delay_ms; //polling
int x_min; //filter
int y_min;
@@ -216,13 +216,13 @@ struct sensor_platform_data {
int (*gsensor_platform_wakeup)(void);
void (*exit_platform_hw)(void);
};
struct akm8975_platform_data {
short m_layout[4][3][3];
char project_name[64];
int gpio_DRDY;
};
struct akm_platform_data {
short m_layout[4][3][3];
char project_name[64];
@@ -291,8 +291,8 @@ extern int sensor_unregister_slave(int type,struct i2c_client *client,
#endif
#define LIGHTSENSOR_IOCTL_MAGIC 'l'
#define LIGHTSENSOR_IOCTL_GET_ENABLED _IOR(LIGHTSENSOR_IOCTL_MAGIC, 1, int *)
#define LIGHTSENSOR_IOCTL_ENABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *)
#define LIGHTSENSOR_IOCTL_GET_ENABLED _IOR(LIGHTSENSOR_IOCTL_MAGIC, 1, int *)
#define LIGHTSENSOR_IOCTL_ENABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *)
#define LIGHTSENSOR_IOCTL_DISABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 3, int *)
#ifdef CONFIG_COMPAT