From 7e8031c9295075deadde3532af1ecc6aab7146e7 Mon Sep 17 00:00:00 2001 From: "Huang, Tao" Date: Wed, 16 Nov 2016 10:25:18 +0800 Subject: [PATCH] input: sensors: fromdos and remove trailing whitespace Change-Id: I6799f2538f95953d1565ac805497161ce6043855 Signed-off-by: Huang, Tao --- drivers/input/sensors/Makefile | 28 +- drivers/input/sensors/accel/dmard10.c | 966 ++-- drivers/input/sensors/accel/lsm303d.c | 732 +-- drivers/input/sensors/angle/Makefile | 4 +- drivers/input/sensors/compass/ak09911.c | 1538 +++--- drivers/input/sensors/compass/ak8963.c | 1458 +++--- drivers/input/sensors/compass/ak8975.c | 1262 ++--- drivers/input/sensors/gyro/ewtsa.c | 772 +-- drivers/input/sensors/gyro/l3g20d.c | 484 +- drivers/input/sensors/gyro/l3g4200d.c | 484 +- drivers/input/sensors/lsensor/cm3217.c | 466 +- drivers/input/sensors/lsensor/cm3232.c | 480 +- drivers/input/sensors/lsensor/isl29023.c | 536 +- drivers/input/sensors/lsensor/ls_al3006.c | 584 +-- drivers/input/sensors/lsensor/ls_ap321xx.c | 460 +- drivers/input/sensors/lsensor/ls_stk3171.c | 628 +-- drivers/input/sensors/lsensor/ls_us5152.c | 876 ++-- drivers/input/sensors/pressure/pr_ms5607.c | 584 +-- drivers/input/sensors/psensor/ps_al3006.c | 506 +- drivers/input/sensors/psensor/ps_ap321xx.c | 400 +- drivers/input/sensors/psensor/ps_stk3171.c | 524 +- drivers/input/sensors/sensor-dev.c | 4564 ++++++++--------- drivers/input/sensors/sensor-i2c.c | 490 +- .../input/sensors/temperature/tmp_ms5607.c | 618 +-- include/linux/sensor-dev.h | 42 +- 25 files changed, 9743 insertions(+), 9743 deletions(-) diff --git a/drivers/input/sensors/Makefile b/drivers/input/sensors/Makefile index 100e65c50af6..ffd165174928 100755 --- a/drivers/input/sensors/Makefile +++ b/drivers/input/sensors/Makefile @@ -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 diff --git a/drivers/input/sensors/accel/dmard10.c b/drivers/input/sensors/accel/dmard10.c index f695818c3009..db1545aa462c 100755 --- a/drivers/input/sensors/accel/dmard10.c +++ b/drivers/input/sensors/accel/dmard10.c @@ -1,483 +1,483 @@ -/* drivers/input/sensors/access/dmard10.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: guoyi - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - -/* 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); - - /* »¥³âµØ»º´æÊý¾Ý. */ - 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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + +/* 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); + + /* »¥³âµØ»º´æÊý¾Ý. */ + 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); + + + diff --git a/drivers/input/sensors/accel/lsm303d.c b/drivers/input/sensors/accel/lsm303d.c index 013ac39cf9da..defb31d97bf7 100755 --- a/drivers/input/sensors/accel/lsm303d.c +++ b/drivers/input/sensors/accel/lsm303d.c @@ -1,366 +1,366 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: Bruins - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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); - - /* »¥³âµØ»º´æÊý¾Ý. */ - 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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + /* »¥³âµØ»º´æÊý¾Ý. */ + 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); + + + + diff --git a/drivers/input/sensors/angle/Makefile b/drivers/input/sensors/angle/Makefile index 104642da8afd..bf01de256af8 100755 --- a/drivers/input/sensors/angle/Makefile +++ b/drivers/input/sensors/angle/Makefile @@ -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 diff --git a/drivers/input/sensors/compass/ak09911.c b/drivers/input/sensors/compass/ak09911.c index 15e52c5f448a..1c5bdf6ec424 100755 --- a/drivers/input/sensors/compass/ak09911.c +++ b/drivers/input/sensors/compass/ak09911.c @@ -1,231 +1,231 @@ -/* drivers/input/sensors/access/akm09911.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - - -#define SENSOR_DATA_SIZE 9 -#define YPR_DATA_SIZE 16 -#define RWBUF_SIZE 16 - -#define ACC_DATA_FLAG 0 -#define MAG_DATA_FLAG 1 -#define ORI_DATA_FLAG 2 -#define AKM_NUM_SENSORS 3 - -#define ACC_DATA_READY (1<<(ACC_DATA_FLAG)) -#define MAG_DATA_READY (1<<(MAG_DATA_FLAG)) -#define ORI_DATA_READY (1<<(ORI_DATA_FLAG)) - -/*Constant definitions of the AK09911.*/ -#define AK09911_MEASUREMENT_TIME_US 10000 - -#define AK09911_MODE_SNG_MEASURE 0x01 -#define AK09911_MODE_SELF_TEST 0x10 -#define AK09911_MODE_FUSE_ACCESS 0x1F -#define AK09911_MODE_POWERDOWN 0x00 -#define AK09911_RESET_DATA 0x01 - - -/* Device specific constant values */ -#define AK09911_REG_WIA1 0x00 -#define AK09911_REG_WIA2 0x01 -#define AK09911_REG_INFO1 0x02 -#define AK09911_REG_INFO2 0x03 -#define AK09911_REG_ST1 0x10 -#define AK09911_REG_HXL 0x11 -#define AK09911_REG_HXH 0x12 -#define AK09911_REG_HYL 0x13 -#define AK09911_REG_HYH 0x14 -#define AK09911_REG_HZL 0x15 -#define AK09911_REG_HZH 0x16 -#define AK09911_REG_TMPS 0x17 -#define AK09911_REG_ST2 0x18 -#define AK09911_REG_CNTL1 0x30 -#define AK09911_REG_CNTL2 0x31 -#define AK09911_REG_CNTL3 0x32 - - -#define AK09911_FUSE_ASAX 0x60 -#define AK09911_FUSE_ASAY 0x61 -#define AK09911_FUSE_ASAZ 0x62 - -#define AK09911_INFO_SIZE 2 -#define AK09911_CONF_SIZE 3 - - - -#define COMPASS_IOCTL_MAGIC 'c' - -/* IOCTLs for AKM library */ -#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*) -#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*) -#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */ -#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short) -#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8]) -#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12]) -#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int) -#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int) -#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char) -#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3]) -#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char) -#define ECS_IOCTL_GET_INFO _IOR(COMPASS_IOCTL_MAGIC, 0x0C, short) -#define ECS_IOCTL_GET_CONF _IOR(COMPASS_IOCTL_MAGIC, 0x0D, short) -#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data) -#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short) - - - -#define AK09911_DEVICE_ID 0x05 -static struct i2c_client *this_client; -static struct miscdevice compass_dev_device; - -static short g_akm_rbuf[12]; -static char g_sensor_info[AK09911_INFO_SIZE]; -static char g_sensor_conf[AK09911_CONF_SIZE]; - - -/****************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; - - //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); - - //register setting according to chip datasheet - if(enable) - { - sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE; - } - else - { - sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN; - } - - 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; - - this_client = client; - - 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 = misc_register(&compass_dev_device); - if (result < 0) { - printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name); - result = -1; - } - - g_sensor_info[0] = AK09911_REG_WIA1; - result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE); - if(result) - { - printk("%s:line=%d,error\n",__func__,__LINE__); - return result; - } - - - g_sensor_conf[0] = AK09911_FUSE_ASAX; - result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE); - if(result) - { - printk("%s:line=%d,error\n",__func__,__LINE__); - return result; - } - - DBG("%s:status_cur=%d\n",__func__, sensor->status_cur); - return result; -} - -static int sensor_report_value(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - char buffer[SENSOR_DATA_SIZE] = {0}; - unsigned char *stat; - unsigned char *stat2; - int ret = 0; - char value = 0; - int i; - - if(sensor->ops->read_len < SENSOR_DATA_SIZE) //sensor->ops->read_len = 8 - { - printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len); - return -1; - } - - memset(buffer, 0, SENSOR_DATA_SIZE); - - /* 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); - - stat = &buffer[0]; - stat2 = &buffer[7]; - - /* +/* drivers/input/sensors/access/akm09911.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + + +#define SENSOR_DATA_SIZE 9 +#define YPR_DATA_SIZE 16 +#define RWBUF_SIZE 16 + +#define ACC_DATA_FLAG 0 +#define MAG_DATA_FLAG 1 +#define ORI_DATA_FLAG 2 +#define AKM_NUM_SENSORS 3 + +#define ACC_DATA_READY (1<<(ACC_DATA_FLAG)) +#define MAG_DATA_READY (1<<(MAG_DATA_FLAG)) +#define ORI_DATA_READY (1<<(ORI_DATA_FLAG)) + +/*Constant definitions of the AK09911.*/ +#define AK09911_MEASUREMENT_TIME_US 10000 + +#define AK09911_MODE_SNG_MEASURE 0x01 +#define AK09911_MODE_SELF_TEST 0x10 +#define AK09911_MODE_FUSE_ACCESS 0x1F +#define AK09911_MODE_POWERDOWN 0x00 +#define AK09911_RESET_DATA 0x01 + + +/* Device specific constant values */ +#define AK09911_REG_WIA1 0x00 +#define AK09911_REG_WIA2 0x01 +#define AK09911_REG_INFO1 0x02 +#define AK09911_REG_INFO2 0x03 +#define AK09911_REG_ST1 0x10 +#define AK09911_REG_HXL 0x11 +#define AK09911_REG_HXH 0x12 +#define AK09911_REG_HYL 0x13 +#define AK09911_REG_HYH 0x14 +#define AK09911_REG_HZL 0x15 +#define AK09911_REG_HZH 0x16 +#define AK09911_REG_TMPS 0x17 +#define AK09911_REG_ST2 0x18 +#define AK09911_REG_CNTL1 0x30 +#define AK09911_REG_CNTL2 0x31 +#define AK09911_REG_CNTL3 0x32 + + +#define AK09911_FUSE_ASAX 0x60 +#define AK09911_FUSE_ASAY 0x61 +#define AK09911_FUSE_ASAZ 0x62 + +#define AK09911_INFO_SIZE 2 +#define AK09911_CONF_SIZE 3 + + + +#define COMPASS_IOCTL_MAGIC 'c' + +/* IOCTLs for AKM library */ +#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*) +#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*) +#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */ +#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short) +#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8]) +#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12]) +#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int) +#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int) +#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char) +#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3]) +#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char) +#define ECS_IOCTL_GET_INFO _IOR(COMPASS_IOCTL_MAGIC, 0x0C, short) +#define ECS_IOCTL_GET_CONF _IOR(COMPASS_IOCTL_MAGIC, 0x0D, short) +#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data) +#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short) + + + +#define AK09911_DEVICE_ID 0x05 +static struct i2c_client *this_client; +static struct miscdevice compass_dev_device; + +static short g_akm_rbuf[12]; +static char g_sensor_info[AK09911_INFO_SIZE]; +static char g_sensor_conf[AK09911_CONF_SIZE]; + + +/****************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; + + //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); + + //register setting according to chip datasheet + if(enable) + { + sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE; + } + else + { + sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN; + } + + 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; + + this_client = client; + + 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 = misc_register(&compass_dev_device); + if (result < 0) { + printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name); + result = -1; + } + + g_sensor_info[0] = AK09911_REG_WIA1; + result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE); + if(result) + { + printk("%s:line=%d,error\n",__func__,__LINE__); + return result; + } + + + g_sensor_conf[0] = AK09911_FUSE_ASAX; + result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE); + if(result) + { + printk("%s:line=%d,error\n",__func__,__LINE__); + return result; + } + + DBG("%s:status_cur=%d\n",__func__, sensor->status_cur); + return result; +} + +static int sensor_report_value(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + char buffer[SENSOR_DATA_SIZE] = {0}; + unsigned char *stat; + unsigned char *stat2; + int ret = 0; + char value = 0; + int i; + + if(sensor->ops->read_len < SENSOR_DATA_SIZE) //sensor->ops->read_len = 8 + { + printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len); + return -1; + } + + memset(buffer, 0, SENSOR_DATA_SIZE); + + /* 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); + + stat = &buffer[0]; + stat2 = &buffer[7]; + + /* * ST : data ready - * Measurement has been completed and data is ready to be read. - */ - if ((*stat & 0x01) != 0x01) { - DBG(KERN_ERR "%s:ST is not set\n",__func__); - return -1; - } -#if 0 + */ + if ((*stat & 0x01) != 0x01) { + DBG(KERN_ERR "%s:ST is not set\n",__func__); + return -1; + } +#if 0 /* * ST2 : data error - * occurs when data read is started outside of a readable period; @@ -236,12 +236,12 @@ static int sensor_report_value(struct i2c_client *client) * corrupted. * DERR bit is self-clearing when ST2 register is read. */ - if (*stat2 & 0x04) - { - DBG(KERN_ERR "%s:compass data error\n",__func__); - return -2; - } - + if (*stat2 & 0x04) + { + DBG(KERN_ERR "%s:compass data error\n",__func__); + return -2; + } + /* * ST2 : overflow - * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT. @@ -251,544 +251,544 @@ static int sensor_report_value(struct i2c_client *client) * An error is returned. * HOFL bit clears when a new measurement starts. */ - if (*stat2 & 0x08) - { - DBG(KERN_ERR "%s:compass data overflow\n",__func__); - return -3; - } -#endif - /* »¥³âµØ»º´æÊý¾Ý. */ - mutex_lock(&sensor->data_mutex); - memcpy(sensor->sensor_data, buffer, sensor->ops->read_len); - mutex_unlock(&sensor->data_mutex); - DBG("%s:",__func__); - for(i=0; iops->read_len; i++) - DBG("0x%x,",buffer[i]); - DBG("\n"); - - 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); - } - - - //trigger next measurement - ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); - if(ret) - { - printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data); - return ret; - } - - return ret; -} - -static void compass_set_YPR(int *rbuf) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(this_client); - - /* No events are reported */ - if (!rbuf[0]) { - printk("%s:Don't waste a time.",__func__); - return; - } - - DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]); - - /* Report magnetic sensor information */ - if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) { - input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]); - input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]); - input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]); - input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]); - DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11], rbuf[4]); - } - - /* Report acceleration sensor information */ - if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) { - input_report_abs(sensor->input_dev, ABS_X, rbuf[1]); - input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]); - input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]); - input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]); - - DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]); - } - - /* Report magnetic vector information */ - if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) { - input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]); - input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]); - input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]); - input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]); - - DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]); - } - - input_sync(sensor->input_dev); - - memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL -} - - - -static int compass_dev_open(struct inode *inode, struct file *file) -{ - struct sensor_private_data* sensor = - (struct sensor_private_data *)i2c_get_clientdata(this_client); - int result = 0; - DBG("%s\n",__func__); - - return result; -} - - -static int compass_dev_release(struct inode *inode, struct file *file) -{ - struct sensor_private_data* sensor = - (struct sensor_private_data *)i2c_get_clientdata(this_client); - int result = 0; - DBG("%s\n",__func__); - - return result; -} - -static int compass_akm_set_mode(struct i2c_client *client, char mode) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - int result = 0; - - switch(mode & 0x1f) - { - case AK09911_MODE_SNG_MEASURE: - case AK09911_MODE_SELF_TEST: - case AK09911_MODE_FUSE_ACCESS: - if(sensor->status_cur == SENSOR_OFF) - { - if(sensor->pdata->irq_enable) - { - //DBG("%s:enable irq=%d\n",__func__,client->irq); - //enable_irq(client->irq); - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - - sensor->status_cur = SENSOR_ON; - } - - break; - - case AK09911_MODE_POWERDOWN: - if(sensor->status_cur == SENSOR_ON) - { - if(sensor->pdata->irq_enable) - { - //DBG("%s:disable irq=%d\n",__func__,client->irq); - //disable_irq_nosync(client->irq);//disable irq - } - else - cancel_delayed_work_sync(&sensor->delaywork); - - sensor->status_cur = SENSOR_OFF; - } - break; - - } - - switch(mode & 0x1f) - { - case AK09911_MODE_SNG_MEASURE: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK09911_MODE_SELF_TEST: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK09911_MODE_FUSE_ACCESS: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK09911_MODE_POWERDOWN: - /* Set powerdown mode */ - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - udelay(100); - break; - default: - printk("%s: Unknown mode(%d)", __func__, mode); - result = -EINVAL; - break; - } - DBG("%s:mode=0x%x\n",__func__,mode); - return result; - -} - -static int compass_akm_reset(struct i2c_client *client) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - int result = 0; - - if(sensor->pdata->reset_pin > 0) - { - gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW); - udelay(10); - gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH); - } - else - { - /* Set measure mode */ - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE); - if(result) - printk("%s:fail to Set measure mode\n",__func__); - } - - udelay(100); - - return result; - -} - - - -static int compass_akm_get_openstatus(void) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0)); - return atomic_read(&sensor->flags.open_flag); -} - -static int compass_akm_get_closestatus(void) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0)); - return atomic_read(&sensor->flags.open_flag); -} - - -/* ioctl - I/O control */ -static long compass_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - struct i2c_client *client = this_client; - void __user *argp = (void __user *)arg; - int result = 0; - struct akm_platform_data compass; - - /* NOTE: In this function the size of "char" should be 1-byte. */ - char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */ - char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */ - char mode; /* for SET_MODE*/ - int value[YPR_DATA_SIZE]; /* for SET_YPR */ - int status; /* for OPEN/CLOSE_STATUS */ - int ret = -1; /* Return value. */ - - //int8_t sensor_buf[SENSOR_DATA_SIZE]; /* for GETDATA */ - //int32_t ypr_buf[YPR_DATA_SIZE]; /* for SET_YPR */ - int16_t acc_buf[3]; /* for GET_ACCEL */ - int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */ - char layout; /* for GET_LAYOUT */ - char outbit; /* for GET_OUTBIT */ - - switch (cmd) { - case ECS_IOCTL_WRITE: - case ECS_IOCTL_READ: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) { - return -EFAULT; - } - break; - case ECS_IOCTL_SET_MODE: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&mode, argp, sizeof(mode))) { - return -EFAULT; - } - break; - case ECS_IOCTL_SET_YPR: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&value, argp, sizeof(value))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GETDATA: - case ECS_IOCTL_GET_OPEN_STATUS: - case ECS_IOCTL_GET_CLOSE_STATUS: - case ECS_IOCTL_GET_DELAY: - case ECS_IOCTL_GET_LAYOUT: - case ECS_IOCTL_GET_OUTBIT: - case ECS_IOCTL_GET_ACCEL: - case ECS_IOCTL_GET_INFO: - case ECS_IOCTL_GET_CONF: - /* Just check buffer pointer */ - if (argp == NULL) { - printk("%s:invalid argument\n",__func__); - return -EINVAL; - } - break; - default: - break; - } - - switch (cmd) { - case ECS_IOCTL_WRITE: - DBG("%s:ECS_IOCTL_WRITE start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { - mutex_unlock(&sensor->operation_mutex); - return -EINVAL; - } - ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]); - if (ret < 0) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fait to tx data\n",__func__); - return ret; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_READ: - DBG("%s:ECS_IOCTL_READ start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:data is error\n",__func__); - return -EINVAL; - } - ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]); - if (ret < 0) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fait to rx data\n",__func__); - return ret; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_SET_MODE: - DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if(sensor->ops->ctrl_data != mode) - { - ret = compass_akm_set_mode(client, mode); - if (ret < 0) { - printk("%s:fait to set mode\n",__func__); - mutex_unlock(&sensor->operation_mutex); - return ret; - } - - sensor->ops->ctrl_data = mode; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_GETDATA: - DBG("%s:ECS_IOCTL_GETDATA start\n",__func__); - mutex_lock(&sensor->data_mutex); - memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer - mutex_unlock(&sensor->data_mutex); - break; - case ECS_IOCTL_SET_YPR: - DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__); - mutex_lock(&sensor->data_mutex); - compass_set_YPR(value); - mutex_unlock(&sensor->data_mutex); - break; - case ECS_IOCTL_GET_OPEN_STATUS: - status = compass_akm_get_openstatus(); - DBG("%s:openstatus=%d\n",__func__,status); - break; - case ECS_IOCTL_GET_CLOSE_STATUS: - status = compass_akm_get_closestatus(); - DBG("%s:closestatus=%d\n",__func__,status); - break; - case ECS_IOCTL_GET_DELAY: - DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__); - mutex_lock(&sensor->operation_mutex); - delay[0] = sensor->flags.delay; - delay[1] = sensor->flags.delay; - delay[2] = sensor->flags.delay; - mutex_unlock(&sensor->operation_mutex); - break; - - case ECS_IOCTL_GET_PLATFORM_DATA: - DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__); - // memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout)); - // memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name)); - ret = copy_to_user(argp, &compass, sizeof(compass)); - if(ret < 0) - { - printk("%s:error,ret=%d\n",__FUNCTION__, ret); - return ret; - } - break; - case ECS_IOCTL_GET_LAYOUT: - DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__); + if (*stat2 & 0x08) + { + DBG(KERN_ERR "%s:compass data overflow\n",__func__); + return -3; + } +#endif + /* »¥³âµØ»º´æÊý¾Ý. */ + mutex_lock(&sensor->data_mutex); + memcpy(sensor->sensor_data, buffer, sensor->ops->read_len); + mutex_unlock(&sensor->data_mutex); + DBG("%s:",__func__); + for(i=0; iops->read_len; i++) + DBG("0x%x,",buffer[i]); + DBG("\n"); + + 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); + } + + + //trigger next measurement + ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); + if(ret) + { + printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data); + return ret; + } + + return ret; +} + +static void compass_set_YPR(int *rbuf) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(this_client); + + /* No events are reported */ + if (!rbuf[0]) { + printk("%s:Don't waste a time.",__func__); + return; + } + + DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]); + + /* Report magnetic sensor information */ + if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) { + input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]); + input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]); + input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]); + input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]); + DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11], rbuf[4]); + } + + /* Report acceleration sensor information */ + if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) { + input_report_abs(sensor->input_dev, ABS_X, rbuf[1]); + input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]); + input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]); + input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]); + + DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]); + } + + /* Report magnetic vector information */ + if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) { + input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]); + input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]); + input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]); + input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]); + + DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]); + } + + input_sync(sensor->input_dev); + + memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL +} + + + +static int compass_dev_open(struct inode *inode, struct file *file) +{ + struct sensor_private_data* sensor = + (struct sensor_private_data *)i2c_get_clientdata(this_client); + int result = 0; + DBG("%s\n",__func__); + + return result; +} + + +static int compass_dev_release(struct inode *inode, struct file *file) +{ + struct sensor_private_data* sensor = + (struct sensor_private_data *)i2c_get_clientdata(this_client); + int result = 0; + DBG("%s\n",__func__); + + return result; +} + +static int compass_akm_set_mode(struct i2c_client *client, char mode) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + int result = 0; + + switch(mode & 0x1f) + { + case AK09911_MODE_SNG_MEASURE: + case AK09911_MODE_SELF_TEST: + case AK09911_MODE_FUSE_ACCESS: + if(sensor->status_cur == SENSOR_OFF) + { + if(sensor->pdata->irq_enable) + { + //DBG("%s:enable irq=%d\n",__func__,client->irq); + //enable_irq(client->irq); + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + + sensor->status_cur = SENSOR_ON; + } + + break; + + case AK09911_MODE_POWERDOWN: + if(sensor->status_cur == SENSOR_ON) + { + if(sensor->pdata->irq_enable) + { + //DBG("%s:disable irq=%d\n",__func__,client->irq); + //disable_irq_nosync(client->irq);//disable irq + } + else + cancel_delayed_work_sync(&sensor->delaywork); + + sensor->status_cur = SENSOR_OFF; + } + break; + + } + + switch(mode & 0x1f) + { + case AK09911_MODE_SNG_MEASURE: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK09911_MODE_SELF_TEST: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK09911_MODE_FUSE_ACCESS: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK09911_MODE_POWERDOWN: + /* Set powerdown mode */ + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + udelay(100); + break; + default: + printk("%s: Unknown mode(%d)", __func__, mode); + result = -EINVAL; + break; + } + DBG("%s:mode=0x%x\n",__func__,mode); + return result; + +} + +static int compass_akm_reset(struct i2c_client *client) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + int result = 0; + + if(sensor->pdata->reset_pin > 0) + { + gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW); + udelay(10); + gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH); + } + else + { + /* Set measure mode */ + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE); + if(result) + printk("%s:fail to Set measure mode\n",__func__); + } + + udelay(100); + + return result; + +} + + + +static int compass_akm_get_openstatus(void) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0)); + return atomic_read(&sensor->flags.open_flag); +} + +static int compass_akm_get_closestatus(void) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0)); + return atomic_read(&sensor->flags.open_flag); +} + + +/* ioctl - I/O control */ +static long compass_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + struct i2c_client *client = this_client; + void __user *argp = (void __user *)arg; + int result = 0; + struct akm_platform_data compass; + + /* NOTE: In this function the size of "char" should be 1-byte. */ + char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */ + char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */ + char mode; /* for SET_MODE*/ + int value[YPR_DATA_SIZE]; /* for SET_YPR */ + int status; /* for OPEN/CLOSE_STATUS */ + int ret = -1; /* Return value. */ + + //int8_t sensor_buf[SENSOR_DATA_SIZE]; /* for GETDATA */ + //int32_t ypr_buf[YPR_DATA_SIZE]; /* for SET_YPR */ + int16_t acc_buf[3]; /* for GET_ACCEL */ + int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */ + char layout; /* for GET_LAYOUT */ + char outbit; /* for GET_OUTBIT */ + + switch (cmd) { + case ECS_IOCTL_WRITE: + case ECS_IOCTL_READ: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) { + return -EFAULT; + } + break; + case ECS_IOCTL_SET_MODE: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&mode, argp, sizeof(mode))) { + return -EFAULT; + } + break; + case ECS_IOCTL_SET_YPR: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GETDATA: + case ECS_IOCTL_GET_OPEN_STATUS: + case ECS_IOCTL_GET_CLOSE_STATUS: + case ECS_IOCTL_GET_DELAY: + case ECS_IOCTL_GET_LAYOUT: + case ECS_IOCTL_GET_OUTBIT: + case ECS_IOCTL_GET_ACCEL: + case ECS_IOCTL_GET_INFO: + case ECS_IOCTL_GET_CONF: + /* Just check buffer pointer */ + if (argp == NULL) { + printk("%s:invalid argument\n",__func__); + return -EINVAL; + } + break; + default: + break; + } + + switch (cmd) { + case ECS_IOCTL_WRITE: + DBG("%s:ECS_IOCTL_WRITE start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { + mutex_unlock(&sensor->operation_mutex); + return -EINVAL; + } + ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]); + if (ret < 0) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fait to tx data\n",__func__); + return ret; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_READ: + DBG("%s:ECS_IOCTL_READ start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:data is error\n",__func__); + return -EINVAL; + } + ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]); + if (ret < 0) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fait to rx data\n",__func__); + return ret; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_SET_MODE: + DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if(sensor->ops->ctrl_data != mode) + { + ret = compass_akm_set_mode(client, mode); + if (ret < 0) { + printk("%s:fait to set mode\n",__func__); + mutex_unlock(&sensor->operation_mutex); + return ret; + } + + sensor->ops->ctrl_data = mode; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_GETDATA: + DBG("%s:ECS_IOCTL_GETDATA start\n",__func__); + mutex_lock(&sensor->data_mutex); + memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer + mutex_unlock(&sensor->data_mutex); + break; + case ECS_IOCTL_SET_YPR: + DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__); + mutex_lock(&sensor->data_mutex); + compass_set_YPR(value); + mutex_unlock(&sensor->data_mutex); + break; + case ECS_IOCTL_GET_OPEN_STATUS: + status = compass_akm_get_openstatus(); + DBG("%s:openstatus=%d\n",__func__,status); + break; + case ECS_IOCTL_GET_CLOSE_STATUS: + status = compass_akm_get_closestatus(); + DBG("%s:closestatus=%d\n",__func__,status); + break; + case ECS_IOCTL_GET_DELAY: + DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__); + mutex_lock(&sensor->operation_mutex); + delay[0] = sensor->flags.delay; + delay[1] = sensor->flags.delay; + delay[2] = sensor->flags.delay; + mutex_unlock(&sensor->operation_mutex); + break; + + case ECS_IOCTL_GET_PLATFORM_DATA: + DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__); + // memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout)); + // memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name)); + ret = copy_to_user(argp, &compass, sizeof(compass)); + if(ret < 0) + { + printk("%s:error,ret=%d\n",__FUNCTION__, ret); + return ret; + } + break; + case ECS_IOCTL_GET_LAYOUT: + DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__); if((sensor->pdata->layout >= 1) && (sensor->pdata->layout <=8 )) layout = sensor->pdata->layout; else layout = 1; - break; - case ECS_IOCTL_GET_OUTBIT: - DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__); - outbit = 1; //sensor->pdata->outbit; - break; - case ECS_IOCTL_RESET: - DBG("%s:ECS_IOCTL_RESET start\n",__func__); - ret = compass_akm_reset(client); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_GET_ACCEL: - DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__); - mutex_lock(&sensor->operation_mutex); - acc_buf[0] = g_akm_rbuf[6]; - acc_buf[1] = g_akm_rbuf[7]; - acc_buf[2] = g_akm_rbuf[8]; - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_GET_INFO: - ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info)); - if(ret < 0) - { - printk("%s:error,ret=%d\n",__FUNCTION__, ret); - return ret; - } - break; - case ECS_IOCTL_GET_CONF: - ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf)); - if(ret < 0) - { - printk("%s:error,ret=%d\n",__FUNCTION__, ret); - return ret; - } - break; - - default: - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_READ: - if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) { - return -EFAULT; - } - break; - case ECS_IOCTL_GETDATA: - if (copy_to_user(argp, &compass_data, sizeof(compass_data))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_OPEN_STATUS: - case ECS_IOCTL_GET_CLOSE_STATUS: - if (copy_to_user(argp, &status, sizeof(status))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_DELAY: - if (copy_to_user(argp, &delay, sizeof(delay))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_LAYOUT: - if (copy_to_user(argp, &layout, sizeof(layout))) { - printk("%s:error:%d\n",__FUNCTION__,__LINE__); - return -EFAULT; - } - break; - case ECS_IOCTL_GET_OUTBIT: - if (copy_to_user(argp, &outbit, sizeof(outbit))) { - printk("%s:error:%d\n",__FUNCTION__,__LINE__); - return -EFAULT; - } - break; - case ECS_IOCTL_GET_ACCEL: - if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) { - printk("%s:error:%d\n",__FUNCTION__,__LINE__); - return -EFAULT; - } - break; - default: - break; - } - - return result; -} - -static struct file_operations compass_dev_fops = -{ - .owner = THIS_MODULE, - .open = compass_dev_open, - .release = compass_dev_release, - .unlocked_ioctl = compass_dev_ioctl, -}; - - -static struct miscdevice compass_dev_device = -{ - .minor = MISC_DYNAMIC_MINOR, - .name = "akm_dev", - .fops = &compass_dev_fops, -}; - -struct sensor_operate compass_akm09911_ops = { - .name = "akm09911", - .type = SENSOR_TYPE_COMPASS, //it is important - .id_i2c = COMPASS_ID_AK09911, - .read_reg = AK09911_REG_ST1, //read data - .read_len = SENSOR_DATA_SIZE, //data length - .id_reg = AK09911_REG_WIA2, //read id - .id_data = AK09911_DEVICE_ID, - .precision = 8, //12 bits - .ctrl_reg = AK09911_REG_CNTL2, //enable or disable - .int_status_reg = SENSOR_UNKNOW_DATA, //not exist - .range = {-0xffff,0xffff}, - .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT - .active = sensor_active, - .init = sensor_init, - .report = sensor_report_value, - .misc_dev = NULL, //private misc support -}; - -/****************operate according to sensor chip:end************/ - -//function name should not be changed -static struct sensor_operate *compass_get_ops(void) -{ - return &compass_akm09911_ops; -} - - -static int __init compass_akm09911_init(void) -{ - struct sensor_operate *ops = compass_get_ops(); - int result = 0; - int type = ops->type; - result = sensor_register_slave(type, NULL, NULL, compass_get_ops); - - return result; -} - -static void __exit compass_akm09911_exit(void) -{ - struct sensor_operate *ops = compass_get_ops(); - int type = ops->type; - sensor_unregister_slave(type, NULL, NULL, compass_get_ops); -} - - -module_init(compass_akm09911_init); -module_exit(compass_akm09911_exit); - - + break; + case ECS_IOCTL_GET_OUTBIT: + DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__); + outbit = 1; //sensor->pdata->outbit; + break; + case ECS_IOCTL_RESET: + DBG("%s:ECS_IOCTL_RESET start\n",__func__); + ret = compass_akm_reset(client); + if (ret < 0) + return ret; + break; + case ECS_IOCTL_GET_ACCEL: + DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__); + mutex_lock(&sensor->operation_mutex); + acc_buf[0] = g_akm_rbuf[6]; + acc_buf[1] = g_akm_rbuf[7]; + acc_buf[2] = g_akm_rbuf[8]; + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_GET_INFO: + ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info)); + if(ret < 0) + { + printk("%s:error,ret=%d\n",__FUNCTION__, ret); + return ret; + } + break; + case ECS_IOCTL_GET_CONF: + ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf)); + if(ret < 0) + { + printk("%s:error,ret=%d\n",__FUNCTION__, ret); + return ret; + } + break; + + default: + return -ENOTTY; + } + + switch (cmd) { + case ECS_IOCTL_READ: + if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) { + return -EFAULT; + } + break; + case ECS_IOCTL_GETDATA: + if (copy_to_user(argp, &compass_data, sizeof(compass_data))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_OPEN_STATUS: + case ECS_IOCTL_GET_CLOSE_STATUS: + if (copy_to_user(argp, &status, sizeof(status))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_DELAY: + if (copy_to_user(argp, &delay, sizeof(delay))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_LAYOUT: + if (copy_to_user(argp, &layout, sizeof(layout))) { + printk("%s:error:%d\n",__FUNCTION__,__LINE__); + return -EFAULT; + } + break; + case ECS_IOCTL_GET_OUTBIT: + if (copy_to_user(argp, &outbit, sizeof(outbit))) { + printk("%s:error:%d\n",__FUNCTION__,__LINE__); + return -EFAULT; + } + break; + case ECS_IOCTL_GET_ACCEL: + if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) { + printk("%s:error:%d\n",__FUNCTION__,__LINE__); + return -EFAULT; + } + break; + default: + break; + } + + return result; +} + +static struct file_operations compass_dev_fops = +{ + .owner = THIS_MODULE, + .open = compass_dev_open, + .release = compass_dev_release, + .unlocked_ioctl = compass_dev_ioctl, +}; + + +static struct miscdevice compass_dev_device = +{ + .minor = MISC_DYNAMIC_MINOR, + .name = "akm_dev", + .fops = &compass_dev_fops, +}; + +struct sensor_operate compass_akm09911_ops = { + .name = "akm09911", + .type = SENSOR_TYPE_COMPASS, //it is important + .id_i2c = COMPASS_ID_AK09911, + .read_reg = AK09911_REG_ST1, //read data + .read_len = SENSOR_DATA_SIZE, //data length + .id_reg = AK09911_REG_WIA2, //read id + .id_data = AK09911_DEVICE_ID, + .precision = 8, //12 bits + .ctrl_reg = AK09911_REG_CNTL2, //enable or disable + .int_status_reg = SENSOR_UNKNOW_DATA, //not exist + .range = {-0xffff,0xffff}, + .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT + .active = sensor_active, + .init = sensor_init, + .report = sensor_report_value, + .misc_dev = NULL, //private misc support +}; + +/****************operate according to sensor chip:end************/ + +//function name should not be changed +static struct sensor_operate *compass_get_ops(void) +{ + return &compass_akm09911_ops; +} + + +static int __init compass_akm09911_init(void) +{ + struct sensor_operate *ops = compass_get_ops(); + int result = 0; + int type = ops->type; + result = sensor_register_slave(type, NULL, NULL, compass_get_ops); + + return result; +} + +static void __exit compass_akm09911_exit(void) +{ + struct sensor_operate *ops = compass_get_ops(); + int type = ops->type; + sensor_unregister_slave(type, NULL, NULL, compass_get_ops); +} + + +module_init(compass_akm09911_init); +module_exit(compass_akm09911_exit); + + diff --git a/drivers/input/sensors/compass/ak8963.c b/drivers/input/sensors/compass/ak8963.c index 227e94109bd6..d919aaed3548 100644 --- a/drivers/input/sensors/compass/ak8963.c +++ b/drivers/input/sensors/compass/ak8963.c @@ -1,234 +1,234 @@ -/* drivers/input/sensors/access/akm8963.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - +/* drivers/input/sensors/access/akm8963.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + #define AKM_SENSOR_INFO_SIZE 2 #define AKM_SENSOR_CONF_SIZE 3 -#define SENSOR_DATA_SIZE 8 -#define YPR_DATA_SIZE 12 -#define RWBUF_SIZE 16 - -#define ACC_DATA_FLAG 0 -#define MAG_DATA_FLAG 1 -#define ORI_DATA_FLAG 2 -#define AKM_NUM_SENSORS 3 - -#define ACC_DATA_READY (1<<(ACC_DATA_FLAG)) -#define MAG_DATA_READY (1<<(MAG_DATA_FLAG)) -#define ORI_DATA_READY (1<<(ORI_DATA_FLAG)) - -/*! \name AK8963 constant definition - \anchor AK8963_Def - Constant definitions of the AK8963.*/ -#define AK8963_MEASUREMENT_TIME_US 10000 - -/*! \name AK8963 operation mode - \anchor AK8963_Mode - Defines an operation mode of the AK8963.*/ -/*! @{*/ -#define AK8963_MODE_SNG_MEASURE 0x01 -#define AK8963_MODE_SELF_TEST 0x08 -#define AK8963_MODE_FUSE_ACCESS 0x0F -#define AK8963_MODE_POWERDOWN 0x00 - -/*! @}*/ - -/*! \name AK8963 register address -\anchor AK8963_REG -Defines a register address of the AK8963.*/ -/*! @{*/ -#define AK8963_REG_WIA 0x00 -#define AK8963_REG_INFO 0x01 -#define AK8963_REG_ST1 0x02 -#define AK8963_REG_HXL 0x03 -#define AK8963_REG_HXH 0x04 -#define AK8963_REG_HYL 0x05 -#define AK8963_REG_HYH 0x06 -#define AK8963_REG_HZL 0x07 -#define AK8963_REG_HZH 0x08 -#define AK8963_REG_ST2 0x09 -#define AK8963_REG_CNTL1 0x0A -#define AK8963_REG_CNTL2 0x0B -#define AK8963_REG_ASTC 0x0C -#define AK8963_REG_TS1 0x0D -#define AK8963_REG_TS2 0x0E -#define AK8963_REG_I2CDIS 0x0F +#define SENSOR_DATA_SIZE 8 +#define YPR_DATA_SIZE 12 +#define RWBUF_SIZE 16 + +#define ACC_DATA_FLAG 0 +#define MAG_DATA_FLAG 1 +#define ORI_DATA_FLAG 2 +#define AKM_NUM_SENSORS 3 + +#define ACC_DATA_READY (1<<(ACC_DATA_FLAG)) +#define MAG_DATA_READY (1<<(MAG_DATA_FLAG)) +#define ORI_DATA_READY (1<<(ORI_DATA_FLAG)) + +/*! \name AK8963 constant definition + \anchor AK8963_Def + Constant definitions of the AK8963.*/ +#define AK8963_MEASUREMENT_TIME_US 10000 + +/*! \name AK8963 operation mode + \anchor AK8963_Mode + Defines an operation mode of the AK8963.*/ +/*! @{*/ +#define AK8963_MODE_SNG_MEASURE 0x01 +#define AK8963_MODE_SELF_TEST 0x08 +#define AK8963_MODE_FUSE_ACCESS 0x0F +#define AK8963_MODE_POWERDOWN 0x00 + +/*! @}*/ + +/*! \name AK8963 register address +\anchor AK8963_REG +Defines a register address of the AK8963.*/ +/*! @{*/ +#define AK8963_REG_WIA 0x00 +#define AK8963_REG_INFO 0x01 +#define AK8963_REG_ST1 0x02 +#define AK8963_REG_HXL 0x03 +#define AK8963_REG_HXH 0x04 +#define AK8963_REG_HYL 0x05 +#define AK8963_REG_HYH 0x06 +#define AK8963_REG_HZL 0x07 +#define AK8963_REG_HZH 0x08 +#define AK8963_REG_ST2 0x09 +#define AK8963_REG_CNTL1 0x0A +#define AK8963_REG_CNTL2 0x0B +#define AK8963_REG_ASTC 0x0C +#define AK8963_REG_TS1 0x0D +#define AK8963_REG_TS2 0x0E +#define AK8963_REG_I2CDIS 0x0F #define AK8963_WIA_VALUE 0x48 -/*! @}*/ - -/*! \name AK8963 fuse-rom address -\anchor AK8963_FUSE -Defines a read-only address of the fuse ROM of the AK8963.*/ -/*! @{*/ -#define AK8963_FUSE_ASAX 0x10 -#define AK8963_FUSE_ASAY 0x11 -#define AK8963_FUSE_ASAZ 0x12 -/*! @}*/ - -#define AK8963_INFO_DATA (0x03<<3) - - -#define COMPASS_IOCTL_MAGIC 'c' - -/* IOCTLs for AKM library */ -#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*) -#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*) -#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */ -#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short) -#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE]) -#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12]) -#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int) -#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int) -#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char) -#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3]) -#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char) -#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short) -#define ECS_IOCTL_GET_PROJECT_NAME _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64]) -#define ECS_IOCTL_GET_MATRIX _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3]) -#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data) +/*! @}*/ + +/*! \name AK8963 fuse-rom address +\anchor AK8963_FUSE +Defines a read-only address of the fuse ROM of the AK8963.*/ +/*! @{*/ +#define AK8963_FUSE_ASAX 0x10 +#define AK8963_FUSE_ASAY 0x11 +#define AK8963_FUSE_ASAZ 0x12 +/*! @}*/ + +#define AK8963_INFO_DATA (0x03<<3) + + +#define COMPASS_IOCTL_MAGIC 'c' + +/* IOCTLs for AKM library */ +#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*) +#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*) +#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */ +#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short) +#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE]) +#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12]) +#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int) +#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int) +#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char) +#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3]) +#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char) +#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short) +#define ECS_IOCTL_GET_PROJECT_NAME _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64]) +#define ECS_IOCTL_GET_MATRIX _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3]) +#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data) #define ECS_IOCTL_GET_INFO _IOR(COMPASS_IOCTL_MAGIC, 0x27, unsigned char[AKM_SENSOR_INFO_SIZE]) #define ECS_IOCTL_GET_CONF _IOR(COMPASS_IOCTL_MAGIC, 0x28, unsigned char[AKM_SENSOR_CONF_SIZE]) - -#define AK8963_DEVICE_ID 0x48 -static struct i2c_client *this_client; -static struct miscdevice compass_dev_device; - -static short g_akm_rbuf[12]; - - -/****************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; - - //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); - - //register setting according to chip datasheet - if(enable) - { - sensor->ops->ctrl_data = AK8963_MODE_SNG_MEASURE; - } - else - { - sensor->ops->ctrl_data = AK8963_MODE_POWERDOWN; - } - - 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 info = 0; - - this_client = client; - - result = sensor->ops->active(client,0,0); - if(result) - { - printk("%s:line=%d,error\n",__func__,__LINE__); - return result; - } - - sensor->status_cur = SENSOR_OFF; - - info = sensor_read_reg(client, AK8963_REG_INFO); - if((info & (0x0f<<3)) != AK8963_INFO_DATA) - { - printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name); - return -1; - } - - result = misc_register(&compass_dev_device); - if (result < 0) { - printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name); - result = -1; - } - - DBG("%s:status_cur=%d\n",__func__, sensor->status_cur); - return result; -} - -static int sensor_report_value(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - char buffer[8] = {0}; - unsigned char *stat; - unsigned char *stat2; - int ret = 0; - char value = 0; - int i; - - if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8 - { - 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); - - stat = &buffer[0]; - stat2 = &buffer[7]; - - /* + +#define AK8963_DEVICE_ID 0x48 +static struct i2c_client *this_client; +static struct miscdevice compass_dev_device; + +static short g_akm_rbuf[12]; + + +/****************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; + + //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); + + //register setting according to chip datasheet + if(enable) + { + sensor->ops->ctrl_data = AK8963_MODE_SNG_MEASURE; + } + else + { + sensor->ops->ctrl_data = AK8963_MODE_POWERDOWN; + } + + 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 info = 0; + + this_client = client; + + result = sensor->ops->active(client,0,0); + if(result) + { + printk("%s:line=%d,error\n",__func__,__LINE__); + return result; + } + + sensor->status_cur = SENSOR_OFF; + + info = sensor_read_reg(client, AK8963_REG_INFO); + if((info & (0x0f<<3)) != AK8963_INFO_DATA) + { + printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name); + return -1; + } + + result = misc_register(&compass_dev_device); + if (result < 0) { + printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name); + result = -1; + } + + DBG("%s:status_cur=%d\n",__func__, sensor->status_cur); + return result; +} + +static int sensor_report_value(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + char buffer[8] = {0}; + unsigned char *stat; + unsigned char *stat2; + int ret = 0; + char value = 0; + int i; + + if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8 + { + 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); + + stat = &buffer[0]; + stat2 = &buffer[7]; + + /* * ST : data ready - * Measurement has been completed and data is ready to be read. - */ - if ((*stat & 0x01) != 0x01) { - DBG(KERN_ERR "%s:ST is not set\n",__func__); - return -1; - } + */ + if ((*stat & 0x01) != 0x01) { + DBG(KERN_ERR "%s:ST is not set\n",__func__); + return -1; + } /* * ST2 : data error - @@ -240,12 +240,12 @@ static int sensor_report_value(struct i2c_client *client) * corrupted. * DERR bit is self-clearing when ST2 register is read. */ - if (*stat2 & 0x04) - { - DBG(KERN_ERR "%s:compass data error\n",__func__); - return -2; - } - + if (*stat2 & 0x04) + { + DBG(KERN_ERR "%s:compass data error\n",__func__); + return -2; + } + /* * ST2 : overflow - * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT. @@ -255,54 +255,54 @@ static int sensor_report_value(struct i2c_client *client) * An error is returned. * HOFL bit clears when a new measurement starts. */ - if (*stat2 & 0x08) - { - DBG(KERN_ERR "%s:compass data overflow\n",__func__); - return -3; - } - - /* »¥³âµØ»º´æÊý¾Ý. */ - mutex_lock(&sensor->data_mutex); - memcpy(sensor->sensor_data, buffer, sensor->ops->read_len); - mutex_unlock(&sensor->data_mutex); - DBG("%s:",__func__); - for(i=0; iops->read_len; i++) - DBG("0x%x,",buffer[i]); - DBG("\n"); - - 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); - } - - - //trigger next measurement - ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); - if(ret) - { - printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data); - return ret; - } - - return ret; -} - -static void compass_set_YPR(int *rbuf) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(this_client); - - /* No events are reported */ - if (!rbuf[0]) { - printk("%s:Don't waste a time.",__func__); - return; - } - - DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]); - - /* Report magnetic sensor information */ + if (*stat2 & 0x08) + { + DBG(KERN_ERR "%s:compass data overflow\n",__func__); + return -3; + } + + /* »¥³âµØ»º´æÊý¾Ý. */ + mutex_lock(&sensor->data_mutex); + memcpy(sensor->sensor_data, buffer, sensor->ops->read_len); + mutex_unlock(&sensor->data_mutex); + DBG("%s:",__func__); + for(i=0; iops->read_len; i++) + DBG("0x%x,",buffer[i]); + DBG("\n"); + + 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); + } + + + //trigger next measurement + ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); + if(ret) + { + printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data); + return ret; + } + + return ret; +} + +static void compass_set_YPR(int *rbuf) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(this_client); + + /* No events are reported */ + if (!rbuf[0]) { + printk("%s:Don't waste a time.",__func__); + return; + } + + DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]); + + /* Report magnetic sensor information */ if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) { input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]); input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]); @@ -310,18 +310,18 @@ static void compass_set_YPR(int *rbuf) input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]); DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n", __func__, rbuf[9], rbuf[10], rbuf[11], rbuf[4]); } - - /* Report acceleration sensor information */ - if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) { - input_report_abs(sensor->input_dev, ABS_X, rbuf[1]); - input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]); - input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]); - input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]); - - DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]); - } - - /* Report magnetic vector information */ + + /* Report acceleration sensor information */ + if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) { + input_report_abs(sensor->input_dev, ABS_X, rbuf[1]); + input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]); + input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]); + input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]); + + DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]); + } + + /* Report magnetic vector information */ if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) { input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]); input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]); @@ -330,225 +330,225 @@ static void compass_set_YPR(int *rbuf) DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n", __func__, rbuf[5], rbuf[6], rbuf[7], rbuf[8]); } - - input_sync(sensor->input_dev); - - memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL -} - - - -static int compass_dev_open(struct inode *inode, struct file *file) -{ - int result = 0; - DBG("%s\n",__func__); - - return result; -} - - -static int compass_dev_release(struct inode *inode, struct file *file) -{ - int result = 0; - DBG("%s\n",__func__); - - return result; -} - -static int compass_akm_set_mode(struct i2c_client *client, char mode) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - int result = 0; - - switch(mode & 0x0f) - { - case AK8963_MODE_SNG_MEASURE: - case AK8963_MODE_SELF_TEST: - case AK8963_MODE_FUSE_ACCESS: - if(sensor->status_cur == SENSOR_OFF) - { - if(sensor->pdata->irq_enable) - { - //DBG("%s:enable irq=%d\n",__func__,client->irq); - //enable_irq(client->irq); - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - - sensor->status_cur = SENSOR_ON; - } - - break; - - case AK8963_MODE_POWERDOWN: - if(sensor->status_cur == SENSOR_ON) - { - if(sensor->pdata->irq_enable) - { - //DBG("%s:disable irq=%d\n",__func__,client->irq); - //disable_irq_nosync(client->irq);//disable irq - } - else - cancel_delayed_work_sync(&sensor->delaywork); - - sensor->status_cur = SENSOR_OFF; - } - break; - - } - - switch(mode & 0x0f) - { - case AK8963_MODE_SNG_MEASURE: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK8963_MODE_SELF_TEST: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK8963_MODE_FUSE_ACCESS: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK8963_MODE_POWERDOWN: - /* Set powerdown mode */ - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_MODE_POWERDOWN); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - udelay(100); - break; - default: - printk("%s: Unknown mode(%d)", __func__, mode); - result = -EINVAL; - break; - } - DBG("%s:mode=0x%x\n",__func__,mode); - return result; - -} - -static int compass_akm_reset(struct i2c_client *client) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - int result = 0; - - if(sensor->pdata->reset_pin > 0) - { - gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW); - udelay(10); - gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH); - } - else - { - /* Set measure mode */ - result = sensor_write_reg(client, AK8963_REG_CNTL2, AK8963_MODE_SNG_MEASURE); - if(result) - printk("%s:fail to Set measure mode\n",__func__); - } - - udelay(100); - - return result; - -} - - - -static int compass_akm_get_openstatus(void) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0)); - return atomic_read(&sensor->flags.open_flag); -} - -static int compass_akm_get_closestatus(void) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0)); - return atomic_read(&sensor->flags.open_flag); -} - - -/* ioctl - I/O control */ -static long compass_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - struct i2c_client *client = this_client; - void __user *argp = (void __user *)arg; - int result = 0; - struct akm_platform_data compass; + + input_sync(sensor->input_dev); + + memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL +} + + + +static int compass_dev_open(struct inode *inode, struct file *file) +{ + int result = 0; + DBG("%s\n",__func__); + + return result; +} + + +static int compass_dev_release(struct inode *inode, struct file *file) +{ + int result = 0; + DBG("%s\n",__func__); + + return result; +} + +static int compass_akm_set_mode(struct i2c_client *client, char mode) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + int result = 0; + + switch(mode & 0x0f) + { + case AK8963_MODE_SNG_MEASURE: + case AK8963_MODE_SELF_TEST: + case AK8963_MODE_FUSE_ACCESS: + if(sensor->status_cur == SENSOR_OFF) + { + if(sensor->pdata->irq_enable) + { + //DBG("%s:enable irq=%d\n",__func__,client->irq); + //enable_irq(client->irq); + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + + sensor->status_cur = SENSOR_ON; + } + + break; + + case AK8963_MODE_POWERDOWN: + if(sensor->status_cur == SENSOR_ON) + { + if(sensor->pdata->irq_enable) + { + //DBG("%s:disable irq=%d\n",__func__,client->irq); + //disable_irq_nosync(client->irq);//disable irq + } + else + cancel_delayed_work_sync(&sensor->delaywork); + + sensor->status_cur = SENSOR_OFF; + } + break; + + } + + switch(mode & 0x0f) + { + case AK8963_MODE_SNG_MEASURE: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK8963_MODE_SELF_TEST: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK8963_MODE_FUSE_ACCESS: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK8963_MODE_POWERDOWN: + /* Set powerdown mode */ + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_MODE_POWERDOWN); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + udelay(100); + break; + default: + printk("%s: Unknown mode(%d)", __func__, mode); + result = -EINVAL; + break; + } + DBG("%s:mode=0x%x\n",__func__,mode); + return result; + +} + +static int compass_akm_reset(struct i2c_client *client) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + int result = 0; + + if(sensor->pdata->reset_pin > 0) + { + gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW); + udelay(10); + gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH); + } + else + { + /* Set measure mode */ + result = sensor_write_reg(client, AK8963_REG_CNTL2, AK8963_MODE_SNG_MEASURE); + if(result) + printk("%s:fail to Set measure mode\n",__func__); + } + + udelay(100); + + return result; + +} + + + +static int compass_akm_get_openstatus(void) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0)); + return atomic_read(&sensor->flags.open_flag); +} + +static int compass_akm_get_closestatus(void) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0)); + return atomic_read(&sensor->flags.open_flag); +} + + +/* ioctl - I/O control */ +static long compass_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + struct i2c_client *client = this_client; + void __user *argp = (void __user *)arg; + int result = 0; + struct akm_platform_data compass; unsigned char sense_info[AKM_SENSOR_INFO_SIZE]; unsigned char sense_conf[AKM_SENSOR_CONF_SIZE]; - /* NOTE: In this function the size of "char" should be 1-byte. */ - char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */ - char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */ - char mode; /* for SET_MODE*/ - int value[12]; /* for SET_YPR */ - int status; /* for OPEN/CLOSE_STATUS */ - int ret = -1; /* Return value. */ - - //int8_t sensor_buf[SENSOR_DATA_SIZE]; /* for GETDATA */ - //int32_t ypr_buf[YPR_DATA_SIZE]; /* for SET_YPR */ - int16_t acc_buf[3]; /* for GET_ACCEL */ - int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */ - - char layout; /* for GET_LAYOUT */ - char outbit; /* for GET_OUTBIT */ - - switch (cmd) { - case ECS_IOCTL_WRITE: - case ECS_IOCTL_READ: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) { - return -EFAULT; - } - break; - case ECS_IOCTL_SET_MODE: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&mode, argp, sizeof(mode))) { - return -EFAULT; - } - break; - case ECS_IOCTL_SET_YPR: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&value, argp, sizeof(value))) { - return -EFAULT; - } - break; + /* NOTE: In this function the size of "char" should be 1-byte. */ + char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */ + char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */ + char mode; /* for SET_MODE*/ + int value[12]; /* for SET_YPR */ + int status; /* for OPEN/CLOSE_STATUS */ + int ret = -1; /* Return value. */ + + //int8_t sensor_buf[SENSOR_DATA_SIZE]; /* for GETDATA */ + //int32_t ypr_buf[YPR_DATA_SIZE]; /* for SET_YPR */ + int16_t acc_buf[3]; /* for GET_ACCEL */ + int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */ + + char layout; /* for GET_LAYOUT */ + char outbit; /* for GET_OUTBIT */ + + switch (cmd) { + case ECS_IOCTL_WRITE: + case ECS_IOCTL_READ: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) { + return -EFAULT; + } + break; + case ECS_IOCTL_SET_MODE: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&mode, argp, sizeof(mode))) { + return -EFAULT; + } + break; + case ECS_IOCTL_SET_YPR: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + break; case ECS_IOCTL_GET_INFO: case ECS_IOCTL_GET_CONF: - case ECS_IOCTL_GETDATA: - case ECS_IOCTL_GET_OPEN_STATUS: - case ECS_IOCTL_GET_CLOSE_STATUS: - case ECS_IOCTL_GET_DELAY: - case ECS_IOCTL_GET_LAYOUT: - case ECS_IOCTL_GET_OUTBIT: - case ECS_IOCTL_GET_ACCEL: - /* Just check buffer pointer */ - if (argp == NULL) { - printk("%s:invalid argument\n",__func__); - return -EINVAL; - } - break; - default: - break; - } - - switch (cmd) { + case ECS_IOCTL_GETDATA: + case ECS_IOCTL_GET_OPEN_STATUS: + case ECS_IOCTL_GET_CLOSE_STATUS: + case ECS_IOCTL_GET_DELAY: + case ECS_IOCTL_GET_LAYOUT: + case ECS_IOCTL_GET_OUTBIT: + case ECS_IOCTL_GET_ACCEL: + /* Just check buffer pointer */ + if (argp == NULL) { + printk("%s:invalid argument\n",__func__); + return -EINVAL; + } + break; + default: + break; + } + + switch (cmd) { case ECS_IOCTL_GET_INFO: sense_info[0] = AK8963_REG_WIA; mutex_lock(&sensor->operation_mutex); @@ -575,160 +575,160 @@ static long compass_dev_ioctl(struct file *file, return ret; } break; - case ECS_IOCTL_WRITE: - DBG("%s:ECS_IOCTL_WRITE start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { - mutex_unlock(&sensor->operation_mutex); - return -EINVAL; - } - ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]); - if (ret < 0) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fait to tx data\n",__func__); - return ret; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_READ: - DBG("%s:ECS_IOCTL_READ start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:data is error\n",__func__); - return -EINVAL; - } - ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]); - if (ret < 0) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fait to rx data\n",__func__); - return ret; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_SET_MODE: - DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if(sensor->ops->ctrl_data != mode) - { - ret = compass_akm_set_mode(client, mode); - if (ret < 0) { - printk("%s:fait to set mode\n",__func__); - mutex_unlock(&sensor->operation_mutex); - return ret; - } - - sensor->ops->ctrl_data = mode; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_GETDATA: - DBG("%s:ECS_IOCTL_GETDATA start\n",__func__); - mutex_lock(&sensor->data_mutex); - memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer - mutex_unlock(&sensor->data_mutex); - break; - case ECS_IOCTL_SET_YPR: - DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__); - mutex_lock(&sensor->data_mutex); - compass_set_YPR(value); - mutex_unlock(&sensor->data_mutex); - break; - case ECS_IOCTL_GET_OPEN_STATUS: - status = compass_akm_get_openstatus(); - DBG("%s:openstatus=%d\n",__func__,status); - break; - case ECS_IOCTL_GET_CLOSE_STATUS: - status = compass_akm_get_closestatus(); - DBG("%s:closestatus=%d\n",__func__,status); - break; - case ECS_IOCTL_GET_DELAY: - DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__); - mutex_lock(&sensor->operation_mutex); - delay[0] = sensor->flags.delay; - delay[1] = sensor->flags.delay; - delay[2] = sensor->flags.delay; - mutex_unlock(&sensor->operation_mutex); - break; - - case ECS_IOCTL_GET_PLATFORM_DATA: - DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__); - //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout)); - //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name)); - ret = copy_to_user(argp, &compass, sizeof(compass)); - if(ret < 0) - { - printk("%s:error,ret=%d\n",__FUNCTION__, ret); - return ret; - } - break; - case ECS_IOCTL_GET_LAYOUT: - DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__); - layout = sensor->pdata->layout; - break; - case ECS_IOCTL_GET_OUTBIT: - DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__); - outbit = 1; //sensor->pdata->outbit; - break; - case ECS_IOCTL_RESET: - DBG("%s:ECS_IOCTL_RESET start\n",__func__); - ret = compass_akm_reset(client); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_GET_ACCEL: - DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__); - mutex_lock(&sensor->operation_mutex); - acc_buf[0] = g_akm_rbuf[6]; - acc_buf[1] = g_akm_rbuf[7]; - acc_buf[2] = g_akm_rbuf[8]; - mutex_unlock(&sensor->operation_mutex); - break; - - default: - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_READ: - if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) { - return -EFAULT; - } - break; - case ECS_IOCTL_GETDATA: - if (copy_to_user(argp, &compass_data, sizeof(compass_data))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_OPEN_STATUS: - case ECS_IOCTL_GET_CLOSE_STATUS: - if (copy_to_user(argp, &status, sizeof(status))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_DELAY: - if (copy_to_user(argp, &delay, sizeof(delay))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_LAYOUT: - if (copy_to_user(argp, &layout, sizeof(layout))) { - printk("%s:error:%d\n",__FUNCTION__,__LINE__); - return -EFAULT; - } - break; - case ECS_IOCTL_GET_OUTBIT: - if (copy_to_user(argp, &outbit, sizeof(outbit))) { - printk("%s:error:%d\n",__FUNCTION__,__LINE__); - return -EFAULT; - } - break; - case ECS_IOCTL_GET_ACCEL: - if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) { - printk("%s:error:%d\n",__FUNCTION__,__LINE__); - return -EFAULT; - } - break; + case ECS_IOCTL_WRITE: + DBG("%s:ECS_IOCTL_WRITE start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { + mutex_unlock(&sensor->operation_mutex); + return -EINVAL; + } + ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]); + if (ret < 0) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fait to tx data\n",__func__); + return ret; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_READ: + DBG("%s:ECS_IOCTL_READ start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:data is error\n",__func__); + return -EINVAL; + } + ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]); + if (ret < 0) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fait to rx data\n",__func__); + return ret; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_SET_MODE: + DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if(sensor->ops->ctrl_data != mode) + { + ret = compass_akm_set_mode(client, mode); + if (ret < 0) { + printk("%s:fait to set mode\n",__func__); + mutex_unlock(&sensor->operation_mutex); + return ret; + } + + sensor->ops->ctrl_data = mode; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_GETDATA: + DBG("%s:ECS_IOCTL_GETDATA start\n",__func__); + mutex_lock(&sensor->data_mutex); + memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer + mutex_unlock(&sensor->data_mutex); + break; + case ECS_IOCTL_SET_YPR: + DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__); + mutex_lock(&sensor->data_mutex); + compass_set_YPR(value); + mutex_unlock(&sensor->data_mutex); + break; + case ECS_IOCTL_GET_OPEN_STATUS: + status = compass_akm_get_openstatus(); + DBG("%s:openstatus=%d\n",__func__,status); + break; + case ECS_IOCTL_GET_CLOSE_STATUS: + status = compass_akm_get_closestatus(); + DBG("%s:closestatus=%d\n",__func__,status); + break; + case ECS_IOCTL_GET_DELAY: + DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__); + mutex_lock(&sensor->operation_mutex); + delay[0] = sensor->flags.delay; + delay[1] = sensor->flags.delay; + delay[2] = sensor->flags.delay; + mutex_unlock(&sensor->operation_mutex); + break; + + case ECS_IOCTL_GET_PLATFORM_DATA: + DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__); + //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout)); + //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name)); + ret = copy_to_user(argp, &compass, sizeof(compass)); + if(ret < 0) + { + printk("%s:error,ret=%d\n",__FUNCTION__, ret); + return ret; + } + break; + case ECS_IOCTL_GET_LAYOUT: + DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__); + layout = sensor->pdata->layout; + break; + case ECS_IOCTL_GET_OUTBIT: + DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__); + outbit = 1; //sensor->pdata->outbit; + break; + case ECS_IOCTL_RESET: + DBG("%s:ECS_IOCTL_RESET start\n",__func__); + ret = compass_akm_reset(client); + if (ret < 0) + return ret; + break; + case ECS_IOCTL_GET_ACCEL: + DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__); + mutex_lock(&sensor->operation_mutex); + acc_buf[0] = g_akm_rbuf[6]; + acc_buf[1] = g_akm_rbuf[7]; + acc_buf[2] = g_akm_rbuf[8]; + mutex_unlock(&sensor->operation_mutex); + break; + + default: + return -ENOTTY; + } + + switch (cmd) { + case ECS_IOCTL_READ: + if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) { + return -EFAULT; + } + break; + case ECS_IOCTL_GETDATA: + if (copy_to_user(argp, &compass_data, sizeof(compass_data))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_OPEN_STATUS: + case ECS_IOCTL_GET_CLOSE_STATUS: + if (copy_to_user(argp, &status, sizeof(status))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_DELAY: + if (copy_to_user(argp, &delay, sizeof(delay))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_LAYOUT: + if (copy_to_user(argp, &layout, sizeof(layout))) { + printk("%s:error:%d\n",__FUNCTION__,__LINE__); + return -EFAULT; + } + break; + case ECS_IOCTL_GET_OUTBIT: + if (copy_to_user(argp, &outbit, sizeof(outbit))) { + printk("%s:error:%d\n",__FUNCTION__,__LINE__); + return -EFAULT; + } + break; + case ECS_IOCTL_GET_ACCEL: + if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) { + printk("%s:error:%d\n",__FUNCTION__,__LINE__); + return -EFAULT; + } + break; case ECS_IOCTL_GET_INFO: if (copy_to_user(argp, &sense_info, sizeof(sense_info))) { printk("%s:error:%d\n", __FUNCTION__, __LINE__); @@ -741,76 +741,76 @@ static long compass_dev_ioctl(struct file *file, return -EFAULT; } break; - default: - break; - } - - return result; -} - -static struct file_operations compass_dev_fops = -{ - .owner = THIS_MODULE, - .open = compass_dev_open, - .release = compass_dev_release, - .unlocked_ioctl = compass_dev_ioctl, -}; - - -static struct miscdevice compass_dev_device = -{ - .minor = MISC_DYNAMIC_MINOR, - .name = "akm8963_dev", - .fops = &compass_dev_fops, -}; - -struct sensor_operate compass_akm8963_ops = { - .name = "akm8963", - .type = SENSOR_TYPE_COMPASS, //it is important - .id_i2c = COMPASS_ID_AK8963, - .read_reg = AK8963_REG_ST1, //read data - .read_len = SENSOR_DATA_SIZE, //data length - .id_reg = AK8963_REG_WIA, //read id - .id_data = AK8963_DEVICE_ID, - .precision = 8, //12 bits - .ctrl_reg = AK8963_REG_CNTL1, //enable or disable - .int_status_reg = SENSOR_UNKNOW_DATA, //not exist - .range = {-0xffff,0xffff}, - .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT - .active = sensor_active, - .init = sensor_init, - .report = sensor_report_value, - .misc_dev = NULL, //private misc support -}; - -/****************operate according to sensor chip:end************/ - -//function name should not be changed -static struct sensor_operate *compass_get_ops(void) -{ - return &compass_akm8963_ops; -} - - -static int __init compass_akm8963_init(void) -{ - struct sensor_operate *ops = compass_get_ops(); - int result = 0; - int type = ops->type; - result = sensor_register_slave(type, NULL, NULL, compass_get_ops); - - return result; -} - -static void __exit compass_akm8963_exit(void) -{ - struct sensor_operate *ops = compass_get_ops(); - int type = ops->type; - sensor_unregister_slave(type, NULL, NULL, compass_get_ops); -} - - -module_init(compass_akm8963_init); -module_exit(compass_akm8963_exit); - - + default: + break; + } + + return result; +} + +static struct file_operations compass_dev_fops = +{ + .owner = THIS_MODULE, + .open = compass_dev_open, + .release = compass_dev_release, + .unlocked_ioctl = compass_dev_ioctl, +}; + + +static struct miscdevice compass_dev_device = +{ + .minor = MISC_DYNAMIC_MINOR, + .name = "akm8963_dev", + .fops = &compass_dev_fops, +}; + +struct sensor_operate compass_akm8963_ops = { + .name = "akm8963", + .type = SENSOR_TYPE_COMPASS, //it is important + .id_i2c = COMPASS_ID_AK8963, + .read_reg = AK8963_REG_ST1, //read data + .read_len = SENSOR_DATA_SIZE, //data length + .id_reg = AK8963_REG_WIA, //read id + .id_data = AK8963_DEVICE_ID, + .precision = 8, //12 bits + .ctrl_reg = AK8963_REG_CNTL1, //enable or disable + .int_status_reg = SENSOR_UNKNOW_DATA, //not exist + .range = {-0xffff,0xffff}, + .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT + .active = sensor_active, + .init = sensor_init, + .report = sensor_report_value, + .misc_dev = NULL, //private misc support +}; + +/****************operate according to sensor chip:end************/ + +//function name should not be changed +static struct sensor_operate *compass_get_ops(void) +{ + return &compass_akm8963_ops; +} + + +static int __init compass_akm8963_init(void) +{ + struct sensor_operate *ops = compass_get_ops(); + int result = 0; + int type = ops->type; + result = sensor_register_slave(type, NULL, NULL, compass_get_ops); + + return result; +} + +static void __exit compass_akm8963_exit(void) +{ + struct sensor_operate *ops = compass_get_ops(); + int type = ops->type; + sensor_unregister_slave(type, NULL, NULL, compass_get_ops); +} + + +module_init(compass_akm8963_init); +module_exit(compass_akm8963_exit); + + diff --git a/drivers/input/sensors/compass/ak8975.c b/drivers/input/sensors/compass/ak8975.c index 62e38911cd9b..f609e1791f4b 100755 --- a/drivers/input/sensors/compass/ak8975.c +++ b/drivers/input/sensors/compass/ak8975.c @@ -1,218 +1,218 @@ -/* drivers/input/sensors/access/akm8975.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - -#include - -#define SENSOR_DATA_SIZE 8 - - -/*! \name AK8975 operation mode - \anchor AK8975_Mode - Defines an operation mode of the AK8975.*/ -/*! @{*/ -#define AK8975_MODE_SNG_MEASURE 0x01 -#define AK8975_MODE_SELF_TEST 0x08 -#define AK8975_MODE_FUSE_ACCESS 0x0F -#define AK8975_MODE_POWERDOWN 0x00 -/*! @}*/ - -#define SENSOR_DATA_SIZE 8 /* Rx buffer size, i.e from ST1 to ST2 */ -#define RWBUF_SIZE 16 /* Read/Write buffer size.*/ - - -/*! \name AK8975 register address -\anchor AK8975_REG -Defines a register address of the AK8975.*/ -/*! @{*/ -#define AK8975_REG_WIA 0x00 -#define AK8975_REG_INFO 0x01 -#define AK8975_REG_ST1 0x02 -#define AK8975_REG_HXL 0x03 -#define AK8975_REG_HXH 0x04 -#define AK8975_REG_HYL 0x05 -#define AK8975_REG_HYH 0x06 -#define AK8975_REG_HZL 0x07 -#define AK8975_REG_HZH 0x08 -#define AK8975_REG_ST2 0x09 -#define AK8975_REG_CNTL 0x0A -#define AK8975_REG_RSV 0x0B -#define AK8975_REG_ASTC 0x0C -#define AK8975_REG_TS1 0x0D -#define AK8975_REG_TS2 0x0E -#define AK8975_REG_I2CDIS 0x0F -/*! @}*/ - -/*! \name AK8975 fuse-rom address -\anchor AK8975_FUSE -Defines a read-only address of the fuse ROM of the AK8975.*/ -/*! @{*/ -#define AK8975_FUSE_ASAX 0x10 -#define AK8975_FUSE_ASAY 0x11 -#define AK8975_FUSE_ASAZ 0x12 -/*! @}*/ - -#define AK8975_INFO_DATA (0x01<<3) - - -#define COMPASS_IOCTL_MAGIC 'c' - -/* IOCTLs for AKM library */ -#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*) -#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*) -#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */ -#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short) -#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE]) -#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12]) -#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int) -#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int) -#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char) -#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3]) -#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char) -#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short) -#define ECS_IOCTL_GET_PROJECT_NAME _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64]) -#define ECS_IOCTL_GET_MATRIX _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3]) -#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data) - - -#define AK8975_DEVICE_ID 0x48 -static struct i2c_client *this_client; -static struct miscdevice compass_dev_device; - - - - -/****************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; - - //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); - - //register setting according to chip datasheet - if(enable) - { - sensor->ops->ctrl_data = AK8975_MODE_SNG_MEASURE; - } - else - { - sensor->ops->ctrl_data = AK8975_MODE_POWERDOWN; - } - - 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 info = 0; - - this_client = client; - - result = sensor->ops->active(client,0,0); - if(result) - { - printk("%s:line=%d,error\n",__func__,__LINE__); - return result; - } - - sensor->status_cur = SENSOR_OFF; - - info = sensor_read_reg(client, AK8975_REG_INFO); - if((info & (0x0f<<3)) != AK8975_INFO_DATA) - - { - printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name); - return -1; - } - - result = misc_register(&compass_dev_device); - if (result < 0) { - printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name); - result = -1; - } - - DBG("%s:status_cur=%d\n",__func__, sensor->status_cur); - return result; -} - -static int sensor_report_value(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - char buffer[8] = {0}; - unsigned char *stat; - unsigned char *stat2; - int ret = 0; - char value = 0; - int i; - - if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8 - { - 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); - - stat = &buffer[0]; - stat2 = &buffer[7]; - - /* +/* drivers/input/sensors/access/akm8975.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + +#include + +#define SENSOR_DATA_SIZE 8 + + +/*! \name AK8975 operation mode + \anchor AK8975_Mode + Defines an operation mode of the AK8975.*/ +/*! @{*/ +#define AK8975_MODE_SNG_MEASURE 0x01 +#define AK8975_MODE_SELF_TEST 0x08 +#define AK8975_MODE_FUSE_ACCESS 0x0F +#define AK8975_MODE_POWERDOWN 0x00 +/*! @}*/ + +#define SENSOR_DATA_SIZE 8 /* Rx buffer size, i.e from ST1 to ST2 */ +#define RWBUF_SIZE 16 /* Read/Write buffer size.*/ + + +/*! \name AK8975 register address +\anchor AK8975_REG +Defines a register address of the AK8975.*/ +/*! @{*/ +#define AK8975_REG_WIA 0x00 +#define AK8975_REG_INFO 0x01 +#define AK8975_REG_ST1 0x02 +#define AK8975_REG_HXL 0x03 +#define AK8975_REG_HXH 0x04 +#define AK8975_REG_HYL 0x05 +#define AK8975_REG_HYH 0x06 +#define AK8975_REG_HZL 0x07 +#define AK8975_REG_HZH 0x08 +#define AK8975_REG_ST2 0x09 +#define AK8975_REG_CNTL 0x0A +#define AK8975_REG_RSV 0x0B +#define AK8975_REG_ASTC 0x0C +#define AK8975_REG_TS1 0x0D +#define AK8975_REG_TS2 0x0E +#define AK8975_REG_I2CDIS 0x0F +/*! @}*/ + +/*! \name AK8975 fuse-rom address +\anchor AK8975_FUSE +Defines a read-only address of the fuse ROM of the AK8975.*/ +/*! @{*/ +#define AK8975_FUSE_ASAX 0x10 +#define AK8975_FUSE_ASAY 0x11 +#define AK8975_FUSE_ASAZ 0x12 +/*! @}*/ + +#define AK8975_INFO_DATA (0x01<<3) + + +#define COMPASS_IOCTL_MAGIC 'c' + +/* IOCTLs for AKM library */ +#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*) +#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*) +#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */ +#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short) +#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE]) +#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12]) +#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int) +#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int) +#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char) +#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3]) +#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char) +#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short) +#define ECS_IOCTL_GET_PROJECT_NAME _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64]) +#define ECS_IOCTL_GET_MATRIX _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3]) +#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data) + + +#define AK8975_DEVICE_ID 0x48 +static struct i2c_client *this_client; +static struct miscdevice compass_dev_device; + + + + +/****************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; + + //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); + + //register setting according to chip datasheet + if(enable) + { + sensor->ops->ctrl_data = AK8975_MODE_SNG_MEASURE; + } + else + { + sensor->ops->ctrl_data = AK8975_MODE_POWERDOWN; + } + + 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 info = 0; + + this_client = client; + + result = sensor->ops->active(client,0,0); + if(result) + { + printk("%s:line=%d,error\n",__func__,__LINE__); + return result; + } + + sensor->status_cur = SENSOR_OFF; + + info = sensor_read_reg(client, AK8975_REG_INFO); + if((info & (0x0f<<3)) != AK8975_INFO_DATA) + + { + printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name); + return -1; + } + + result = misc_register(&compass_dev_device); + if (result < 0) { + printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name); + result = -1; + } + + DBG("%s:status_cur=%d\n",__func__, sensor->status_cur); + return result; +} + +static int sensor_report_value(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + char buffer[8] = {0}; + unsigned char *stat; + unsigned char *stat2; + int ret = 0; + char value = 0; + int i; + + if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8 + { + 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); + + stat = &buffer[0]; + stat2 = &buffer[7]; + + /* * ST : data ready - * Measurement has been completed and data is ready to be read. - */ - if ((*stat & 0x01) != 0x01) { - DBG(KERN_ERR "%s:ST is not set\n",__func__); - return -1; - } + */ + if ((*stat & 0x01) != 0x01) { + DBG(KERN_ERR "%s:ST is not set\n",__func__); + return -1; + } /* * ST2 : data error - @@ -224,12 +224,12 @@ static int sensor_report_value(struct i2c_client *client) * corrupted. * DERR bit is self-clearing when ST2 register is read. */ - if (*stat2 & 0x04) - { - DBG(KERN_ERR "%s:compass data error\n",__func__); - return -2; - } - + if (*stat2 & 0x04) + { + DBG(KERN_ERR "%s:compass data error\n",__func__); + return -2; + } + /* * ST2 : overflow - * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT. @@ -239,416 +239,416 @@ static int sensor_report_value(struct i2c_client *client) * An error is returned. * HOFL bit clears when a new measurement starts. */ - if (*stat2 & 0x08) - { - DBG(KERN_ERR "%s:compass data overflow\n",__func__); - return -3; - } - - /* »¥³âµØ»º´æÊý¾Ý. */ - mutex_lock(&sensor->data_mutex); - memcpy(sensor->sensor_data, buffer, sensor->ops->read_len); - mutex_unlock(&sensor->data_mutex); - DBG("%s:",__func__); - for(i=0; iops->read_len; i++) - DBG("0x%x,",buffer[i]); - DBG("\n"); - - 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); - } - - - //trigger next measurement - ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); - if(ret) - { - printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data); - return ret; - } - - return ret; -} - -static void compass_set_YPR(short *rbuf) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(this_client); - - /* Report magnetic sensor information */ - if (atomic_read(&sensor->flags.m_flag)) { - input_report_abs(sensor->input_dev, ABS_RX, rbuf[0]); - input_report_abs(sensor->input_dev, ABS_RY, rbuf[1]); - input_report_abs(sensor->input_dev, ABS_RZ, rbuf[2]); - input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]); - DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[0], rbuf[1], rbuf[2], rbuf[4]); - } - - /* Report acceleration sensor information */ - if (atomic_read(&sensor->flags.a_flag)) { - input_report_abs(sensor->input_dev, ABS_X, rbuf[6]); - input_report_abs(sensor->input_dev, ABS_Y, rbuf[7]); - input_report_abs(sensor->input_dev, ABS_Z, rbuf[8]); - input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[5]); - - DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[6], rbuf[7], rbuf[8], rbuf[5]); - } - - /* Report magnetic vector information */ - if (atomic_read(&sensor->flags.mv_flag)) { - input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[9]); - input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[10]); - input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[11]); - - DBG("%s:mv_flag:x=%d,y=%d,BRAKE=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11]); - } - - input_sync(sensor->input_dev); -} - - -static int compass_dev_open(struct inode *inode, struct file *file) -{ - int result = 0; - DBG("%s\n",__func__); - - return result; -} - - -static int compass_dev_release(struct inode *inode, struct file *file) -{ - int result = 0; - DBG("%s\n",__func__); - - return result; -} - -static int compass_akm_set_mode(struct i2c_client *client, char mode) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - int result = 0; - - switch(mode) - { - case AK8975_MODE_SNG_MEASURE: - case AK8975_MODE_SELF_TEST: - case AK8975_MODE_FUSE_ACCESS: - if(sensor->status_cur == SENSOR_OFF) - { - if(sensor->pdata->irq_enable) - { - //DBG("%s:enable irq=%d\n",__func__,client->irq); - //enable_irq(client->irq); - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - - sensor->status_cur = SENSOR_ON; - } - - break; - - case AK8975_MODE_POWERDOWN: - if(sensor->status_cur == SENSOR_ON) - { - if(sensor->pdata->irq_enable) - { - //DBG("%s:disable irq=%d\n",__func__,client->irq); - //disable_irq_nosync(client->irq);//disable irq - } - else - cancel_delayed_work_sync(&sensor->delaywork); - - sensor->status_cur = SENSOR_OFF; - } - break; - - } - - switch(mode) - { - case AK8975_MODE_SNG_MEASURE: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SNG_MEASURE); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK8975_MODE_SELF_TEST: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SELF_TEST); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK8975_MODE_FUSE_ACCESS: - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_FUSE_ACCESS); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - break; - case AK8975_MODE_POWERDOWN: - /* Set powerdown mode */ - result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_POWERDOWN); - if(result) - printk("%s:i2c error,mode=%d\n",__func__,mode); - udelay(100); - break; - default: - printk("%s: Unknown mode(%d)", __func__, mode); - result = -EINVAL; - break; - } - DBG("%s:mode=%d\n",__func__,mode); - return result; - -} - - -static int compass_akm_get_openstatus(void) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0)); - return atomic_read(&sensor->flags.open_flag); -} - -static int compass_akm_get_closestatus(void) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0)); - return atomic_read(&sensor->flags.open_flag); -} - - -/* ioctl - I/O control */ -static long compass_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); - struct i2c_client *client = this_client; - void __user *argp = (void __user *)arg; - int result = 0; - struct akm_platform_data compass; - - /* NOTE: In this function the size of "char" should be 1-byte. */ - char compass_data[SENSOR_DATA_SIZE];/* for GETDATA */ - char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */ - char mode; /* for SET_MODE*/ - short value[12]; /* for SET_YPR */ - short delay; /* for GET_DELAY */ - int status; /* for OPEN/CLOSE_STATUS */ - int ret = -1; /* Return value. */ - - switch (cmd) { - case ECS_IOCTL_WRITE: - case ECS_IOCTL_READ: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) { - return -EFAULT; - } - break; - case ECS_IOCTL_SET_MODE: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&mode, argp, sizeof(mode))) { - return -EFAULT; - } - break; - case ECS_IOCTL_SET_YPR: - if (argp == NULL) { - return -EINVAL; - } - if (copy_from_user(&value, argp, sizeof(value))) { - return -EFAULT; - } - break; - default: - break; - } - - switch (cmd) { - case ECS_IOCTL_WRITE: - DBG("%s:ECS_IOCTL_WRITE start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { - mutex_unlock(&sensor->operation_mutex); - return -EINVAL; - } - ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]); - if (ret < 0) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fait to tx data\n",__func__); - return ret; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_READ: - DBG("%s:ECS_IOCTL_READ start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:data is error\n",__func__); - return -EINVAL; - } - ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]); - if (ret < 0) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fait to rx data\n",__func__); - return ret; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_SET_MODE: - DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); - mutex_lock(&sensor->operation_mutex); - if(sensor->ops->ctrl_data != mode) - { - ret = compass_akm_set_mode(client, mode); - if (ret < 0) { - printk("%s:fait to set mode\n",__func__); - mutex_unlock(&sensor->operation_mutex); - return ret; - } - - sensor->ops->ctrl_data = mode; - } - mutex_unlock(&sensor->operation_mutex); - break; - case ECS_IOCTL_GETDATA: - DBG("%s:ECS_IOCTL_GETDATA start\n",__func__); - mutex_lock(&sensor->data_mutex); - memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer - mutex_unlock(&sensor->data_mutex); - break; - case ECS_IOCTL_SET_YPR: - DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__); - mutex_lock(&sensor->data_mutex); - compass_set_YPR(value); - mutex_unlock(&sensor->data_mutex); - break; - case ECS_IOCTL_GET_OPEN_STATUS: - status = compass_akm_get_openstatus(); - DBG("%s:openstatus=%d\n",__func__,status); - break; + if (*stat2 & 0x08) + { + DBG(KERN_ERR "%s:compass data overflow\n",__func__); + return -3; + } + + /* »¥³âµØ»º´æÊý¾Ý. */ + mutex_lock(&sensor->data_mutex); + memcpy(sensor->sensor_data, buffer, sensor->ops->read_len); + mutex_unlock(&sensor->data_mutex); + DBG("%s:",__func__); + for(i=0; iops->read_len; i++) + DBG("0x%x,",buffer[i]); + DBG("\n"); + + 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); + } + + + //trigger next measurement + ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); + if(ret) + { + printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data); + return ret; + } + + return ret; +} + +static void compass_set_YPR(short *rbuf) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(this_client); + + /* Report magnetic sensor information */ + if (atomic_read(&sensor->flags.m_flag)) { + input_report_abs(sensor->input_dev, ABS_RX, rbuf[0]); + input_report_abs(sensor->input_dev, ABS_RY, rbuf[1]); + input_report_abs(sensor->input_dev, ABS_RZ, rbuf[2]); + input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]); + DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[0], rbuf[1], rbuf[2], rbuf[4]); + } + + /* Report acceleration sensor information */ + if (atomic_read(&sensor->flags.a_flag)) { + input_report_abs(sensor->input_dev, ABS_X, rbuf[6]); + input_report_abs(sensor->input_dev, ABS_Y, rbuf[7]); + input_report_abs(sensor->input_dev, ABS_Z, rbuf[8]); + input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[5]); + + DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[6], rbuf[7], rbuf[8], rbuf[5]); + } + + /* Report magnetic vector information */ + if (atomic_read(&sensor->flags.mv_flag)) { + input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[9]); + input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[10]); + input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[11]); + + DBG("%s:mv_flag:x=%d,y=%d,BRAKE=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11]); + } + + input_sync(sensor->input_dev); +} + + +static int compass_dev_open(struct inode *inode, struct file *file) +{ + int result = 0; + DBG("%s\n",__func__); + + return result; +} + + +static int compass_dev_release(struct inode *inode, struct file *file) +{ + int result = 0; + DBG("%s\n",__func__); + + return result; +} + +static int compass_akm_set_mode(struct i2c_client *client, char mode) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + int result = 0; + + switch(mode) + { + case AK8975_MODE_SNG_MEASURE: + case AK8975_MODE_SELF_TEST: + case AK8975_MODE_FUSE_ACCESS: + if(sensor->status_cur == SENSOR_OFF) + { + if(sensor->pdata->irq_enable) + { + //DBG("%s:enable irq=%d\n",__func__,client->irq); + //enable_irq(client->irq); + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + + sensor->status_cur = SENSOR_ON; + } + + break; + + case AK8975_MODE_POWERDOWN: + if(sensor->status_cur == SENSOR_ON) + { + if(sensor->pdata->irq_enable) + { + //DBG("%s:disable irq=%d\n",__func__,client->irq); + //disable_irq_nosync(client->irq);//disable irq + } + else + cancel_delayed_work_sync(&sensor->delaywork); + + sensor->status_cur = SENSOR_OFF; + } + break; + + } + + switch(mode) + { + case AK8975_MODE_SNG_MEASURE: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SNG_MEASURE); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK8975_MODE_SELF_TEST: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SELF_TEST); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK8975_MODE_FUSE_ACCESS: + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_FUSE_ACCESS); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + break; + case AK8975_MODE_POWERDOWN: + /* Set powerdown mode */ + result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_POWERDOWN); + if(result) + printk("%s:i2c error,mode=%d\n",__func__,mode); + udelay(100); + break; + default: + printk("%s: Unknown mode(%d)", __func__, mode); + result = -EINVAL; + break; + } + DBG("%s:mode=%d\n",__func__,mode); + return result; + +} + + +static int compass_akm_get_openstatus(void) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0)); + return atomic_read(&sensor->flags.open_flag); +} + +static int compass_akm_get_closestatus(void) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0)); + return atomic_read(&sensor->flags.open_flag); +} + + +/* ioctl - I/O control */ +static long compass_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); + struct i2c_client *client = this_client; + void __user *argp = (void __user *)arg; + int result = 0; + struct akm_platform_data compass; + + /* NOTE: In this function the size of "char" should be 1-byte. */ + char compass_data[SENSOR_DATA_SIZE];/* for GETDATA */ + char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */ + char mode; /* for SET_MODE*/ + short value[12]; /* for SET_YPR */ + short delay; /* for GET_DELAY */ + int status; /* for OPEN/CLOSE_STATUS */ + int ret = -1; /* Return value. */ + + switch (cmd) { + case ECS_IOCTL_WRITE: + case ECS_IOCTL_READ: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) { + return -EFAULT; + } + break; + case ECS_IOCTL_SET_MODE: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&mode, argp, sizeof(mode))) { + return -EFAULT; + } + break; + case ECS_IOCTL_SET_YPR: + if (argp == NULL) { + return -EINVAL; + } + if (copy_from_user(&value, argp, sizeof(value))) { + return -EFAULT; + } + break; + default: + break; + } + + switch (cmd) { + case ECS_IOCTL_WRITE: + DBG("%s:ECS_IOCTL_WRITE start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { + mutex_unlock(&sensor->operation_mutex); + return -EINVAL; + } + ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]); + if (ret < 0) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fait to tx data\n",__func__); + return ret; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_READ: + DBG("%s:ECS_IOCTL_READ start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:data is error\n",__func__); + return -EINVAL; + } + ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]); + if (ret < 0) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fait to rx data\n",__func__); + return ret; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_SET_MODE: + DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); + mutex_lock(&sensor->operation_mutex); + if(sensor->ops->ctrl_data != mode) + { + ret = compass_akm_set_mode(client, mode); + if (ret < 0) { + printk("%s:fait to set mode\n",__func__); + mutex_unlock(&sensor->operation_mutex); + return ret; + } + + sensor->ops->ctrl_data = mode; + } + mutex_unlock(&sensor->operation_mutex); + break; + case ECS_IOCTL_GETDATA: + DBG("%s:ECS_IOCTL_GETDATA start\n",__func__); + mutex_lock(&sensor->data_mutex); + memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer + mutex_unlock(&sensor->data_mutex); + break; + case ECS_IOCTL_SET_YPR: + DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__); + mutex_lock(&sensor->data_mutex); + compass_set_YPR(value); + mutex_unlock(&sensor->data_mutex); + break; + case ECS_IOCTL_GET_OPEN_STATUS: + status = compass_akm_get_openstatus(); + DBG("%s:openstatus=%d\n",__func__,status); + break; case ECS_IOCTL_GET_CLOSE_STATUS: - status = compass_akm_get_closestatus(); - DBG("%s:closestatus=%d\n",__func__,status); - break; - case ECS_IOCTL_GET_DELAY: - delay = sensor->flags.delay; - break; - case ECS_IOCTL_GET_PLATFORM_DATA: - DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__); - //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout)); - //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name)); - ret = copy_to_user(argp, &compass, sizeof(compass)); - if(ret < 0) - { - printk("%s:error,ret=%d\n",__FUNCTION__, ret); - return ret; - } - break; - - default: - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_READ: - if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) { - return -EFAULT; - } - break; - case ECS_IOCTL_GETDATA: - if (copy_to_user(argp, &compass_data, sizeof(compass_data))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_OPEN_STATUS: - case ECS_IOCTL_GET_CLOSE_STATUS: - if (copy_to_user(argp, &status, sizeof(status))) { - return -EFAULT; - } - break; - case ECS_IOCTL_GET_DELAY: - if (copy_to_user(argp, &delay, sizeof(delay))) { - return -EFAULT; - } - break; - default: - break; - } - - return result; -} - -static struct file_operations compass_dev_fops = -{ - .owner = THIS_MODULE, - .open = compass_dev_open, - .release = compass_dev_release, - .unlocked_ioctl = compass_dev_ioctl, -}; - - -static struct miscdevice compass_dev_device = -{ - .minor = MISC_DYNAMIC_MINOR, - .name = "akm8975_dev", - .fops = &compass_dev_fops, -}; - -struct sensor_operate compass_akm8975_ops = { - .name = "akm8975", - .type = SENSOR_TYPE_COMPASS, //it is important - .id_i2c = COMPASS_ID_AK8975, - .read_reg = AK8975_REG_ST1, //read data - .read_len = SENSOR_DATA_SIZE, //data length - .id_reg = AK8975_REG_WIA, //read id - .id_data = AK8975_DEVICE_ID, - .precision = 8, //12 bits - .ctrl_reg = AK8975_REG_CNTL, //enable or disable - .int_status_reg = SENSOR_UNKNOW_DATA, //not exist - .range = {-0xffff,0xffff}, - .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT - .active = sensor_active, - .init = sensor_init, - .report = sensor_report_value, - .misc_dev = NULL, //private misc support -}; - -/****************operate according to sensor chip:end************/ - -//function name should not be changed -static struct sensor_operate *compass_get_ops(void) -{ - return &compass_akm8975_ops; -} - - -static int __init compass_akm8975_init(void) -{ - struct sensor_operate *ops = compass_get_ops(); - int result = 0; - int type = ops->type; - result = sensor_register_slave(type, NULL, NULL, compass_get_ops); - - return result; -} - -static void __exit compass_akm8975_exit(void) -{ - struct sensor_operate *ops = compass_get_ops(); - int type = ops->type; - sensor_unregister_slave(type, NULL, NULL, compass_get_ops); -} - - -module_init(compass_akm8975_init); -module_exit(compass_akm8975_exit); - - + status = compass_akm_get_closestatus(); + DBG("%s:closestatus=%d\n",__func__,status); + break; + case ECS_IOCTL_GET_DELAY: + delay = sensor->flags.delay; + break; + case ECS_IOCTL_GET_PLATFORM_DATA: + DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__); + //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout)); + //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name)); + ret = copy_to_user(argp, &compass, sizeof(compass)); + if(ret < 0) + { + printk("%s:error,ret=%d\n",__FUNCTION__, ret); + return ret; + } + break; + + default: + return -ENOTTY; + } + + switch (cmd) { + case ECS_IOCTL_READ: + if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) { + return -EFAULT; + } + break; + case ECS_IOCTL_GETDATA: + if (copy_to_user(argp, &compass_data, sizeof(compass_data))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_OPEN_STATUS: + case ECS_IOCTL_GET_CLOSE_STATUS: + if (copy_to_user(argp, &status, sizeof(status))) { + return -EFAULT; + } + break; + case ECS_IOCTL_GET_DELAY: + if (copy_to_user(argp, &delay, sizeof(delay))) { + return -EFAULT; + } + break; + default: + break; + } + + return result; +} + +static struct file_operations compass_dev_fops = +{ + .owner = THIS_MODULE, + .open = compass_dev_open, + .release = compass_dev_release, + .unlocked_ioctl = compass_dev_ioctl, +}; + + +static struct miscdevice compass_dev_device = +{ + .minor = MISC_DYNAMIC_MINOR, + .name = "akm8975_dev", + .fops = &compass_dev_fops, +}; + +struct sensor_operate compass_akm8975_ops = { + .name = "akm8975", + .type = SENSOR_TYPE_COMPASS, //it is important + .id_i2c = COMPASS_ID_AK8975, + .read_reg = AK8975_REG_ST1, //read data + .read_len = SENSOR_DATA_SIZE, //data length + .id_reg = AK8975_REG_WIA, //read id + .id_data = AK8975_DEVICE_ID, + .precision = 8, //12 bits + .ctrl_reg = AK8975_REG_CNTL, //enable or disable + .int_status_reg = SENSOR_UNKNOW_DATA, //not exist + .range = {-0xffff,0xffff}, + .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT + .active = sensor_active, + .init = sensor_init, + .report = sensor_report_value, + .misc_dev = NULL, //private misc support +}; + +/****************operate according to sensor chip:end************/ + +//function name should not be changed +static struct sensor_operate *compass_get_ops(void) +{ + return &compass_akm8975_ops; +} + + +static int __init compass_akm8975_init(void) +{ + struct sensor_operate *ops = compass_get_ops(); + int result = 0; + int type = ops->type; + result = sensor_register_slave(type, NULL, NULL, compass_get_ops); + + return result; +} + +static void __exit compass_akm8975_exit(void) +{ + struct sensor_operate *ops = compass_get_ops(); + int type = ops->type; + sensor_unregister_slave(type, NULL, NULL, compass_get_ops); +} + + +module_init(compass_akm8975_init); +module_exit(compass_akm8975_exit); + + diff --git a/drivers/input/sensors/gyro/ewtsa.c b/drivers/input/sensors/gyro/ewtsa.c index 78684d6ea678..2670515575e9 100755 --- a/drivers/input/sensors/gyro/ewtsa.c +++ b/drivers/input/sensors/gyro/ewtsa.c @@ -1,460 +1,460 @@ -/* drivers/input/sensors/gyro/Ewtsa.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: zhangaihui - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - -/** 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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + +/** 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*)®Addr, 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) +{ + 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_disable(struct i2c_client *client) + +static int ewtsa_enable(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; + 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; } - -static int ewtsa_enable(struct i2c_client *client) + +void gyro_dev_reset(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; + 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); } - -void gyro_dev_reset(struct i2c_client *client) + +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; + 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; + 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; + 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++) + + 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); + 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); - - /* »¥³âµØ»º´æÊý¾Ý. */ - 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); + + /* »¥³âµØ»º´æÊý¾Ý. */ + 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); + + diff --git a/drivers/input/sensors/gyro/l3g20d.c b/drivers/input/sensors/gyro/l3g20d.c index 1b7bf91025fa..839cf3922f24 100755 --- a/drivers/input/sensors/gyro/l3g20d.c +++ b/drivers/input/sensors/gyro/l3g20d.c @@ -1,256 +1,256 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include -#include - - -#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; - - 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++) +/* drivers/input/sensors/access/kxtik.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include + + +#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); - - /* »¥³âµØ»º´æÊý¾Ý. */ - 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); + + /* »¥³âµØ»º´æÊý¾Ý. */ + 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); + + diff --git a/drivers/input/sensors/gyro/l3g4200d.c b/drivers/input/sensors/gyro/l3g4200d.c index 1071b971faf8..00cd5af5e8e7 100755 --- a/drivers/input/sensors/gyro/l3g4200d.c +++ b/drivers/input/sensors/gyro/l3g4200d.c @@ -1,256 +1,256 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include -#include - - -#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; - - 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++) +/* drivers/input/sensors/access/kxtik.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include + + +#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); - - /* »¥³âµØ»º´æÊý¾Ý. */ - 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); + + /* »¥³âµØ»º´æÊý¾Ý. */ + 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); + + diff --git a/drivers/input/sensors/lsensor/cm3217.c b/drivers/input/sensors/lsensor/cm3217.c index 5edf40f30a2a..b23cb77cfb7a 100755 --- a/drivers/input/sensors/lsensor/cm3217.c +++ b/drivers/input/sensors/lsensor/cm3217.c @@ -1,233 +1,233 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + diff --git a/drivers/input/sensors/lsensor/cm3232.c b/drivers/input/sensors/lsensor/cm3232.c index 013b67015aa4..2afd1d79e82d 100755 --- a/drivers/input/sensors/lsensor/cm3232.c +++ b/drivers/input/sensors/lsensor/cm3232.c @@ -1,240 +1,240 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + diff --git a/drivers/input/sensors/lsensor/isl29023.c b/drivers/input/sensors/lsensor/isl29023.c index 269740c3f744..cd649e4a4ff2 100755 --- a/drivers/input/sensors/lsensor/isl29023.c +++ b/drivers/input/sensors/lsensor/isl29023.c @@ -1,268 +1,268 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + diff --git a/drivers/input/sensors/lsensor/ls_al3006.c b/drivers/input/sensors/lsensor/ls_al3006.c index 6fbf1a3e01f0..05b4c233d6b0 100755 --- a/drivers/input/sensors/lsensor/ls_al3006.c +++ b/drivers/input/sensors/lsensor/ls_al3006.c @@ -1,295 +1,295 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + diff --git a/drivers/input/sensors/lsensor/ls_ap321xx.c b/drivers/input/sensors/lsensor/ls_ap321xx.c index e902fc8cd884..225d7a4d9829 100644 --- a/drivers/input/sensors/lsensor/ls_ap321xx.c +++ b/drivers/input/sensors/lsensor/ls_ap321xx.c @@ -1,58 +1,58 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - +/* drivers/input/sensors/access/kxtik.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + #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) + + 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; - } - + 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); + 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) + if (int_stat & AP3212B_INT_AMASK) { - ap321xx_change_ls_threshold(client); + 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); - - + + 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); + + diff --git a/drivers/input/sensors/lsensor/ls_stk3171.c b/drivers/input/sensors/lsensor/ls_stk3171.c index 4c8b582b10f1..e50e9c632842 100755 --- a/drivers/input/sensors/lsensor/ls_stk3171.c +++ b/drivers/input/sensors/lsensor/ls_stk3171.c @@ -1,314 +1,314 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + diff --git a/drivers/input/sensors/lsensor/ls_us5152.c b/drivers/input/sensors/lsensor/ls_us5152.c index f651a0b669af..d79234051590 100644 --- a/drivers/input/sensors/lsensor/ls_us5152.c +++ b/drivers/input/sensors/lsensor/ls_us5152.c @@ -1,438 +1,438 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include -#include - - -#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include + + +#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); + diff --git a/drivers/input/sensors/pressure/pr_ms5607.c b/drivers/input/sensors/pressure/pr_ms5607.c index 66f4fe07d5e5..7690c14cccc5 100755 --- a/drivers/input/sensors/pressure/pr_ms5607.c +++ b/drivers/input/sensors/pressure/pr_ms5607.c @@ -1,292 +1,292 @@ -/* drivers/input/sensors/pressure/ms5607.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + diff --git a/drivers/input/sensors/psensor/ps_al3006.c b/drivers/input/sensors/psensor/ps_al3006.c index cf679809f98b..000af717ac8d 100755 --- a/drivers/input/sensors/psensor/ps_al3006.c +++ b/drivers/input/sensors/psensor/ps_al3006.c @@ -1,256 +1,256 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + diff --git a/drivers/input/sensors/psensor/ps_ap321xx.c b/drivers/input/sensors/psensor/ps_ap321xx.c index db42d734a7d2..8a656c01814f 100644 --- a/drivers/input/sensors/psensor/ps_ap321xx.c +++ b/drivers/input/sensors/psensor/ps_ap321xx.c @@ -1,60 +1,60 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - +/* drivers/input/sensors/access/kxtik.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + #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) +} + +/****************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; - } - + 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); + 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) + 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); + 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); - - + + 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); + + diff --git a/drivers/input/sensors/psensor/ps_stk3171.c b/drivers/input/sensors/psensor/ps_stk3171.c index 6374585bb3ad..53471a4c5579 100755 --- a/drivers/input/sensors/psensor/ps_stk3171.c +++ b/drivers/input/sensors/psensor/ps_stk3171.c @@ -1,262 +1,262 @@ -/* drivers/input/sensors/access/kxtik.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + + diff --git a/drivers/input/sensors/sensor-dev.c b/drivers/input/sensors/sensor-dev.c index 052763173097..8e9aa6af3c04 100755 --- a/drivers/input/sensors/sensor-dev.c +++ b/drivers/input/sensors/sensor-dev.c @@ -1,399 +1,399 @@ -/* drivers/input/sensors/sensor-dev.c - handle all gsensor in this file - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include -#include -#include +/* drivers/input/sensors/sensor-dev.c - handle all gsensor in this file + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include +#include #ifdef CONFIG_COMPAT #include #endif - - -/* -sensor-dev.c v1.1 add pressure and temperature support 2013-2-27 -sensor-dev.c v1.2 add akm8963 support 2013-3-10 -sensor-dev.c v1.3 add sensor debug support 2013-3-15 -sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01 -*/ - -#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01" - - -struct sensor_private_data *g_sensor[SENSOR_NUM_TYPES]; -static struct sensor_operate *sensor_ops[SENSOR_NUM_ID]; -static struct class *g_sensor_class[SENSOR_NUM_TYPES]; - -static ssize_t sensor_proc_write(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - char c; - int rc; - int i = 0, num = 0; - - rc = get_user(c, buffer); - if (rc) - { - for(i=SENSOR_TYPE_NULL+1; iflags.debug_flag, SENSOR_TYPE_NULL); - return rc; - } - - - num = c - '0'; - - printk("%s command list:close:%d,angle:%d accel:%d, compass:%d, gyro:%d, light:%d, psensor:%d, temp:%d, pressure:%d,total:%d,num=%d\n",__func__, - - SENSOR_TYPE_NULL, SENSOR_TYPE_ANGLE, SENSOR_TYPE_ACCEL,SENSOR_TYPE_COMPASS,SENSOR_TYPE_GYROSCOPE,SENSOR_TYPE_LIGHT,SENSOR_TYPE_PROXIMITY, - - SENSOR_TYPE_TEMPERATURE,SENSOR_TYPE_PRESSURE,SENSOR_NUM_TYPES,num); - - if((num > SENSOR_NUM_TYPES) || (num < SENSOR_TYPE_NULL)) - { - printk("%s:error! only support %d to %d\n",__func__, SENSOR_TYPE_NULL,SENSOR_NUM_TYPES); - return -1; - } - - for(i=SENSOR_TYPE_NULL+1; iflags.debug_flag, num); - } - - return count; -} - -static const struct file_operations sensor_proc_fops = { - .owner = THIS_MODULE, - .write = sensor_proc_write, -}; - - - -static int sensor_get_id(struct i2c_client *client, int *value) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - int result = 0; - char temp = sensor->ops->id_reg; - int i = 0; - - if(sensor->ops->id_reg >= 0) - { - for(i=0; i<3; i++) - { - result = sensor_rx_data(client, &temp, 1); - *value = temp; - if(!result) - break; - } - - if(result) - return result; - - if(*value != sensor->ops->id_data) - { - printk("%s:id=0x%x is not 0x%x\n",__func__,*value, sensor->ops->id_data); - result = -1; - } - - DBG("%s:devid=0x%x\n",__func__,*value); - } - - return result; -} - -static int sensor_initial(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - int result = 0; - - //register setting according to chip datasheet - result = sensor->ops->init(client); - if(result < 0) - { - printk("%s:fail to init sensor\n",__func__); - return result; - } - - - DBG("%s:ctrl_data=0x%x\n",__func__,sensor->ops->ctrl_data); - - return result; - -} - -static int sensor_chip_init(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - struct sensor_operate *ops = sensor_ops[(int)sensor->i2c_id->driver_data]; - int result = 0; - - if(ops) - { - sensor->ops = ops; - } - else - { - printk("%s:ops is null,sensor name is %s\n",__func__,sensor->i2c_id->name); - result = -1; - goto error; - } - - if((sensor->type != ops->type) || ((int)sensor->i2c_id->driver_data != ops->id_i2c)) - { - printk("%s:type or id is different:type=%d,%d,id=%d,%d\n",__func__,sensor->type, ops->type, (int)sensor->i2c_id->driver_data, ops->id_i2c); - result = -1; - goto error; - } - - if(!ops->init || !ops->active || !ops->report) - { - printk("%s:error:some function is needed\n",__func__); - result = -1; - goto error; - } - - result = sensor_get_id(sensor->client, &sensor->devid);//get id - if(result < 0) - { - printk("%s:fail to read %s devid:0x%x\n",__func__, sensor->i2c_id->name, sensor->devid); - goto error; - } - - printk("%s:%s:devid=0x%x,ops=0x%p\n",__func__, sensor->i2c_id->name, sensor->devid,sensor->ops); - - result = sensor_initial(sensor->client); //init sensor - if(result < 0) - { - printk("%s:fail to init sensor\n",__func__); - goto error; - } - - return 0; - -error: - - return result; -} - -static int sensor_reset_rate(struct i2c_client *client, int rate) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - int result = 0; - - result = sensor->ops->active(client,SENSOR_OFF,rate); - sensor->ops->init(client); - result = sensor->ops->active(client,SENSOR_ON,rate); - - return result; -} - -static int sensor_get_data(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - int result = 0; - - result = sensor->ops->report(client); - if(result) - goto error; - - /* set data_ready */ - atomic_set(&sensor->data_ready, 1); - /*wake up data_ready work queue*/ - wake_up(&sensor->data_ready_wq); - -error: - return result; -} - -#if 0 -int sensor_get_cached_data(struct i2c_client* client, char *buffer, int length, struct sensor_axis *axis) -{ - struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(client); - wait_event_interruptible_timeout(sensor->data_ready_wq, - atomic_read(&(sensor->data_ready) ), - msecs_to_jiffies(1000) ); - if ( 0 == atomic_read(&(sensor->data_ready) ) ) { - printk("waiting 'data_ready_wq' timed out."); - goto error; - } - - - mutex_lock(&sensor->data_mutex); - - switch(sensor->type) - { - case SENSOR_TYPE_ACCEL: - *axis = sensor->axis; - break; - - case SENSOR_TYPE_COMPASS: - memcpy(buffer, sensor->sensor_data, length); - break; - } - - mutex_unlock(&sensor->data_mutex); - - return 0; - -error: - return -1; -} -#endif - -static void sensor_delaywork_func(struct work_struct *work) -{ - struct delayed_work *delaywork = container_of(work, struct delayed_work, work); - struct sensor_private_data *sensor = container_of(delaywork, struct sensor_private_data, delaywork); - struct i2c_client *client = sensor->client; - - mutex_lock(&sensor->sensor_mutex); - if (sensor_get_data(client) < 0) - DBG(KERN_ERR "%s: Get data failed\n",__func__); - - if(!sensor->pdata->irq_enable)//restart work while polling - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - //else - //{ - //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH)) - //enable_irq(sensor->client->irq); - //} - mutex_unlock(&sensor->sensor_mutex); - - DBG("%s:%s\n",__func__,sensor->i2c_id->name); -} - -/* - * This is a threaded IRQ handler so can access I2C/SPI. Since all - * interrupts are clear on read the IRQ line will be reasserted and - * the physical IRQ will be handled again if another interrupt is - * asserted while we run - in the normal course of events this is a - * rare occurrence so we save I2C/SPI reads. We're also assuming that - * it's rare to get lots of interrupts firing simultaneously so try to - * minimise I/O. - */ -static irqreturn_t sensor_interrupt(int irq, void *dev_id) -{ - struct sensor_private_data *sensor = (struct sensor_private_data *)dev_id; - - //use threaded IRQ - if (sensor_get_data(sensor->client) < 0) - DBG(KERN_ERR "%s: Get data failed\n",__func__); - msleep(sensor->pdata->poll_delay_ms); - - - //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH)) - //disable_irq_nosync(irq); - //schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - DBG("%s:irq=%d\n",__func__,irq); - return IRQ_HANDLED; -} - - -static int sensor_irq_init(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - int result = 0; - int irq; - if((sensor->pdata->irq_enable)&&(sensor->pdata->irq_flags!= SENSOR_UNKNOW_DATA)) - { - //INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func); - if(sensor->pdata->poll_delay_ms < 0) - sensor->pdata->poll_delay_ms = 30; - result = gpio_request(client->irq, sensor->i2c_id->name); - if (result) - { - printk("%s:fail to request gpio :%d\n",__func__,client->irq); - } - - //gpio_pull_updown(client->irq, PullEnable); - irq = gpio_to_irq(client->irq); - //result = request_irq(irq, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor); - //result = request_threaded_irq(irq, NULL, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor); - result = devm_request_threaded_irq(&client->dev, irq, NULL, sensor_interrupt, sensor->pdata->irq_flags | IRQF_ONESHOT, sensor->ops->name, sensor); - if (result) { - printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, irq, result); - goto error; - } - client->irq = irq; - if((sensor->pdata->type == SENSOR_TYPE_GYROSCOPE) || (sensor->pdata->type == SENSOR_TYPE_ACCEL) || (sensor->pdata->type == SENSOR_TYPE_ANGLE)) - disable_irq_nosync(client->irq);//disable irq - if(((sensor->pdata->type == SENSOR_TYPE_LIGHT) || (sensor->pdata->type == SENSOR_TYPE_PROXIMITY))&& (!(sensor->ops->trig & IRQF_SHARED))) - disable_irq_nosync(client->irq);//disable irq - if(((sensor->pdata->type == SENSOR_TYPE_TEMPERATURE) || (sensor->pdata->type == SENSOR_TYPE_PRESSURE))&& (!(sensor->ops->trig & IRQF_SHARED))) - disable_irq_nosync(client->irq);//disable irq - DBG("%s:use irq=%d\n",__func__,irq); - } - else if(!sensor->pdata->irq_enable) - { - INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func); - if(sensor->pdata->poll_delay_ms < 0) - sensor->pdata->poll_delay_ms = 30; - - DBG("%s:use polling,delay=%d ms\n",__func__,sensor->pdata->poll_delay_ms); - } - -error: - return result; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void sensor_suspend(struct early_suspend *h) -{ - struct sensor_private_data *sensor = - container_of(h, struct sensor_private_data, early_suspend); - - if(sensor->ops->suspend) - sensor->ops->suspend(sensor->client); - -} - -static void sensor_resume(struct early_suspend *h) -{ - struct sensor_private_data *sensor = - container_of(h, struct sensor_private_data, early_suspend); - - if(sensor->ops->resume) - sensor->ops->resume(sensor->client); -} -#endif + + +/* +sensor-dev.c v1.1 add pressure and temperature support 2013-2-27 +sensor-dev.c v1.2 add akm8963 support 2013-3-10 +sensor-dev.c v1.3 add sensor debug support 2013-3-15 +sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01 +*/ + +#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01" + + +struct sensor_private_data *g_sensor[SENSOR_NUM_TYPES]; +static struct sensor_operate *sensor_ops[SENSOR_NUM_ID]; +static struct class *g_sensor_class[SENSOR_NUM_TYPES]; + +static ssize_t sensor_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ + char c; + int rc; + int i = 0, num = 0; + + rc = get_user(c, buffer); + if (rc) + { + for(i=SENSOR_TYPE_NULL+1; iflags.debug_flag, SENSOR_TYPE_NULL); + return rc; + } + + + num = c - '0'; + + printk("%s command list:close:%d,angle:%d accel:%d, compass:%d, gyro:%d, light:%d, psensor:%d, temp:%d, pressure:%d,total:%d,num=%d\n",__func__, + + SENSOR_TYPE_NULL, SENSOR_TYPE_ANGLE, SENSOR_TYPE_ACCEL,SENSOR_TYPE_COMPASS,SENSOR_TYPE_GYROSCOPE,SENSOR_TYPE_LIGHT,SENSOR_TYPE_PROXIMITY, + + SENSOR_TYPE_TEMPERATURE,SENSOR_TYPE_PRESSURE,SENSOR_NUM_TYPES,num); + + if((num > SENSOR_NUM_TYPES) || (num < SENSOR_TYPE_NULL)) + { + printk("%s:error! only support %d to %d\n",__func__, SENSOR_TYPE_NULL,SENSOR_NUM_TYPES); + return -1; + } + + for(i=SENSOR_TYPE_NULL+1; iflags.debug_flag, num); + } + + return count; +} + +static const struct file_operations sensor_proc_fops = { + .owner = THIS_MODULE, + .write = sensor_proc_write, +}; + + + +static int sensor_get_id(struct i2c_client *client, int *value) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + char temp = sensor->ops->id_reg; + int i = 0; + + if(sensor->ops->id_reg >= 0) + { + for(i=0; i<3; i++) + { + result = sensor_rx_data(client, &temp, 1); + *value = temp; + if(!result) + break; + } + + if(result) + return result; + + if(*value != sensor->ops->id_data) + { + printk("%s:id=0x%x is not 0x%x\n",__func__,*value, sensor->ops->id_data); + result = -1; + } + + DBG("%s:devid=0x%x\n",__func__,*value); + } + + return result; +} + +static int sensor_initial(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + + //register setting according to chip datasheet + result = sensor->ops->init(client); + if(result < 0) + { + printk("%s:fail to init sensor\n",__func__); + return result; + } + + + DBG("%s:ctrl_data=0x%x\n",__func__,sensor->ops->ctrl_data); + + return result; + +} + +static int sensor_chip_init(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + struct sensor_operate *ops = sensor_ops[(int)sensor->i2c_id->driver_data]; + int result = 0; + + if(ops) + { + sensor->ops = ops; + } + else + { + printk("%s:ops is null,sensor name is %s\n",__func__,sensor->i2c_id->name); + result = -1; + goto error; + } + + if((sensor->type != ops->type) || ((int)sensor->i2c_id->driver_data != ops->id_i2c)) + { + printk("%s:type or id is different:type=%d,%d,id=%d,%d\n",__func__,sensor->type, ops->type, (int)sensor->i2c_id->driver_data, ops->id_i2c); + result = -1; + goto error; + } + + if(!ops->init || !ops->active || !ops->report) + { + printk("%s:error:some function is needed\n",__func__); + result = -1; + goto error; + } + + result = sensor_get_id(sensor->client, &sensor->devid);//get id + if(result < 0) + { + printk("%s:fail to read %s devid:0x%x\n",__func__, sensor->i2c_id->name, sensor->devid); + goto error; + } + + printk("%s:%s:devid=0x%x,ops=0x%p\n",__func__, sensor->i2c_id->name, sensor->devid,sensor->ops); + + result = sensor_initial(sensor->client); //init sensor + if(result < 0) + { + printk("%s:fail to init sensor\n",__func__); + goto error; + } + + return 0; + +error: + + return result; +} + +static int sensor_reset_rate(struct i2c_client *client, int rate) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + + result = sensor->ops->active(client,SENSOR_OFF,rate); + sensor->ops->init(client); + result = sensor->ops->active(client,SENSOR_ON,rate); + + return result; +} + +static int sensor_get_data(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + + result = sensor->ops->report(client); + if(result) + goto error; + + /* set data_ready */ + atomic_set(&sensor->data_ready, 1); + /*wake up data_ready work queue*/ + wake_up(&sensor->data_ready_wq); + +error: + return result; +} + +#if 0 +int sensor_get_cached_data(struct i2c_client* client, char *buffer, int length, struct sensor_axis *axis) +{ + struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(client); + wait_event_interruptible_timeout(sensor->data_ready_wq, + atomic_read(&(sensor->data_ready) ), + msecs_to_jiffies(1000) ); + if ( 0 == atomic_read(&(sensor->data_ready) ) ) { + printk("waiting 'data_ready_wq' timed out."); + goto error; + } + + + mutex_lock(&sensor->data_mutex); + + switch(sensor->type) + { + case SENSOR_TYPE_ACCEL: + *axis = sensor->axis; + break; + + case SENSOR_TYPE_COMPASS: + memcpy(buffer, sensor->sensor_data, length); + break; + } + + mutex_unlock(&sensor->data_mutex); + + return 0; + +error: + return -1; +} +#endif + +static void sensor_delaywork_func(struct work_struct *work) +{ + struct delayed_work *delaywork = container_of(work, struct delayed_work, work); + struct sensor_private_data *sensor = container_of(delaywork, struct sensor_private_data, delaywork); + struct i2c_client *client = sensor->client; + + mutex_lock(&sensor->sensor_mutex); + if (sensor_get_data(client) < 0) + DBG(KERN_ERR "%s: Get data failed\n",__func__); + + if(!sensor->pdata->irq_enable)//restart work while polling + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + //else + //{ + //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH)) + //enable_irq(sensor->client->irq); + //} + mutex_unlock(&sensor->sensor_mutex); + + DBG("%s:%s\n",__func__,sensor->i2c_id->name); +} + +/* + * This is a threaded IRQ handler so can access I2C/SPI. Since all + * interrupts are clear on read the IRQ line will be reasserted and + * the physical IRQ will be handled again if another interrupt is + * asserted while we run - in the normal course of events this is a + * rare occurrence so we save I2C/SPI reads. We're also assuming that + * it's rare to get lots of interrupts firing simultaneously so try to + * minimise I/O. + */ +static irqreturn_t sensor_interrupt(int irq, void *dev_id) +{ + struct sensor_private_data *sensor = (struct sensor_private_data *)dev_id; + + //use threaded IRQ + if (sensor_get_data(sensor->client) < 0) + DBG(KERN_ERR "%s: Get data failed\n",__func__); + msleep(sensor->pdata->poll_delay_ms); + + + //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH)) + //disable_irq_nosync(irq); + //schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + DBG("%s:irq=%d\n",__func__,irq); + return IRQ_HANDLED; +} + + +static int sensor_irq_init(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + int irq; + if((sensor->pdata->irq_enable)&&(sensor->pdata->irq_flags!= SENSOR_UNKNOW_DATA)) + { + //INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func); + if(sensor->pdata->poll_delay_ms < 0) + sensor->pdata->poll_delay_ms = 30; + result = gpio_request(client->irq, sensor->i2c_id->name); + if (result) + { + printk("%s:fail to request gpio :%d\n",__func__,client->irq); + } + + //gpio_pull_updown(client->irq, PullEnable); + irq = gpio_to_irq(client->irq); + //result = request_irq(irq, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor); + //result = request_threaded_irq(irq, NULL, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor); + result = devm_request_threaded_irq(&client->dev, irq, NULL, sensor_interrupt, sensor->pdata->irq_flags | IRQF_ONESHOT, sensor->ops->name, sensor); + if (result) { + printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, irq, result); + goto error; + } + client->irq = irq; + if((sensor->pdata->type == SENSOR_TYPE_GYROSCOPE) || (sensor->pdata->type == SENSOR_TYPE_ACCEL) || (sensor->pdata->type == SENSOR_TYPE_ANGLE)) + disable_irq_nosync(client->irq);//disable irq + if(((sensor->pdata->type == SENSOR_TYPE_LIGHT) || (sensor->pdata->type == SENSOR_TYPE_PROXIMITY))&& (!(sensor->ops->trig & IRQF_SHARED))) + disable_irq_nosync(client->irq);//disable irq + if(((sensor->pdata->type == SENSOR_TYPE_TEMPERATURE) || (sensor->pdata->type == SENSOR_TYPE_PRESSURE))&& (!(sensor->ops->trig & IRQF_SHARED))) + disable_irq_nosync(client->irq);//disable irq + DBG("%s:use irq=%d\n",__func__,irq); + } + else if(!sensor->pdata->irq_enable) + { + INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func); + if(sensor->pdata->poll_delay_ms < 0) + sensor->pdata->poll_delay_ms = 30; + + DBG("%s:use polling,delay=%d ms\n",__func__,sensor->pdata->poll_delay_ms); + } + +error: + return result; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void sensor_suspend(struct early_suspend *h) +{ + struct sensor_private_data *sensor = + container_of(h, struct sensor_private_data, early_suspend); + + if(sensor->ops->suspend) + sensor->ops->suspend(sensor->client); + +} + +static void sensor_resume(struct early_suspend *h) +{ + struct sensor_private_data *sensor = + container_of(h, struct sensor_private_data, early_suspend); + + if(sensor->ops->resume) + sensor->ops->resume(sensor->client); +} +#endif #ifdef CONFIG_PM static int sensor_of_suspend(struct device *dev) @@ -427,1943 +427,1943 @@ static const struct dev_pm_ops sensor_pm_ops = { #define SENSOR_PM_OPS NULL #endif -static int angle_dev_open(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -static int angle_dev_release(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - -/* ioctl - I/O control */ -static long angle_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE]; - struct i2c_client *client = sensor->client; - void __user *argp = (void __user *)arg; - struct sensor_axis axis = {0}; - char rate; - int result = 0; - - switch (cmd) { - case GSENSOR_IOCTL_APP_SET_RATE: - if (copy_from_user(&rate, argp, sizeof(rate))) - { - result = -EFAULT; - goto error; - } - break; - default: - break; - } - - switch (cmd) { - case GSENSOR_IOCTL_START: - DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur); - mutex_lock(&sensor->operation_mutex); - if(++sensor->start_count == 1) - { - if(sensor->status_cur == SENSOR_OFF) - { - atomic_set(&(sensor->data_ready), 0); - if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - if(sensor->pdata->irq_enable) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - sensor->status_cur = SENSOR_ON; - } - } - mutex_unlock(&sensor->operation_mutex); - DBG("%s:GSENSOR_IOCTL_START OK\n", __func__); - break; - - case GSENSOR_IOCTL_CLOSE: - DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur); - mutex_lock(&sensor->operation_mutex); - if(--sensor->start_count == 0) - { - if(sensor->status_cur == SENSOR_ON) - { - atomic_set(&(sensor->data_ready), 0); - if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - if(sensor->pdata->irq_enable) - { - DBG("%s:disable irq,irq=%d\n",__func__,client->irq); - disable_irq_nosync(client->irq);//disable irq - } - else - cancel_delayed_work_sync(&sensor->delaywork); - sensor->status_cur = SENSOR_OFF; - } - - DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__); - } - - mutex_unlock(&sensor->operation_mutex); - break; - - case GSENSOR_IOCTL_APP_SET_RATE: - DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__); - mutex_lock(&sensor->operation_mutex); - result = sensor_reset_rate(client, rate); - if (result < 0){ - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - sensor->status_cur = SENSOR_ON; - mutex_unlock(&sensor->operation_mutex); - DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__); - break; - - case GSENSOR_IOCTL_GETDATA: - mutex_lock(&sensor->data_mutex); - memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer - mutex_unlock(&sensor->data_mutex); - break; - default: - result = -ENOTTY; - goto error; - } - - switch (cmd) { - case GSENSOR_IOCTL_GETDATA: - if ( copy_to_user(argp, &axis, sizeof(axis) ) ) { - printk("failed to copy sense data to user space."); - result = -EFAULT; - goto error; - } - DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__); - break; - default: - break; - } - -error: - return result; -} - - -static int gsensor_dev_open(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -static int gsensor_dev_release(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - -/* ioctl - I/O control */ -static long gsensor_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; - struct i2c_client *client = sensor->client; - void __user *argp = (void __user *)arg; - struct sensor_axis axis = {0}; - char rate; - int result = 0; - - switch (cmd) { - case GSENSOR_IOCTL_APP_SET_RATE: - if (copy_from_user(&rate, argp, sizeof(rate))) - { - result = -EFAULT; - goto error; - } - break; - default: - break; - } - - switch (cmd) { - case GSENSOR_IOCTL_START: - DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur); - mutex_lock(&sensor->operation_mutex); - if(++sensor->start_count == 1) - { - if(sensor->status_cur == SENSOR_OFF) - { - atomic_set(&(sensor->data_ready), 0); - if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - if(sensor->pdata->irq_enable) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - sensor->status_cur = SENSOR_ON; - } - } - mutex_unlock(&sensor->operation_mutex); - DBG("%s:GSENSOR_IOCTL_START OK\n", __func__); - break; - - case GSENSOR_IOCTL_CLOSE: - DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur); - mutex_lock(&sensor->operation_mutex); - if(--sensor->start_count == 0) - { - if(sensor->status_cur == SENSOR_ON) - { - atomic_set(&(sensor->data_ready), 0); - if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - if(sensor->pdata->irq_enable) - { - DBG("%s:disable irq,irq=%d\n",__func__,client->irq); - disable_irq_nosync(client->irq);//disable irq - } - else - cancel_delayed_work_sync(&sensor->delaywork); - sensor->status_cur = SENSOR_OFF; - } - - DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__); - } - - mutex_unlock(&sensor->operation_mutex); - break; - - case GSENSOR_IOCTL_APP_SET_RATE: - DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__); - mutex_lock(&sensor->operation_mutex); - result = sensor_reset_rate(client, rate); - if (result < 0){ - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - sensor->status_cur = SENSOR_ON; - mutex_unlock(&sensor->operation_mutex); - DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__); - break; - - case GSENSOR_IOCTL_GETDATA: - mutex_lock(&sensor->data_mutex); - memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer - mutex_unlock(&sensor->data_mutex); - break; - default: - result = -ENOTTY; - goto error; - } - - switch (cmd) { - case GSENSOR_IOCTL_GETDATA: - if ( copy_to_user(argp, &axis, sizeof(axis) ) ) { - printk("failed to copy sense data to user space."); - result = -EFAULT; - goto error; - } - DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__); - break; - default: - break; - } - -error: - return result; -} - -static ssize_t gsensor_set_orientation_online(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) -{ - int i=0; - char orientation[20]; - char *tmp; - - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; - struct sensor_platform_data *pdata = sensor->pdata; - - - char *p = strstr(buf,"gsensor_class"); - int start = strcspn(p,"{"); - int end = strcspn(p,"}"); - - strncpy(orientation,p+start,end-start+1); - tmp = orientation; - - - while(strncmp(tmp,"}",1)!=0) - { - if((strncmp(tmp,",",1)==0)||(strncmp(tmp,"{",1)==0)) - { - - tmp++; - continue; - } - else if(strncmp(tmp,"-",1)==0) - { - pdata->orientation[i++]=-1; - DBG("i=%d,data=%d\n",i,pdata->orientation[i]); - tmp++; - } - else - { - pdata->orientation[i++]=tmp[0]-48; - DBG("----i=%d,data=%d\n",i,pdata->orientation[i]); - } - tmp++; - - - } - - for(i=0;i<9;i++) - DBG("i=%d gsensor_info=%d\n",i,pdata->orientation[i]); - return 0; - -} - -static CLASS_ATTR(orientation, 0660, NULL, gsensor_set_orientation_online); - -static int gsensor_class_init(void) -{ - int ret ; - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; - g_sensor_class[SENSOR_TYPE_ACCEL] = class_create(THIS_MODULE, "gsensor_class"); - ret = class_create_file(g_sensor_class[SENSOR_TYPE_ACCEL], &class_attr_orientation); - if (ret) - { - printk("%s:Fail to creat class\n",__func__); - return ret; - } - printk("%s:%s\n",__func__,sensor->i2c_id->name); - return 0; -} - - - -static int compass_dev_open(struct inode *inode, struct file *file) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS]; - //struct i2c_client *client = sensor->client; - - int result = 0; - int flag = 0; - flag = atomic_read(&sensor->flags.open_flag); - if(!flag) - { - atomic_set(&sensor->flags.open_flag, 1); - wake_up(&sensor->flags.open_wq); - } - - DBG("%s\n", __func__); - return result; -} - - - -static int compass_dev_release(struct inode *inode, struct file *file) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS]; - //struct i2c_client *client = sensor->client; - //void __user *argp = (void __user *)arg; - int result = 0; - int flag = 0; - flag = atomic_read(&sensor->flags.open_flag); - if(flag) - { - atomic_set(&sensor->flags.open_flag, 0); - wake_up(&sensor->flags.open_wq); - } - - DBG("%s\n", __func__); - return result; -} - -#ifdef CONFIG_COMPAT -/* ioctl - I/O control */ -static long compass_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int angle_dev_open(struct inode *inode, struct file *file) { - void __user *arg64 = compat_ptr(arg); + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; + //struct i2c_client *client = sensor->client; + int result = 0; - if (!file->f_op || !file->f_op->unlocked_ioctl) { - pr_err("file->f_op or file->f_op->unlocked_ioctl is null\n"); - return -ENOTTY; - } + + return result; +} + + +static int angle_dev_release(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE]; + //struct i2c_client *client = sensor->client; + + int result = 0; + + + return result; +} + +/* ioctl - I/O control */ +static long angle_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE]; + struct i2c_client *client = sensor->client; + void __user *argp = (void __user *)arg; + struct sensor_axis axis = {0}; + char rate; + int result = 0; switch (cmd) { - case COMPAT_ECS_IOCTL_APP_SET_MFLAG: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_MFLAG, (unsigned long)arg64); - break; - case COMPAT_ECS_IOCTL_APP_GET_MFLAG: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_MFLAG, (unsigned long)arg64); - break; - case COMPAT_ECS_IOCTL_APP_SET_AFLAG: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_AFLAG, (unsigned long)arg64); - break; - case COMPAT_ECS_IOCTL_APP_GET_AFLAG: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_AFLAG, (unsigned long)arg64); + case GSENSOR_IOCTL_APP_SET_RATE: + if (copy_from_user(&rate, argp, sizeof(rate))) + { + result = -EFAULT; + goto error; + } break; - case COMPAT_ECS_IOCTL_APP_SET_MVFLAG: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_MVFLAG, (unsigned long)arg64); + default: break; - case COMPAT_ECS_IOCTL_APP_GET_MVFLAG: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_MVFLAG, (unsigned long)arg64); + } + + switch (cmd) { + case GSENSOR_IOCTL_START: + DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur); + mutex_lock(&sensor->operation_mutex); + if(++sensor->start_count == 1) + { + if(sensor->status_cur == SENSOR_OFF) + { + atomic_set(&(sensor->data_ready), 0); + if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + if(sensor->pdata->irq_enable) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + sensor->status_cur = SENSOR_ON; + } + } + mutex_unlock(&sensor->operation_mutex); + DBG("%s:GSENSOR_IOCTL_START OK\n", __func__); + break; + + case GSENSOR_IOCTL_CLOSE: + DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur); + mutex_lock(&sensor->operation_mutex); + if(--sensor->start_count == 0) + { + if(sensor->status_cur == SENSOR_ON) + { + atomic_set(&(sensor->data_ready), 0); + if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + if(sensor->pdata->irq_enable) + { + DBG("%s:disable irq,irq=%d\n",__func__,client->irq); + disable_irq_nosync(client->irq);//disable irq + } + else + cancel_delayed_work_sync(&sensor->delaywork); + sensor->status_cur = SENSOR_OFF; + } + + DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__); + } + + mutex_unlock(&sensor->operation_mutex); + break; + + case GSENSOR_IOCTL_APP_SET_RATE: + DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__); + mutex_lock(&sensor->operation_mutex); + result = sensor_reset_rate(client, rate); + if (result < 0){ + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + sensor->status_cur = SENSOR_ON; + mutex_unlock(&sensor->operation_mutex); + DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__); break; - case COMPAT_ECS_IOCTL_APP_SET_DELAY: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_DELAY, (unsigned long)arg64); + + case GSENSOR_IOCTL_GETDATA: + mutex_lock(&sensor->data_mutex); + memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer + mutex_unlock(&sensor->data_mutex); break; - case COMPAT_ECS_IOCTL_APP_GET_DELAY: - if (file->f_op->unlocked_ioctl) - result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_DELAY, (unsigned long)arg64); + default: + result = -ENOTTY; + goto error; + } + + switch (cmd) { + case GSENSOR_IOCTL_GETDATA: + if ( copy_to_user(argp, &axis, sizeof(axis) ) ) { + printk("failed to copy sense data to user space."); + result = -EFAULT; + goto error; + } + DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__); break; default: break; } +error: return result; } -#endif - -/* ioctl - I/O control */ -static long compass_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS]; - //struct i2c_client *client = sensor->client; - void __user *argp = (void __user *)arg; - int result = 0; - short flag; - - switch (cmd) { - case ECS_IOCTL_APP_SET_MFLAG: - case ECS_IOCTL_APP_SET_AFLAG: - case ECS_IOCTL_APP_SET_MVFLAG: - if (copy_from_user(&flag, argp, sizeof(flag))) { - return -EFAULT; - } - if (flag < 0 || flag > 1) { - return -EINVAL; - } - break; - case ECS_IOCTL_APP_SET_DELAY: - if (copy_from_user(&flag, argp, sizeof(flag))) { - return -EFAULT; - } - break; - default: - break; - } - - switch (cmd) { - case ECS_IOCTL_APP_SET_MFLAG: - atomic_set(&sensor->flags.m_flag, flag); - DBG("%s:ECS_IOCTL_APP_SET_MFLAG,flag=%d\n", __func__,flag); - break; - case ECS_IOCTL_APP_GET_MFLAG: - flag = atomic_read(&sensor->flags.m_flag); - DBG("%s:ECS_IOCTL_APP_GET_MFLAG,flag=%d\n", __func__,flag); - break; - case ECS_IOCTL_APP_SET_AFLAG: - atomic_set(&sensor->flags.a_flag, flag); - DBG("%s:ECS_IOCTL_APP_SET_AFLAG,flag=%d\n", __func__,flag); - break; - case ECS_IOCTL_APP_GET_AFLAG: - flag = atomic_read(&sensor->flags.a_flag); - DBG("%s:ECS_IOCTL_APP_GET_AFLAG,flag=%d\n", __func__,flag); - break; - case ECS_IOCTL_APP_SET_MVFLAG: - atomic_set(&sensor->flags.mv_flag, flag); - DBG("%s:ECS_IOCTL_APP_SET_MVFLAG,flag=%d\n", __func__,flag); - break; - case ECS_IOCTL_APP_GET_MVFLAG: - flag = atomic_read(&sensor->flags.mv_flag); - DBG("%s:ECS_IOCTL_APP_GET_MVFLAG,flag=%d\n", __func__,flag); - break; - case ECS_IOCTL_APP_SET_DELAY: - sensor->flags.delay = flag; - break; - case ECS_IOCTL_APP_GET_DELAY: - flag = sensor->flags.delay; - break; - default: - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_APP_GET_MFLAG: - case ECS_IOCTL_APP_GET_AFLAG: - case ECS_IOCTL_APP_GET_MVFLAG: - case ECS_IOCTL_APP_GET_DELAY: - if (copy_to_user(argp, &flag, sizeof(flag))) { - return -EFAULT; - } - break; - default: - break; - } - - return result; -} - -static int gyro_dev_open(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -static int gyro_dev_release(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -/* ioctl - I/O control */ -static long gyro_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE]; - struct i2c_client *client = sensor->client; - void __user *argp = (void __user *)arg; - int result = 0; - char rate; - switch (cmd) { - case L3G4200D_IOCTL_GET_ENABLE: - result = !sensor->status_cur; - if (copy_to_user(argp, &result, sizeof(result))) - { - printk("%s:failed to copy status to user space.\n",__FUNCTION__); - return -EFAULT; - } - - DBG("%s :L3G4200D_IOCTL_GET_ENABLE,status=%d\n",__FUNCTION__,result); - break; - case L3G4200D_IOCTL_SET_ENABLE: - DBG("%s :L3G4200D_IOCTL_SET_ENABLE,flag=%d\n",__FUNCTION__,*(unsigned int *)argp); - mutex_lock(&sensor->operation_mutex); - if(*(unsigned int *)argp) - { - if(sensor->status_cur == SENSOR_OFF) - { - if ( (result = sensor->ops->active(client, 1, ODR100_BW12_5) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - if(sensor->pdata->irq_enable) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - sensor->status_cur = SENSOR_ON; - } - } - else - { - if(sensor->status_cur == SENSOR_ON) - { - if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - if(sensor->pdata->irq_enable) - { - DBG("%s:disable irq,irq=%d\n",__func__,client->irq); - disable_irq_nosync(client->irq);//disable irq - } - else - cancel_delayed_work_sync(&sensor->delaywork); - sensor->status_cur = SENSOR_OFF; - } - } - - result = sensor->status_cur; - if (copy_to_user(argp, &result, sizeof(result))) - { - mutex_unlock(&sensor->operation_mutex); - printk("%s:failed to copy sense data to user space.\n",__FUNCTION__); - return -EFAULT; - } - - mutex_unlock(&sensor->operation_mutex); - DBG("%s:L3G4200D_IOCTL_SET_ENABLE OK\n", __func__); - break; - case L3G4200D_IOCTL_SET_DELAY: - if (copy_from_user(&rate, argp, sizeof(rate))) - return -EFAULT; - mutex_lock(&sensor->operation_mutex); - if(sensor->status_cur == SENSOR_OFF) - { - if ( (result = sensor->ops->active(client, 1, rate) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - - if(sensor->pdata->irq_enable) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - sensor->status_cur = SENSOR_ON; - } - - mutex_unlock(&sensor->operation_mutex); - DBG("%s :L3G4200D_IOCTL_SET_DELAY,rate=%d\n",__FUNCTION__,rate); - break; - - default: - printk("%s:error,cmd=0x%x\n",__func__,cmd); - return -ENOTTY; - } - - DBG("%s:line=%d,cmd=0x%x\n",__func__,__LINE__,cmd); - -error: - return result; -} - -static int light_dev_open(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT]; - //struct i2c_client *client = sensor->client; - int result = 0; - - - return result; -} - - - - -static int light_dev_release(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT]; - //struct i2c_client *client = sensor->client; - int result = 0; - - - return result; -} - -#ifdef CONFIG_COMPAT -static long light_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + +static int gsensor_dev_open(struct inode *inode, struct file *file) { - long ret = 0; - void __user *arg64 = compat_ptr(arg); + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; + //struct i2c_client *client = sensor->client; - if (!file->f_op || !file->f_op->unlocked_ioctl) { - pr_err("[DEBUG] file->f_op or file->f_op->unlocked_ioctl is null\n"); - return -ENOTTY; - } + int result = 0; - switch (cmd) { - case COMPAT_LIGHTSENSOR_IOCTL_GET_ENABLED: - if (file->f_op->unlocked_ioctl) - ret = file->f_op->unlocked_ioctl(file, LIGHTSENSOR_IOCTL_GET_ENABLED, (unsigned long)arg64); - break; - case COMPAT_LIGHTSENSOR_IOCTL_ENABLE: - if (file->f_op->unlocked_ioctl) - ret = file->f_op->unlocked_ioctl(file, LIGHTSENSOR_IOCTL_ENABLE, (unsigned long)arg64); - break; - default: - break; - } - return ret; + return result; } -#endif - -/* ioctl - I/O control */ -static long light_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT]; - struct i2c_client *client = sensor->client; - unsigned int *argp = (unsigned int *)arg; - int result = 0; - - switch(cmd) - { - case LIGHTSENSOR_IOCTL_GET_ENABLED: - *argp = sensor->status_cur; - break; - case LIGHTSENSOR_IOCTL_ENABLE: - DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__); - mutex_lock(&sensor->operation_mutex); - if(*(unsigned int *)argp) - { - if(sensor->status_cur == SENSOR_OFF) - { - if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - - sensor->status_cur = SENSOR_ON; - } - } - else - { - if(sensor->status_cur == SENSOR_ON) - { - if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:disable irq,irq=%d\n",__func__,client->irq); - disable_irq_nosync(client->irq);//disable irq - } - } - else - cancel_delayed_work_sync(&sensor->delaywork); - - sensor->status_cur = SENSOR_OFF; - } - } - mutex_unlock(&sensor->operation_mutex); - DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__); - break; - - default: - break; - } - -error: - return result; -} - - -static int proximity_dev_open(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY]; - //struct i2c_client *client = sensor->client; - int result = 0; - - - return result; -} - - -static int proximity_dev_release(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY]; - //struct i2c_client *client = sensor->client; - int result = 0; - - - return result; -} - -#ifdef CONFIG_COMPAT -static long proximity_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + + +static int gsensor_dev_release(struct inode *inode, struct file *file) { - long ret = 0; - void __user *arg64 = compat_ptr(arg); + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; + //struct i2c_client *client = sensor->client; - if (!file->f_op || !file->f_op->unlocked_ioctl) { - pr_err("file->f_op or file->f_op->unlocked_ioctl is null\n"); - return -ENOTTY; - } + int result = 0; + + + return result; +} + +/* ioctl - I/O control */ +static long gsensor_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; + struct i2c_client *client = sensor->client; + void __user *argp = (void __user *)arg; + struct sensor_axis axis = {0}; + char rate; + int result = 0; switch (cmd) { - case COMPAT_PSENSOR_IOCTL_GET_ENABLED: - if (file->f_op->unlocked_ioctl) - ret = file->f_op->unlocked_ioctl(file, PSENSOR_IOCTL_GET_ENABLED, (unsigned long)arg64); - break; - case COMPAT_PSENSOR_IOCTL_ENABLE: - if (file->f_op->unlocked_ioctl) - ret = file->f_op->unlocked_ioctl(file, PSENSOR_IOCTL_ENABLE, (unsigned long)arg64); + case GSENSOR_IOCTL_APP_SET_RATE: + if (copy_from_user(&rate, argp, sizeof(rate))) + { + result = -EFAULT; + goto error; + } break; default: break; } - return ret; -} -#endif - -/* ioctl - I/O control */ -static long proximity_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY]; - struct i2c_client *client = sensor->client; - unsigned int *argp = (unsigned int *)arg; - int result = 0; - switch(cmd) - { - case PSENSOR_IOCTL_GET_ENABLED: - *argp = sensor->status_cur; - break; - case PSENSOR_IOCTL_ENABLE: - DBG("%s:PSENSOR_IOCTL_ENABLE start\n", __func__); - mutex_lock(&sensor->operation_mutex); - if(*(unsigned int *)argp) - { - if(sensor->status_cur == SENSOR_OFF) - { - if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - - sensor->status_cur = SENSOR_ON; - } - } - else - { - if(sensor->status_cur == SENSOR_ON) - { - if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - goto error; - } - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:disable irq,irq=%d\n",__func__,client->irq); - disable_irq_nosync(client->irq);//disable irq - } - } - else - cancel_delayed_work_sync(&sensor->delaywork); - sensor->status_cur = SENSOR_OFF; - } - } - mutex_unlock(&sensor->operation_mutex); - DBG("%s:PSENSOR_IOCTL_ENABLE OK\n", __func__); - break; - - default: - break; - } - -error: - return result; -} - -static int temperature_dev_open(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -static int temperature_dev_release(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -/* ioctl - I/O control */ -static long temperature_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE]; - struct i2c_client *client = sensor->client; - unsigned int *argp = (unsigned int *)arg; - int result = 0; - - switch(cmd) - { - case TEMPERATURE_IOCTL_GET_ENABLED: - *argp = sensor->status_cur; - break; - case TEMPERATURE_IOCTL_ENABLE: - DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__); - mutex_lock(&sensor->operation_mutex); - if(*(unsigned int *)argp) - { - if(sensor->status_cur == SENSOR_OFF) - { - if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - - sensor->status_cur = SENSOR_ON; - } - } - else - { - if(sensor->status_cur == SENSOR_ON) - { - if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:disable irq,irq=%d\n",__func__,client->irq); - disable_irq_nosync(client->irq);//disable irq - } - } - else - cancel_delayed_work_sync(&sensor->delaywork); - - sensor->status_cur = SENSOR_OFF; - } - } - mutex_unlock(&sensor->operation_mutex); - DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__); - break; - - default: - break; - } - -error: - return result; -} - - -static int pressure_dev_open(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -static int pressure_dev_release(struct inode *inode, struct file *file) -{ - //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE]; - //struct i2c_client *client = sensor->client; - - int result = 0; - - - return result; -} - - -/* ioctl - I/O control */ -static long pressure_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE]; - struct i2c_client *client = sensor->client; - unsigned int *argp = (unsigned int *)arg; - int result = 0; - - switch(cmd) - { - case PRESSURE_IOCTL_GET_ENABLED: - *argp = sensor->status_cur; - break; - case PRESSURE_IOCTL_ENABLE: - DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__); - mutex_lock(&sensor->operation_mutex); - if(*(unsigned int *)argp) - { - if(sensor->status_cur == SENSOR_OFF) - { - if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - printk("%s:fail to active sensor,ret=%d\n",__func__,result); - goto error; - } - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:enable irq,irq=%d\n",__func__,client->irq); - enable_irq(client->irq); //enable irq - } - } - else - { - schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); - } - - sensor->status_cur = SENSOR_ON; - } - } - else - { - if(sensor->status_cur == SENSOR_ON) - { - if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { - mutex_unlock(&sensor->operation_mutex); - goto error; - } - - if(sensor->pdata->irq_enable) - { - if(!(sensor->ops->trig & IRQF_SHARED)) - { - DBG("%s:disable irq,irq=%d\n",__func__,client->irq); - disable_irq_nosync(client->irq);//disable irq - } - } - else - cancel_delayed_work_sync(&sensor->delaywork); - - sensor->status_cur = SENSOR_OFF; - } - } - mutex_unlock(&sensor->operation_mutex); - DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__); - break; - - default: - break; - } - -error: - return result; -} - - - - -static int sensor_misc_device_register(struct sensor_private_data *sensor, int type) -{ - int result = 0; - - switch(type) - { - case SENSOR_TYPE_ANGLE: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = angle_dev_ioctl; - sensor->fops.open = angle_dev_open; - sensor->fops.release = angle_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "angle"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - - break; - - case SENSOR_TYPE_ACCEL: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = gsensor_dev_ioctl; - #ifdef CONFIG_COMPAT - sensor->fops.compat_ioctl = gsensor_dev_ioctl; - #endif - sensor->fops.open = gsensor_dev_open; - sensor->fops.release = gsensor_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "mma8452_daemon"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - - break; - - case SENSOR_TYPE_COMPASS: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = compass_dev_ioctl; -#ifdef CONFIG_COMPAT + switch (cmd) { + case GSENSOR_IOCTL_START: + DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur); + mutex_lock(&sensor->operation_mutex); + if(++sensor->start_count == 1) + { + if(sensor->status_cur == SENSOR_OFF) + { + atomic_set(&(sensor->data_ready), 0); + if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + if(sensor->pdata->irq_enable) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + sensor->status_cur = SENSOR_ON; + } + } + mutex_unlock(&sensor->operation_mutex); + DBG("%s:GSENSOR_IOCTL_START OK\n", __func__); + break; + + case GSENSOR_IOCTL_CLOSE: + DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur); + mutex_lock(&sensor->operation_mutex); + if(--sensor->start_count == 0) + { + if(sensor->status_cur == SENSOR_ON) + { + atomic_set(&(sensor->data_ready), 0); + if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + if(sensor->pdata->irq_enable) + { + DBG("%s:disable irq,irq=%d\n",__func__,client->irq); + disable_irq_nosync(client->irq);//disable irq + } + else + cancel_delayed_work_sync(&sensor->delaywork); + sensor->status_cur = SENSOR_OFF; + } + + DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__); + } + + mutex_unlock(&sensor->operation_mutex); + break; + + case GSENSOR_IOCTL_APP_SET_RATE: + DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__); + mutex_lock(&sensor->operation_mutex); + result = sensor_reset_rate(client, rate); + if (result < 0){ + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + sensor->status_cur = SENSOR_ON; + mutex_unlock(&sensor->operation_mutex); + DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__); + break; + + case GSENSOR_IOCTL_GETDATA: + mutex_lock(&sensor->data_mutex); + memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer + mutex_unlock(&sensor->data_mutex); + break; + default: + result = -ENOTTY; + goto error; + } + + switch (cmd) { + case GSENSOR_IOCTL_GETDATA: + if ( copy_to_user(argp, &axis, sizeof(axis) ) ) { + printk("failed to copy sense data to user space."); + result = -EFAULT; + goto error; + } + DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__); + break; + default: + break; + } + +error: + return result; +} + +static ssize_t gsensor_set_orientation_online(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + int i=0; + char orientation[20]; + char *tmp; + + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; + struct sensor_platform_data *pdata = sensor->pdata; + + + char *p = strstr(buf,"gsensor_class"); + int start = strcspn(p,"{"); + int end = strcspn(p,"}"); + + strncpy(orientation,p+start,end-start+1); + tmp = orientation; + + + while(strncmp(tmp,"}",1)!=0) + { + if((strncmp(tmp,",",1)==0)||(strncmp(tmp,"{",1)==0)) + { + + tmp++; + continue; + } + else if(strncmp(tmp,"-",1)==0) + { + pdata->orientation[i++]=-1; + DBG("i=%d,data=%d\n",i,pdata->orientation[i]); + tmp++; + } + else + { + pdata->orientation[i++]=tmp[0]-48; + DBG("----i=%d,data=%d\n",i,pdata->orientation[i]); + } + tmp++; + + + } + + for(i=0;i<9;i++) + DBG("i=%d gsensor_info=%d\n",i,pdata->orientation[i]); + return 0; + +} + +static CLASS_ATTR(orientation, 0660, NULL, gsensor_set_orientation_online); + +static int gsensor_class_init(void) +{ + int ret ; + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; + g_sensor_class[SENSOR_TYPE_ACCEL] = class_create(THIS_MODULE, "gsensor_class"); + ret = class_create_file(g_sensor_class[SENSOR_TYPE_ACCEL], &class_attr_orientation); + if (ret) + { + printk("%s:Fail to creat class\n",__func__); + return ret; + } + printk("%s:%s\n",__func__,sensor->i2c_id->name); + return 0; +} + + + +static int compass_dev_open(struct inode *inode, struct file *file) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS]; + //struct i2c_client *client = sensor->client; + + int result = 0; + int flag = 0; + flag = atomic_read(&sensor->flags.open_flag); + if(!flag) + { + atomic_set(&sensor->flags.open_flag, 1); + wake_up(&sensor->flags.open_wq); + } + + DBG("%s\n", __func__); + return result; +} + + + +static int compass_dev_release(struct inode *inode, struct file *file) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS]; + //struct i2c_client *client = sensor->client; + //void __user *argp = (void __user *)arg; + int result = 0; + int flag = 0; + flag = atomic_read(&sensor->flags.open_flag); + if(flag) + { + atomic_set(&sensor->flags.open_flag, 0); + wake_up(&sensor->flags.open_wq); + } + + DBG("%s\n", __func__); + return result; +} + +#ifdef CONFIG_COMPAT +/* ioctl - I/O control */ +static long compass_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + void __user *arg64 = compat_ptr(arg); + int result = 0; + + if (!file->f_op || !file->f_op->unlocked_ioctl) { + pr_err("file->f_op or file->f_op->unlocked_ioctl is null\n"); + return -ENOTTY; + } + + switch (cmd) { + case COMPAT_ECS_IOCTL_APP_SET_MFLAG: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_MFLAG, (unsigned long)arg64); + break; + case COMPAT_ECS_IOCTL_APP_GET_MFLAG: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_MFLAG, (unsigned long)arg64); + break; + case COMPAT_ECS_IOCTL_APP_SET_AFLAG: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_AFLAG, (unsigned long)arg64); + break; + case COMPAT_ECS_IOCTL_APP_GET_AFLAG: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_AFLAG, (unsigned long)arg64); + break; + case COMPAT_ECS_IOCTL_APP_SET_MVFLAG: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_MVFLAG, (unsigned long)arg64); + break; + case COMPAT_ECS_IOCTL_APP_GET_MVFLAG: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_MVFLAG, (unsigned long)arg64); + break; + case COMPAT_ECS_IOCTL_APP_SET_DELAY: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_DELAY, (unsigned long)arg64); + break; + case COMPAT_ECS_IOCTL_APP_GET_DELAY: + if (file->f_op->unlocked_ioctl) + result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_DELAY, (unsigned long)arg64); + break; + default: + break; + } + + return result; +} +#endif + + +/* ioctl - I/O control */ +static long compass_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS]; + //struct i2c_client *client = sensor->client; + void __user *argp = (void __user *)arg; + int result = 0; + short flag; + + switch (cmd) { + case ECS_IOCTL_APP_SET_MFLAG: + case ECS_IOCTL_APP_SET_AFLAG: + case ECS_IOCTL_APP_SET_MVFLAG: + if (copy_from_user(&flag, argp, sizeof(flag))) { + return -EFAULT; + } + if (flag < 0 || flag > 1) { + return -EINVAL; + } + break; + case ECS_IOCTL_APP_SET_DELAY: + if (copy_from_user(&flag, argp, sizeof(flag))) { + return -EFAULT; + } + break; + default: + break; + } + + switch (cmd) { + case ECS_IOCTL_APP_SET_MFLAG: + atomic_set(&sensor->flags.m_flag, flag); + DBG("%s:ECS_IOCTL_APP_SET_MFLAG,flag=%d\n", __func__,flag); + break; + case ECS_IOCTL_APP_GET_MFLAG: + flag = atomic_read(&sensor->flags.m_flag); + DBG("%s:ECS_IOCTL_APP_GET_MFLAG,flag=%d\n", __func__,flag); + break; + case ECS_IOCTL_APP_SET_AFLAG: + atomic_set(&sensor->flags.a_flag, flag); + DBG("%s:ECS_IOCTL_APP_SET_AFLAG,flag=%d\n", __func__,flag); + break; + case ECS_IOCTL_APP_GET_AFLAG: + flag = atomic_read(&sensor->flags.a_flag); + DBG("%s:ECS_IOCTL_APP_GET_AFLAG,flag=%d\n", __func__,flag); + break; + case ECS_IOCTL_APP_SET_MVFLAG: + atomic_set(&sensor->flags.mv_flag, flag); + DBG("%s:ECS_IOCTL_APP_SET_MVFLAG,flag=%d\n", __func__,flag); + break; + case ECS_IOCTL_APP_GET_MVFLAG: + flag = atomic_read(&sensor->flags.mv_flag); + DBG("%s:ECS_IOCTL_APP_GET_MVFLAG,flag=%d\n", __func__,flag); + break; + case ECS_IOCTL_APP_SET_DELAY: + sensor->flags.delay = flag; + break; + case ECS_IOCTL_APP_GET_DELAY: + flag = sensor->flags.delay; + break; + default: + return -ENOTTY; + } + + switch (cmd) { + case ECS_IOCTL_APP_GET_MFLAG: + case ECS_IOCTL_APP_GET_AFLAG: + case ECS_IOCTL_APP_GET_MVFLAG: + case ECS_IOCTL_APP_GET_DELAY: + if (copy_to_user(argp, &flag, sizeof(flag))) { + return -EFAULT; + } + break; + default: + break; + } + + return result; +} + +static int gyro_dev_open(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE]; + //struct i2c_client *client = sensor->client; + + int result = 0; + + + return result; +} + + +static int gyro_dev_release(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE]; + //struct i2c_client *client = sensor->client; + + int result = 0; + + + return result; +} + + +/* ioctl - I/O control */ +static long gyro_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE]; + struct i2c_client *client = sensor->client; + void __user *argp = (void __user *)arg; + int result = 0; + char rate; + switch (cmd) { + case L3G4200D_IOCTL_GET_ENABLE: + result = !sensor->status_cur; + if (copy_to_user(argp, &result, sizeof(result))) + { + printk("%s:failed to copy status to user space.\n",__FUNCTION__); + return -EFAULT; + } + + DBG("%s :L3G4200D_IOCTL_GET_ENABLE,status=%d\n",__FUNCTION__,result); + break; + case L3G4200D_IOCTL_SET_ENABLE: + DBG("%s :L3G4200D_IOCTL_SET_ENABLE,flag=%d\n",__FUNCTION__,*(unsigned int *)argp); + mutex_lock(&sensor->operation_mutex); + if(*(unsigned int *)argp) + { + if(sensor->status_cur == SENSOR_OFF) + { + if ( (result = sensor->ops->active(client, 1, ODR100_BW12_5) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + if(sensor->pdata->irq_enable) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + sensor->status_cur = SENSOR_ON; + } + } + else + { + if(sensor->status_cur == SENSOR_ON) + { + if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + if(sensor->pdata->irq_enable) + { + DBG("%s:disable irq,irq=%d\n",__func__,client->irq); + disable_irq_nosync(client->irq);//disable irq + } + else + cancel_delayed_work_sync(&sensor->delaywork); + sensor->status_cur = SENSOR_OFF; + } + } + + result = sensor->status_cur; + if (copy_to_user(argp, &result, sizeof(result))) + { + mutex_unlock(&sensor->operation_mutex); + printk("%s:failed to copy sense data to user space.\n",__FUNCTION__); + return -EFAULT; + } + + mutex_unlock(&sensor->operation_mutex); + DBG("%s:L3G4200D_IOCTL_SET_ENABLE OK\n", __func__); + break; + case L3G4200D_IOCTL_SET_DELAY: + if (copy_from_user(&rate, argp, sizeof(rate))) + return -EFAULT; + mutex_lock(&sensor->operation_mutex); + if(sensor->status_cur == SENSOR_OFF) + { + if ( (result = sensor->ops->active(client, 1, rate) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + + if(sensor->pdata->irq_enable) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + sensor->status_cur = SENSOR_ON; + } + + mutex_unlock(&sensor->operation_mutex); + DBG("%s :L3G4200D_IOCTL_SET_DELAY,rate=%d\n",__FUNCTION__,rate); + break; + + default: + printk("%s:error,cmd=0x%x\n",__func__,cmd); + return -ENOTTY; + } + + DBG("%s:line=%d,cmd=0x%x\n",__func__,__LINE__,cmd); + +error: + return result; +} + +static int light_dev_open(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT]; + //struct i2c_client *client = sensor->client; + int result = 0; + + + return result; +} + + + + +static int light_dev_release(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT]; + //struct i2c_client *client = sensor->client; + int result = 0; + + + return result; +} + +#ifdef CONFIG_COMPAT +static long light_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + void __user *arg64 = compat_ptr(arg); + + if (!file->f_op || !file->f_op->unlocked_ioctl) { + pr_err("[DEBUG] file->f_op or file->f_op->unlocked_ioctl is null\n"); + return -ENOTTY; + } + + switch (cmd) { + case COMPAT_LIGHTSENSOR_IOCTL_GET_ENABLED: + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, LIGHTSENSOR_IOCTL_GET_ENABLED, (unsigned long)arg64); + break; + case COMPAT_LIGHTSENSOR_IOCTL_ENABLE: + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, LIGHTSENSOR_IOCTL_ENABLE, (unsigned long)arg64); + break; + default: + break; + } + + return ret; +} +#endif + +/* ioctl - I/O control */ +static long light_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT]; + struct i2c_client *client = sensor->client; + unsigned int *argp = (unsigned int *)arg; + int result = 0; + + switch(cmd) + { + case LIGHTSENSOR_IOCTL_GET_ENABLED: + *argp = sensor->status_cur; + break; + case LIGHTSENSOR_IOCTL_ENABLE: + DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__); + mutex_lock(&sensor->operation_mutex); + if(*(unsigned int *)argp) + { + if(sensor->status_cur == SENSOR_OFF) + { + if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + + sensor->status_cur = SENSOR_ON; + } + } + else + { + if(sensor->status_cur == SENSOR_ON) + { + if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:disable irq,irq=%d\n",__func__,client->irq); + disable_irq_nosync(client->irq);//disable irq + } + } + else + cancel_delayed_work_sync(&sensor->delaywork); + + sensor->status_cur = SENSOR_OFF; + } + } + mutex_unlock(&sensor->operation_mutex); + DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__); + break; + + default: + break; + } + +error: + return result; +} + + +static int proximity_dev_open(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY]; + //struct i2c_client *client = sensor->client; + int result = 0; + + + return result; +} + + +static int proximity_dev_release(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY]; + //struct i2c_client *client = sensor->client; + int result = 0; + + + return result; +} + +#ifdef CONFIG_COMPAT +static long proximity_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + void __user *arg64 = compat_ptr(arg); + + if (!file->f_op || !file->f_op->unlocked_ioctl) { + pr_err("file->f_op or file->f_op->unlocked_ioctl is null\n"); + return -ENOTTY; + } + + switch (cmd) { + case COMPAT_PSENSOR_IOCTL_GET_ENABLED: + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, PSENSOR_IOCTL_GET_ENABLED, (unsigned long)arg64); + break; + case COMPAT_PSENSOR_IOCTL_ENABLE: + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, PSENSOR_IOCTL_ENABLE, (unsigned long)arg64); + break; + default: + break; + } + + return ret; +} +#endif + +/* ioctl - I/O control */ +static long proximity_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY]; + struct i2c_client *client = sensor->client; + unsigned int *argp = (unsigned int *)arg; + int result = 0; + switch(cmd) + { + case PSENSOR_IOCTL_GET_ENABLED: + *argp = sensor->status_cur; + break; + case PSENSOR_IOCTL_ENABLE: + DBG("%s:PSENSOR_IOCTL_ENABLE start\n", __func__); + mutex_lock(&sensor->operation_mutex); + if(*(unsigned int *)argp) + { + if(sensor->status_cur == SENSOR_OFF) + { + if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + + sensor->status_cur = SENSOR_ON; + } + } + else + { + if(sensor->status_cur == SENSOR_ON) + { + if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + goto error; + } + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:disable irq,irq=%d\n",__func__,client->irq); + disable_irq_nosync(client->irq);//disable irq + } + } + else + cancel_delayed_work_sync(&sensor->delaywork); + sensor->status_cur = SENSOR_OFF; + } + } + mutex_unlock(&sensor->operation_mutex); + DBG("%s:PSENSOR_IOCTL_ENABLE OK\n", __func__); + break; + + default: + break; + } + +error: + return result; +} + +static int temperature_dev_open(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE]; + //struct i2c_client *client = sensor->client; + + int result = 0; + + + return result; +} + + +static int temperature_dev_release(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE]; + //struct i2c_client *client = sensor->client; + + int result = 0; + + + return result; +} + + +/* ioctl - I/O control */ +static long temperature_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE]; + struct i2c_client *client = sensor->client; + unsigned int *argp = (unsigned int *)arg; + int result = 0; + + switch(cmd) + { + case TEMPERATURE_IOCTL_GET_ENABLED: + *argp = sensor->status_cur; + break; + case TEMPERATURE_IOCTL_ENABLE: + DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__); + mutex_lock(&sensor->operation_mutex); + if(*(unsigned int *)argp) + { + if(sensor->status_cur == SENSOR_OFF) + { + if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + + sensor->status_cur = SENSOR_ON; + } + } + else + { + if(sensor->status_cur == SENSOR_ON) + { + if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:disable irq,irq=%d\n",__func__,client->irq); + disable_irq_nosync(client->irq);//disable irq + } + } + else + cancel_delayed_work_sync(&sensor->delaywork); + + sensor->status_cur = SENSOR_OFF; + } + } + mutex_unlock(&sensor->operation_mutex); + DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__); + break; + + default: + break; + } + +error: + return result; +} + + +static int pressure_dev_open(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE]; + //struct i2c_client *client = sensor->client; + + int result = 0; + + + return result; +} + + +static int pressure_dev_release(struct inode *inode, struct file *file) +{ + //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE]; + //struct i2c_client *client = sensor->client; + + int result = 0; + + + return result; +} + + +/* ioctl - I/O control */ +static long pressure_dev_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE]; + struct i2c_client *client = sensor->client; + unsigned int *argp = (unsigned int *)arg; + int result = 0; + + switch(cmd) + { + case PRESSURE_IOCTL_GET_ENABLED: + *argp = sensor->status_cur; + break; + case PRESSURE_IOCTL_ENABLE: + DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__); + mutex_lock(&sensor->operation_mutex); + if(*(unsigned int *)argp) + { + if(sensor->status_cur == SENSOR_OFF) + { + if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + printk("%s:fail to active sensor,ret=%d\n",__func__,result); + goto error; + } + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:enable irq,irq=%d\n",__func__,client->irq); + enable_irq(client->irq); //enable irq + } + } + else + { + schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms)); + } + + sensor->status_cur = SENSOR_ON; + } + } + else + { + if(sensor->status_cur == SENSOR_ON) + { + if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) { + mutex_unlock(&sensor->operation_mutex); + goto error; + } + + if(sensor->pdata->irq_enable) + { + if(!(sensor->ops->trig & IRQF_SHARED)) + { + DBG("%s:disable irq,irq=%d\n",__func__,client->irq); + disable_irq_nosync(client->irq);//disable irq + } + } + else + cancel_delayed_work_sync(&sensor->delaywork); + + sensor->status_cur = SENSOR_OFF; + } + } + mutex_unlock(&sensor->operation_mutex); + DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__); + break; + + default: + break; + } + +error: + return result; +} + + + + +static int sensor_misc_device_register(struct sensor_private_data *sensor, int type) +{ + int result = 0; + + switch(type) + { + case SENSOR_TYPE_ANGLE: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = angle_dev_ioctl; + sensor->fops.open = angle_dev_open; + sensor->fops.release = angle_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "angle"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + + break; + + case SENSOR_TYPE_ACCEL: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = gsensor_dev_ioctl; + #ifdef CONFIG_COMPAT + sensor->fops.compat_ioctl = gsensor_dev_ioctl; + #endif + sensor->fops.open = gsensor_dev_open; + sensor->fops.release = gsensor_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "mma8452_daemon"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + + break; + + case SENSOR_TYPE_COMPASS: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = compass_dev_ioctl; +#ifdef CONFIG_COMPAT sensor->fops.compat_ioctl = compass_dev_compat_ioctl; #endif - sensor->fops.open = compass_dev_open; - sensor->fops.release = compass_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "compass"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - - break; - - case SENSOR_TYPE_GYROSCOPE: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = gyro_dev_ioctl; - sensor->fops.open = gyro_dev_open; - sensor->fops.release = gyro_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "gyrosensor"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - - break; - - case SENSOR_TYPE_LIGHT: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = light_dev_ioctl; + sensor->fops.open = compass_dev_open; + sensor->fops.release = compass_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "compass"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + + break; + + case SENSOR_TYPE_GYROSCOPE: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = gyro_dev_ioctl; + sensor->fops.open = gyro_dev_open; + sensor->fops.release = gyro_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "gyrosensor"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + + break; + + case SENSOR_TYPE_LIGHT: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = light_dev_ioctl; #ifdef CONFIG_COMPAT sensor->fops.compat_ioctl = light_dev_compat_ioctl; #endif - sensor->fops.open = light_dev_open; - sensor->fops.release = light_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "lightsensor"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - break; - - case SENSOR_TYPE_PROXIMITY: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = proximity_dev_ioctl; + sensor->fops.open = light_dev_open; + sensor->fops.release = light_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "lightsensor"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + break; + + case SENSOR_TYPE_PROXIMITY: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = proximity_dev_ioctl; #ifdef CONFIG_COMPAT sensor->fops.compat_ioctl = proximity_dev_compat_ioctl; #endif - sensor->fops.open = proximity_dev_open; - sensor->fops.release = proximity_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "psensor"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - break; - - case SENSOR_TYPE_TEMPERATURE: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = temperature_dev_ioctl; - sensor->fops.open = temperature_dev_open; - sensor->fops.release = temperature_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "temperature"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - - break; - - case SENSOR_TYPE_PRESSURE: - if(!sensor->ops->misc_dev) - { - sensor->fops.owner = THIS_MODULE; - sensor->fops.unlocked_ioctl = pressure_dev_ioctl; - sensor->fops.open = pressure_dev_open; - sensor->fops.release = pressure_dev_release; - - sensor->miscdev.minor = MISC_DYNAMIC_MINOR; - sensor->miscdev.name = "pressure"; - sensor->miscdev.fops = &sensor->fops; - } - else - { - memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); - - } - - break; - - default: - printk("%s:unknow sensor type=%d\n",__func__,type); - result = -1; - goto error; - } - - sensor->miscdev.parent = &sensor->client->dev; - result = misc_register(&sensor->miscdev); - if (result < 0) { - dev_err(&sensor->client->dev, - "fail to register misc device %s\n", sensor->miscdev.name); - goto error; - } - - printk("%s:miscdevice: %s\n",__func__,sensor->miscdev.name); - -error: - - return result; - -} - -int sensor_register_slave(int type,struct i2c_client *client, - struct sensor_platform_data *slave_pdata, - struct sensor_operate *(*get_sensor_ops)(void)) -{ - int result = 0; - struct sensor_operate *ops = get_sensor_ops(); - if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID)) - { - printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c); - return -1; - } - sensor_ops[ops->id_i2c] = ops; - printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c); - return result; -} - - -int sensor_unregister_slave(int type,struct i2c_client *client, - struct sensor_platform_data *slave_pdata, - struct sensor_operate *(*get_sensor_ops)(void)) -{ - int result = 0; - struct sensor_operate *ops = get_sensor_ops(); - if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID)) - { - printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c); - return -1; - } - printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c); - sensor_ops[ops->id_i2c] = NULL; - return result; -} - - -int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - struct sensor_platform_data *pdata; - struct device_node *np = client->dev.of_node; - enum of_gpio_flags rst_flags, pwr_flags; - unsigned long irq_flags; - int result = 0; - int type = 0; - - dev_info(&client->adapter->dev, "%s: %s,%p\n", __func__, devid->name, client); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - result = -ENODEV; - goto out_no_free; - } - if (!np) { - dev_err(&client->dev, "no device tree\n"); - return -EINVAL; - } - pdata = devm_kzalloc(&client->dev,sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - result = -ENOMEM; - goto out_no_free; - } - sensor = devm_kzalloc(&client->dev,sizeof(*sensor), GFP_KERNEL); - if (!sensor) { - result = -ENOMEM; - goto out_no_free; - } - - of_property_read_u32(np,"type",&(pdata->type)); - - pdata->irq_pin = of_get_named_gpio_flags(np, "irq-gpio", 0,(enum of_gpio_flags *)&irq_flags); - pdata->reset_pin = of_get_named_gpio_flags(np, "reset-gpio",0,&rst_flags); - pdata->power_pin = of_get_named_gpio_flags(np, "power-gpio",0,&pwr_flags); - - of_property_read_u32(np,"irq_enable",&(pdata->irq_enable)); - of_property_read_u32(np,"poll_delay_ms",&(pdata->poll_delay_ms)); - - of_property_read_u32(np,"x_min",&(pdata->x_min)); - of_property_read_u32(np,"y_min",&(pdata->y_min)); - of_property_read_u32(np,"z_min",&(pdata->z_min)); - of_property_read_u32(np,"factory",&(pdata->factory)); - of_property_read_u32(np,"layout",&(pdata->layout)); - - of_property_read_u8(np,"address",&(pdata->address)); - of_get_property(np, "project_name", pdata->project_name); + sensor->fops.open = proximity_dev_open; + sensor->fops.release = proximity_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "psensor"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + break; + + case SENSOR_TYPE_TEMPERATURE: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = temperature_dev_ioctl; + sensor->fops.open = temperature_dev_open; + sensor->fops.release = temperature_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "temperature"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + + break; + + case SENSOR_TYPE_PRESSURE: + if(!sensor->ops->misc_dev) + { + sensor->fops.owner = THIS_MODULE; + sensor->fops.unlocked_ioctl = pressure_dev_ioctl; + sensor->fops.open = pressure_dev_open; + sensor->fops.release = pressure_dev_release; + + sensor->miscdev.minor = MISC_DYNAMIC_MINOR; + sensor->miscdev.name = "pressure"; + sensor->miscdev.fops = &sensor->fops; + } + else + { + memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev)); + + } + + break; + + default: + printk("%s:unknow sensor type=%d\n",__func__,type); + result = -1; + goto error; + } + + sensor->miscdev.parent = &sensor->client->dev; + result = misc_register(&sensor->miscdev); + if (result < 0) { + dev_err(&sensor->client->dev, + "fail to register misc device %s\n", sensor->miscdev.name); + goto error; + } + + printk("%s:miscdevice: %s\n",__func__,sensor->miscdev.name); + +error: + + return result; + +} + +int sensor_register_slave(int type,struct i2c_client *client, + struct sensor_platform_data *slave_pdata, + struct sensor_operate *(*get_sensor_ops)(void)) +{ + int result = 0; + struct sensor_operate *ops = get_sensor_ops(); + if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID)) + { + printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c); + return -1; + } + sensor_ops[ops->id_i2c] = ops; + printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c); + return result; +} + + +int sensor_unregister_slave(int type,struct i2c_client *client, + struct sensor_platform_data *slave_pdata, + struct sensor_operate *(*get_sensor_ops)(void)) +{ + int result = 0; + struct sensor_operate *ops = get_sensor_ops(); + if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID)) + { + printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c); + return -1; + } + printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c); + sensor_ops[ops->id_i2c] = NULL; + return result; +} + + +int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + struct sensor_platform_data *pdata; + struct device_node *np = client->dev.of_node; + enum of_gpio_flags rst_flags, pwr_flags; + unsigned long irq_flags; + int result = 0; + int type = 0; + + dev_info(&client->adapter->dev, "%s: %s,%p\n", __func__, devid->name, client); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + result = -ENODEV; + goto out_no_free; + } + if (!np) { + dev_err(&client->dev, "no device tree\n"); + return -EINVAL; + } + pdata = devm_kzalloc(&client->dev,sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + result = -ENOMEM; + goto out_no_free; + } + sensor = devm_kzalloc(&client->dev,sizeof(*sensor), GFP_KERNEL); + if (!sensor) { + result = -ENOMEM; + goto out_no_free; + } + + of_property_read_u32(np,"type",&(pdata->type)); + + pdata->irq_pin = of_get_named_gpio_flags(np, "irq-gpio", 0,(enum of_gpio_flags *)&irq_flags); + pdata->reset_pin = of_get_named_gpio_flags(np, "reset-gpio",0,&rst_flags); + pdata->power_pin = of_get_named_gpio_flags(np, "power-gpio",0,&pwr_flags); + + of_property_read_u32(np,"irq_enable",&(pdata->irq_enable)); + of_property_read_u32(np,"poll_delay_ms",&(pdata->poll_delay_ms)); + + of_property_read_u32(np,"x_min",&(pdata->x_min)); + of_property_read_u32(np,"y_min",&(pdata->y_min)); + of_property_read_u32(np,"z_min",&(pdata->z_min)); + of_property_read_u32(np,"factory",&(pdata->factory)); + of_property_read_u32(np,"layout",&(pdata->layout)); + + of_property_read_u8(np,"address",&(pdata->address)); + of_get_property(np, "project_name", pdata->project_name); of_property_read_u32(np, "power-off-in-suspend", &pdata->power_off_in_suspend); - - switch(pdata->layout) - { - case 1: - pdata->orientation[0] = 1; - pdata->orientation[1] = 0; - pdata->orientation[2] = 0; - - pdata->orientation[3] = 0; - pdata->orientation[4] = 1; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = 1; - break; - - case 2: - pdata->orientation[0] = 0; - pdata->orientation[1] = -1; - pdata->orientation[2] = 0; - - pdata->orientation[3] = 1; - pdata->orientation[4] = 0; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = 1; - break; - - case 3: - pdata->orientation[0] = -1; - pdata->orientation[1] = 0; - pdata->orientation[2] = 0; - - pdata->orientation[3] = 0; - pdata->orientation[4] = -1; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = 1; - break; - - case 4: - pdata->orientation[0] = 0; - pdata->orientation[1] = 1; - pdata->orientation[2] = 0; - - pdata->orientation[3] = -1; - pdata->orientation[4] = 0; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = 1; - break; - - case 5: - pdata->orientation[0] = 1; - pdata->orientation[1] = 0; - pdata->orientation[2] = 0; - - pdata->orientation[3] = 0; - pdata->orientation[4] = -1; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = -1; - break; - - case 6: - pdata->orientation[0] = 0; - pdata->orientation[1] = -1; - pdata->orientation[2] = 0; - - pdata->orientation[3] = -1; - pdata->orientation[4] = 0; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = -1; - break; - - case 7: - pdata->orientation[0] = -1; - pdata->orientation[1] = 0; - pdata->orientation[2] = 0; - - pdata->orientation[3] = 0; - pdata->orientation[4] = 1; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = -1; - break; - - case 8: - pdata->orientation[0] = 0; - pdata->orientation[1] = 1; - pdata->orientation[2] = 0; - - pdata->orientation[3] = 1; - pdata->orientation[4] = 0; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = -1; - break; - - default: - pdata->orientation[0] = 1; - pdata->orientation[1] = 0; - pdata->orientation[2] = 0; - - pdata->orientation[3] = 0; - pdata->orientation[4] = 1; - pdata->orientation[5] = 0; - - pdata->orientation[6] = 0; - pdata->orientation[7] = 0; - pdata->orientation[8] = 1; - break; - } - - client->irq = pdata->irq_pin; - type = pdata->type; - pdata->irq_flags = irq_flags; - DBG("irq_flags = %lu padta->irq_flags = %lu\n",irq_flags, pdata->irq_flags); - DBG("type = %d \n",pdata->type); - DBG("irq = %d \n",pdata->irq); - DBG("irq_pin = %d \n",pdata->irq_pin); - DBG("pwer_pin = %d \n",pdata->power_pin); - DBG("reset_pin = %d \n",pdata->reset_pin); - DBG("irq_enable = %d \n",pdata->irq_enable); - - DBG("poll_delay_ms = %d \n",pdata->poll_delay_ms); - DBG("x_min = %d \n",pdata->x_min); - DBG("y_min = %d \n",pdata->y_min); - DBG("z_min = %d \n",pdata->z_min); - DBG("factory = %d \n",pdata->factory); - DBG("layout = %d \n",pdata->layout); - DBG("address = 0x%x \n",pdata->address); - DBG("project_name = [%s] \n",pdata->project_name); - - DBG(" == %d,%d ,%d \t ,%d ,%d ,%d , \t ,%d, %d, %d ,==%d\n",pdata->orientation[0],pdata->orientation[1],pdata->orientation[2] - ,pdata->orientation[3],pdata->orientation[4],pdata->orientation[5] - ,pdata->orientation[6],pdata->orientation[7],pdata->orientation[8],ARRAY_SIZE(pdata->orientation)); - - - if((type >= SENSOR_NUM_TYPES) || (type <= SENSOR_TYPE_NULL)) - { - dev_err(&client->adapter->dev, "sensor type is error %d\n", type); - result = -EFAULT; - goto out_no_free; - } - if(((int)devid->driver_data >= SENSOR_NUM_ID) || ((int)devid->driver_data <= ID_INVALID)) - { - dev_err(&client->adapter->dev, "sensor id is error %d\n", (int)devid->driver_data); - result = -EFAULT; - goto out_no_free; - } - i2c_set_clientdata(client, sensor); - sensor->client = client; - sensor->pdata = pdata; - sensor->type = type; - sensor->i2c_id = (struct i2c_device_id *)devid; - - - memset(&(sensor->axis), 0, sizeof(struct sensor_axis) ); - atomic_set(&(sensor->data_ready), 0); - init_waitqueue_head(&(sensor->data_ready_wq)); - mutex_init(&sensor->data_mutex); - mutex_init(&sensor->operation_mutex); - mutex_init(&sensor->sensor_mutex); - mutex_init(&sensor->i2c_mutex); - - /* As default, report all information */ - atomic_set(&sensor->flags.m_flag, 1); - atomic_set(&sensor->flags.a_flag, 1); - atomic_set(&sensor->flags.mv_flag, 1); - atomic_set(&sensor->flags.open_flag, 0); - atomic_set(&sensor->flags.debug_flag, 1); - init_waitqueue_head(&sensor->flags.open_wq); - sensor->flags.delay = 100; - - sensor->status_cur = SENSOR_OFF; - sensor->axis.x = 0; - sensor->axis.y = 0; - sensor->axis.z = 0; - - result = sensor_chip_init(sensor->client); - if(result < 0) - goto out_free_memory; - - sensor->input_dev = devm_input_allocate_device(&client->dev); - if (!sensor->input_dev) { - result = -ENOMEM; - dev_err(&client->dev, - "Failed to allocate input device\n"); - goto out_free_memory; - } - - switch(type) - { - case SENSOR_TYPE_ANGLE: - sensor->input_dev->name = "angle"; - set_bit(EV_ABS, sensor->input_dev->evbit); - /* x-axis acceleration */ - input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range - /* y-axis acceleration */ - input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range - /* z-axis acceleration */ - input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range - break; - - case SENSOR_TYPE_ACCEL: - sensor->input_dev->name = "gsensor"; - set_bit(EV_ABS, sensor->input_dev->evbit); - /* x-axis acceleration */ - input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range - /* y-axis acceleration */ - input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range - /* z-axis acceleration */ - input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range - break; - case SENSOR_TYPE_COMPASS: - sensor->input_dev->name = "compass"; - /* Setup input device */ - set_bit(EV_ABS, sensor->input_dev->evbit); - /* yaw (0, 360) */ - input_set_abs_params(sensor->input_dev, ABS_RX, 0, 23040, 0, 0); - /* pitch (-180, 180) */ - input_set_abs_params(sensor->input_dev, ABS_RY, -11520, 11520, 0, 0); - /* roll (-90, 90) */ - input_set_abs_params(sensor->input_dev, ABS_RZ, -5760, 5760, 0, 0); - /* x-axis acceleration (720 x 8G) */ - input_set_abs_params(sensor->input_dev, ABS_X, -5760, 5760, 0, 0); - /* y-axis acceleration (720 x 8G) */ - input_set_abs_params(sensor->input_dev, ABS_Y, -5760, 5760, 0, 0); - /* z-axis acceleration (720 x 8G) */ - input_set_abs_params(sensor->input_dev, ABS_Z, -5760, 5760, 0, 0); - /* status of magnetic sensor */ - input_set_abs_params(sensor->input_dev, ABS_RUDDER, -32768, 3, 0, 0); - /* status of acceleration sensor */ - input_set_abs_params(sensor->input_dev, ABS_WHEEL, -32768, 3, 0, 0); - /* x-axis of raw magnetic vector (-4096, 4095) */ - input_set_abs_params(sensor->input_dev, ABS_HAT0X, -20480, 20479, 0, 0); - /* y-axis of raw magnetic vector (-4096, 4095) */ - input_set_abs_params(sensor->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0); - /* z-axis of raw magnetic vector (-4096, 4095) */ - input_set_abs_params(sensor->input_dev, ABS_BRAKE, -20480, 20479, 0, 0); - break; - case SENSOR_TYPE_GYROSCOPE: - sensor->input_dev->name = "gyro"; - /* x-axis acceleration */ - input_set_capability(sensor->input_dev, EV_REL, REL_RX); - input_set_abs_params(sensor->input_dev, ABS_RX, sensor->ops->range[0], sensor->ops->range[1], 0, 0); - /* y-axis acceleration */ - input_set_capability(sensor->input_dev, EV_REL, REL_RY); - input_set_abs_params(sensor->input_dev, ABS_RY, sensor->ops->range[0], sensor->ops->range[1], 0, 0); - /* z-axis acceleration */ - input_set_capability(sensor->input_dev, EV_REL, REL_RZ); - input_set_abs_params(sensor->input_dev, ABS_RZ, sensor->ops->range[0], sensor->ops->range[1], 0, 0); - break; - case SENSOR_TYPE_LIGHT: - sensor->input_dev->name = "lightsensor-level"; - set_bit(EV_ABS, sensor->input_dev->evbit); - input_set_abs_params(sensor->input_dev, ABS_MISC, sensor->ops->range[0], sensor->ops->range[1], 0, 0); - input_set_abs_params(sensor->input_dev, ABS_TOOL_WIDTH , sensor->ops->brightness[0],sensor->ops->brightness[1], 0, 0); - break; - case SENSOR_TYPE_PROXIMITY: - sensor->input_dev->name = "proximity"; - set_bit(EV_ABS, sensor->input_dev->evbit); - input_set_abs_params(sensor->input_dev, ABS_DISTANCE, sensor->ops->range[0], sensor->ops->range[1], 0, 0); - break; - case SENSOR_TYPE_TEMPERATURE: - sensor->input_dev->name = "temperature"; - set_bit(EV_ABS, sensor->input_dev->evbit); - input_set_abs_params(sensor->input_dev, ABS_THROTTLE, sensor->ops->range[0], sensor->ops->range[1], 0, 0); - break; - case SENSOR_TYPE_PRESSURE: - sensor->input_dev->name = "pressure"; - set_bit(EV_ABS, sensor->input_dev->evbit); - input_set_abs_params(sensor->input_dev, ABS_PRESSURE, sensor->ops->range[0], sensor->ops->range[1], 0, 0); - break; - default: - printk("%s:unknow sensor type=%d\n",__func__,type); - break; - - } - sensor->input_dev->dev.parent = &client->dev; - - result = input_register_device(sensor->input_dev); - if (result) { - dev_err(&client->dev, - "Unable to register input device %s\n", sensor->input_dev->name); - goto out_input_register_device_failed; - } - - result = sensor_irq_init(sensor->client); - if (result) { - dev_err(&client->dev, - "fail to init sensor irq,ret=%d\n",result); - goto out_input_register_device_failed; - } - - - sensor->miscdev.parent = &client->dev; - result = sensor_misc_device_register(sensor, type); - if (result) { - dev_err(&client->dev, - "fail to register misc device %s\n", sensor->miscdev.name); - goto out_misc_device_register_device_failed; - } - - g_sensor[type] = sensor; - - if((type == SENSOR_TYPE_ACCEL) && (sensor->pdata->factory)) //only support setting gsensor orientation online now - { - result = gsensor_class_init(); - if (result) { - dev_err(&client->dev, - "fail to register misc device %s\n", sensor->i2c_id->name); - goto out_misc_device_register_device_failed; - } - } - -#ifdef CONFIG_HAS_EARLYSUSPEND - if((sensor->ops->suspend) && (sensor->ops->resume)) - { - sensor->early_suspend.suspend = sensor_suspend; - sensor->early_suspend.resume = sensor_resume; - sensor->early_suspend.level = 0x02; - register_early_suspend(&sensor->early_suspend); - } -#endif - - printk("%s:initialized ok,sensor name:%s,type:%d,id=%d\n\n",__func__,sensor->ops->name,type,(int)sensor->i2c_id->driver_data); - - return result; - -out_misc_device_register_device_failed: -out_input_register_device_failed: -out_free_memory: -out_no_free: - dev_err(&client->adapter->dev, "%s failed %d\n\n", __func__, result); - return result; - -} - -static void sensor_shut_down(struct i2c_client *client) -{ -#ifdef CONFIG_HAS_EARLYSUSPEND - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - if((sensor->ops->suspend) && (sensor->ops->resume)) - unregister_early_suspend(&sensor->early_suspend); - DBG("%s:%s\n",__func__,sensor->i2c_id->name); -#endif -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor_private_data *sensor = - (struct sensor_private_data *) i2c_get_clientdata(client); - int result = 0; - - cancel_delayed_work_sync(&sensor->delaywork); - misc_deregister(&sensor->miscdev); -#ifdef CONFIG_HAS_EARLYSUSPEND - if((sensor->ops->suspend) && (sensor->ops->resume)) - unregister_early_suspend(&sensor->early_suspend); -#endif - return result; -} - -static const struct i2c_device_id sensor_id[] = { - /*angle*/ - {"angle_kxtik", ANGLE_ID_KXTIK}, - {"angle_lis3dh", ANGLE_ID_LIS3DH}, - /*gsensor*/ - {"gsensor", ACCEL_ID_ALL}, - {"gs_mma8452", ACCEL_ID_MMA845X}, - {"gs_kxtik", ACCEL_ID_KXTIK}, - {"gs_kxtj9", ACCEL_ID_KXTJ9}, - {"gs_lis3dh", ACCEL_ID_LIS3DH}, - {"gs_mma7660", ACCEL_ID_MMA7660}, - {"gs_mxc6225", ACCEL_ID_MXC6225}, - {"gs_dmard10", ACCEL_ID_DMARD10}, - {"gs_lsm303d", ACCEL_ID_LSM303D}, - {"gs_mc3230",ACCEL_ID_MC3230}, - {"mpu6880_acc",ACCEL_ID_MPU6880}, - {"mpu6500_acc",ACCEL_ID_MPU6500}, + + switch(pdata->layout) + { + case 1: + pdata->orientation[0] = 1; + pdata->orientation[1] = 0; + pdata->orientation[2] = 0; + + pdata->orientation[3] = 0; + pdata->orientation[4] = 1; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = 1; + break; + + case 2: + pdata->orientation[0] = 0; + pdata->orientation[1] = -1; + pdata->orientation[2] = 0; + + pdata->orientation[3] = 1; + pdata->orientation[4] = 0; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = 1; + break; + + case 3: + pdata->orientation[0] = -1; + pdata->orientation[1] = 0; + pdata->orientation[2] = 0; + + pdata->orientation[3] = 0; + pdata->orientation[4] = -1; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = 1; + break; + + case 4: + pdata->orientation[0] = 0; + pdata->orientation[1] = 1; + pdata->orientation[2] = 0; + + pdata->orientation[3] = -1; + pdata->orientation[4] = 0; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = 1; + break; + + case 5: + pdata->orientation[0] = 1; + pdata->orientation[1] = 0; + pdata->orientation[2] = 0; + + pdata->orientation[3] = 0; + pdata->orientation[4] = -1; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = -1; + break; + + case 6: + pdata->orientation[0] = 0; + pdata->orientation[1] = -1; + pdata->orientation[2] = 0; + + pdata->orientation[3] = -1; + pdata->orientation[4] = 0; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = -1; + break; + + case 7: + pdata->orientation[0] = -1; + pdata->orientation[1] = 0; + pdata->orientation[2] = 0; + + pdata->orientation[3] = 0; + pdata->orientation[4] = 1; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = -1; + break; + + case 8: + pdata->orientation[0] = 0; + pdata->orientation[1] = 1; + pdata->orientation[2] = 0; + + pdata->orientation[3] = 1; + pdata->orientation[4] = 0; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = -1; + break; + + default: + pdata->orientation[0] = 1; + pdata->orientation[1] = 0; + pdata->orientation[2] = 0; + + pdata->orientation[3] = 0; + pdata->orientation[4] = 1; + pdata->orientation[5] = 0; + + pdata->orientation[6] = 0; + pdata->orientation[7] = 0; + pdata->orientation[8] = 1; + break; + } + + client->irq = pdata->irq_pin; + type = pdata->type; + pdata->irq_flags = irq_flags; + DBG("irq_flags = %lu padta->irq_flags = %lu\n",irq_flags, pdata->irq_flags); + DBG("type = %d \n",pdata->type); + DBG("irq = %d \n",pdata->irq); + DBG("irq_pin = %d \n",pdata->irq_pin); + DBG("pwer_pin = %d \n",pdata->power_pin); + DBG("reset_pin = %d \n",pdata->reset_pin); + DBG("irq_enable = %d \n",pdata->irq_enable); + + DBG("poll_delay_ms = %d \n",pdata->poll_delay_ms); + DBG("x_min = %d \n",pdata->x_min); + DBG("y_min = %d \n",pdata->y_min); + DBG("z_min = %d \n",pdata->z_min); + DBG("factory = %d \n",pdata->factory); + DBG("layout = %d \n",pdata->layout); + DBG("address = 0x%x \n",pdata->address); + DBG("project_name = [%s] \n",pdata->project_name); + + DBG(" == %d,%d ,%d \t ,%d ,%d ,%d , \t ,%d, %d, %d ,==%d\n",pdata->orientation[0],pdata->orientation[1],pdata->orientation[2] + ,pdata->orientation[3],pdata->orientation[4],pdata->orientation[5] + ,pdata->orientation[6],pdata->orientation[7],pdata->orientation[8],ARRAY_SIZE(pdata->orientation)); + + + if((type >= SENSOR_NUM_TYPES) || (type <= SENSOR_TYPE_NULL)) + { + dev_err(&client->adapter->dev, "sensor type is error %d\n", type); + result = -EFAULT; + goto out_no_free; + } + if(((int)devid->driver_data >= SENSOR_NUM_ID) || ((int)devid->driver_data <= ID_INVALID)) + { + dev_err(&client->adapter->dev, "sensor id is error %d\n", (int)devid->driver_data); + result = -EFAULT; + goto out_no_free; + } + i2c_set_clientdata(client, sensor); + sensor->client = client; + sensor->pdata = pdata; + sensor->type = type; + sensor->i2c_id = (struct i2c_device_id *)devid; + + + memset(&(sensor->axis), 0, sizeof(struct sensor_axis) ); + atomic_set(&(sensor->data_ready), 0); + init_waitqueue_head(&(sensor->data_ready_wq)); + mutex_init(&sensor->data_mutex); + mutex_init(&sensor->operation_mutex); + mutex_init(&sensor->sensor_mutex); + mutex_init(&sensor->i2c_mutex); + + /* As default, report all information */ + atomic_set(&sensor->flags.m_flag, 1); + atomic_set(&sensor->flags.a_flag, 1); + atomic_set(&sensor->flags.mv_flag, 1); + atomic_set(&sensor->flags.open_flag, 0); + atomic_set(&sensor->flags.debug_flag, 1); + init_waitqueue_head(&sensor->flags.open_wq); + sensor->flags.delay = 100; + + sensor->status_cur = SENSOR_OFF; + sensor->axis.x = 0; + sensor->axis.y = 0; + sensor->axis.z = 0; + + result = sensor_chip_init(sensor->client); + if(result < 0) + goto out_free_memory; + + sensor->input_dev = devm_input_allocate_device(&client->dev); + if (!sensor->input_dev) { + result = -ENOMEM; + dev_err(&client->dev, + "Failed to allocate input device\n"); + goto out_free_memory; + } + + switch(type) + { + case SENSOR_TYPE_ANGLE: + sensor->input_dev->name = "angle"; + set_bit(EV_ABS, sensor->input_dev->evbit); + /* x-axis acceleration */ + input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range + /* y-axis acceleration */ + input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range + /* z-axis acceleration */ + input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range + break; + + case SENSOR_TYPE_ACCEL: + sensor->input_dev->name = "gsensor"; + set_bit(EV_ABS, sensor->input_dev->evbit); + /* x-axis acceleration */ + input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range + /* y-axis acceleration */ + input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range + /* z-axis acceleration */ + input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range + break; + case SENSOR_TYPE_COMPASS: + sensor->input_dev->name = "compass"; + /* Setup input device */ + set_bit(EV_ABS, sensor->input_dev->evbit); + /* yaw (0, 360) */ + input_set_abs_params(sensor->input_dev, ABS_RX, 0, 23040, 0, 0); + /* pitch (-180, 180) */ + input_set_abs_params(sensor->input_dev, ABS_RY, -11520, 11520, 0, 0); + /* roll (-90, 90) */ + input_set_abs_params(sensor->input_dev, ABS_RZ, -5760, 5760, 0, 0); + /* x-axis acceleration (720 x 8G) */ + input_set_abs_params(sensor->input_dev, ABS_X, -5760, 5760, 0, 0); + /* y-axis acceleration (720 x 8G) */ + input_set_abs_params(sensor->input_dev, ABS_Y, -5760, 5760, 0, 0); + /* z-axis acceleration (720 x 8G) */ + input_set_abs_params(sensor->input_dev, ABS_Z, -5760, 5760, 0, 0); + /* status of magnetic sensor */ + input_set_abs_params(sensor->input_dev, ABS_RUDDER, -32768, 3, 0, 0); + /* status of acceleration sensor */ + input_set_abs_params(sensor->input_dev, ABS_WHEEL, -32768, 3, 0, 0); + /* x-axis of raw magnetic vector (-4096, 4095) */ + input_set_abs_params(sensor->input_dev, ABS_HAT0X, -20480, 20479, 0, 0); + /* y-axis of raw magnetic vector (-4096, 4095) */ + input_set_abs_params(sensor->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0); + /* z-axis of raw magnetic vector (-4096, 4095) */ + input_set_abs_params(sensor->input_dev, ABS_BRAKE, -20480, 20479, 0, 0); + break; + case SENSOR_TYPE_GYROSCOPE: + sensor->input_dev->name = "gyro"; + /* x-axis acceleration */ + input_set_capability(sensor->input_dev, EV_REL, REL_RX); + input_set_abs_params(sensor->input_dev, ABS_RX, sensor->ops->range[0], sensor->ops->range[1], 0, 0); + /* y-axis acceleration */ + input_set_capability(sensor->input_dev, EV_REL, REL_RY); + input_set_abs_params(sensor->input_dev, ABS_RY, sensor->ops->range[0], sensor->ops->range[1], 0, 0); + /* z-axis acceleration */ + input_set_capability(sensor->input_dev, EV_REL, REL_RZ); + input_set_abs_params(sensor->input_dev, ABS_RZ, sensor->ops->range[0], sensor->ops->range[1], 0, 0); + break; + case SENSOR_TYPE_LIGHT: + sensor->input_dev->name = "lightsensor-level"; + set_bit(EV_ABS, sensor->input_dev->evbit); + input_set_abs_params(sensor->input_dev, ABS_MISC, sensor->ops->range[0], sensor->ops->range[1], 0, 0); + input_set_abs_params(sensor->input_dev, ABS_TOOL_WIDTH , sensor->ops->brightness[0],sensor->ops->brightness[1], 0, 0); + break; + case SENSOR_TYPE_PROXIMITY: + sensor->input_dev->name = "proximity"; + set_bit(EV_ABS, sensor->input_dev->evbit); + input_set_abs_params(sensor->input_dev, ABS_DISTANCE, sensor->ops->range[0], sensor->ops->range[1], 0, 0); + break; + case SENSOR_TYPE_TEMPERATURE: + sensor->input_dev->name = "temperature"; + set_bit(EV_ABS, sensor->input_dev->evbit); + input_set_abs_params(sensor->input_dev, ABS_THROTTLE, sensor->ops->range[0], sensor->ops->range[1], 0, 0); + break; + case SENSOR_TYPE_PRESSURE: + sensor->input_dev->name = "pressure"; + set_bit(EV_ABS, sensor->input_dev->evbit); + input_set_abs_params(sensor->input_dev, ABS_PRESSURE, sensor->ops->range[0], sensor->ops->range[1], 0, 0); + break; + default: + printk("%s:unknow sensor type=%d\n",__func__,type); + break; + + } + sensor->input_dev->dev.parent = &client->dev; + + result = input_register_device(sensor->input_dev); + if (result) { + dev_err(&client->dev, + "Unable to register input device %s\n", sensor->input_dev->name); + goto out_input_register_device_failed; + } + + result = sensor_irq_init(sensor->client); + if (result) { + dev_err(&client->dev, + "fail to init sensor irq,ret=%d\n",result); + goto out_input_register_device_failed; + } + + + sensor->miscdev.parent = &client->dev; + result = sensor_misc_device_register(sensor, type); + if (result) { + dev_err(&client->dev, + "fail to register misc device %s\n", sensor->miscdev.name); + goto out_misc_device_register_device_failed; + } + + g_sensor[type] = sensor; + + if((type == SENSOR_TYPE_ACCEL) && (sensor->pdata->factory)) //only support setting gsensor orientation online now + { + result = gsensor_class_init(); + if (result) { + dev_err(&client->dev, + "fail to register misc device %s\n", sensor->i2c_id->name); + goto out_misc_device_register_device_failed; + } + } + +#ifdef CONFIG_HAS_EARLYSUSPEND + if((sensor->ops->suspend) && (sensor->ops->resume)) + { + sensor->early_suspend.suspend = sensor_suspend; + sensor->early_suspend.resume = sensor_resume; + sensor->early_suspend.level = 0x02; + register_early_suspend(&sensor->early_suspend); + } +#endif + + printk("%s:initialized ok,sensor name:%s,type:%d,id=%d\n\n",__func__,sensor->ops->name,type,(int)sensor->i2c_id->driver_data); + + return result; + +out_misc_device_register_device_failed: +out_input_register_device_failed: +out_free_memory: +out_no_free: + dev_err(&client->adapter->dev, "%s failed %d\n\n", __func__, result); + return result; + +} + +static void sensor_shut_down(struct i2c_client *client) +{ +#ifdef CONFIG_HAS_EARLYSUSPEND + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + if((sensor->ops->suspend) && (sensor->ops->resume)) + unregister_early_suspend(&sensor->early_suspend); + DBG("%s:%s\n",__func__,sensor->i2c_id->name); +#endif +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + + cancel_delayed_work_sync(&sensor->delaywork); + misc_deregister(&sensor->miscdev); +#ifdef CONFIG_HAS_EARLYSUSPEND + if((sensor->ops->suspend) && (sensor->ops->resume)) + unregister_early_suspend(&sensor->early_suspend); +#endif + return result; +} + +static const struct i2c_device_id sensor_id[] = { + /*angle*/ + {"angle_kxtik", ANGLE_ID_KXTIK}, + {"angle_lis3dh", ANGLE_ID_LIS3DH}, + /*gsensor*/ + {"gsensor", ACCEL_ID_ALL}, + {"gs_mma8452", ACCEL_ID_MMA845X}, + {"gs_kxtik", ACCEL_ID_KXTIK}, + {"gs_kxtj9", ACCEL_ID_KXTJ9}, + {"gs_lis3dh", ACCEL_ID_LIS3DH}, + {"gs_mma7660", ACCEL_ID_MMA7660}, + {"gs_mxc6225", ACCEL_ID_MXC6225}, + {"gs_dmard10", ACCEL_ID_DMARD10}, + {"gs_lsm303d", ACCEL_ID_LSM303D}, + {"gs_mc3230",ACCEL_ID_MC3230}, + {"mpu6880_acc",ACCEL_ID_MPU6880}, + {"mpu6500_acc",ACCEL_ID_MPU6500}, {"lsm330_acc", ACCEL_ID_LSM330}, - /*compass*/ - {"compass", COMPASS_ID_ALL}, - {"ak8975", COMPASS_ID_AK8975}, - {"ak8963", COMPASS_ID_AK8963}, - {"ak09911", COMPASS_ID_AK09911}, - {"mmc314x", COMPASS_ID_MMC314X}, - /*gyroscope*/ - {"gyro", GYRO_ID_ALL}, - {"l3g4200d_gyro", GYRO_ID_L3G4200D}, - {"l3g20d_gyro", GYRO_ID_L3G20D}, - {"ewtsa_gyro", GYRO_ID_EWTSA}, - {"k3g", GYRO_ID_K3G}, - {"mpu6880_gyro",GYRO_ID_MPU6880}, + /*compass*/ + {"compass", COMPASS_ID_ALL}, + {"ak8975", COMPASS_ID_AK8975}, + {"ak8963", COMPASS_ID_AK8963}, + {"ak09911", COMPASS_ID_AK09911}, + {"mmc314x", COMPASS_ID_MMC314X}, + /*gyroscope*/ + {"gyro", GYRO_ID_ALL}, + {"l3g4200d_gyro", GYRO_ID_L3G4200D}, + {"l3g20d_gyro", GYRO_ID_L3G20D}, + {"ewtsa_gyro", GYRO_ID_EWTSA}, + {"k3g", GYRO_ID_K3G}, + {"mpu6880_gyro",GYRO_ID_MPU6880}, {"lsm330_gyro", GYRO_ID_LSM330}, - /*light sensor*/ - {"lightsensor", LIGHT_ID_ALL}, - {"light_cm3217", LIGHT_ID_CM3217}, - {"light_cm3218", LIGHT_ID_CM3218}, - {"light_cm3232", LIGHT_ID_CM3232}, - {"light_al3006", LIGHT_ID_AL3006}, - {"ls_stk3171", LIGHT_ID_STK3171}, - {"ls_isl29023", LIGHT_ID_ISL29023}, - {"ls_ap321xx", LIGHT_ID_AP321XX}, - {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR}, - {"ls_us5152", LIGHT_ID_US5152}, - /*proximity sensor*/ - {"psensor", PROXIMITY_ID_ALL}, - {"proximity_al3006", PROXIMITY_ID_AL3006}, - {"ps_stk3171", PROXIMITY_ID_STK3171}, - {"ps_ap321xx", PROXIMITY_ID_AP321XX}, - - /*temperature*/ - {"temperature", TEMPERATURE_ID_ALL}, - {"tmp_ms5607", TEMPERATURE_ID_MS5607}, - - /*pressure*/ - {"pressure", PRESSURE_ID_ALL}, - {"pr_ms5607", PRESSURE_ID_MS5607}, - - {}, -}; - -static struct of_device_id sensor_dt_ids[] = { - /*gsensor*/ - { .compatible = "gs_mma8452" }, - { .compatible = "gs_lis3dh" }, - { .compatible = "gs_lsm303d" }, - { .compatible = "gs_mma7660" }, - { .compatible = "gs_mxc6225" }, - { .compatible = "gs_mc3230" }, + /*light sensor*/ + {"lightsensor", LIGHT_ID_ALL}, + {"light_cm3217", LIGHT_ID_CM3217}, + {"light_cm3218", LIGHT_ID_CM3218}, + {"light_cm3232", LIGHT_ID_CM3232}, + {"light_al3006", LIGHT_ID_AL3006}, + {"ls_stk3171", LIGHT_ID_STK3171}, + {"ls_isl29023", LIGHT_ID_ISL29023}, + {"ls_ap321xx", LIGHT_ID_AP321XX}, + {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR}, + {"ls_us5152", LIGHT_ID_US5152}, + /*proximity sensor*/ + {"psensor", PROXIMITY_ID_ALL}, + {"proximity_al3006", PROXIMITY_ID_AL3006}, + {"ps_stk3171", PROXIMITY_ID_STK3171}, + {"ps_ap321xx", PROXIMITY_ID_AP321XX}, + + /*temperature*/ + {"temperature", TEMPERATURE_ID_ALL}, + {"tmp_ms5607", TEMPERATURE_ID_MS5607}, + + /*pressure*/ + {"pressure", PRESSURE_ID_ALL}, + {"pr_ms5607", PRESSURE_ID_MS5607}, + + {}, +}; + +static struct of_device_id sensor_dt_ids[] = { + /*gsensor*/ + { .compatible = "gs_mma8452" }, + { .compatible = "gs_lis3dh" }, + { .compatible = "gs_lsm303d" }, + { .compatible = "gs_mma7660" }, + { .compatible = "gs_mxc6225" }, + { .compatible = "gs_mc3230" }, { .compatible = "lsm330_acc" }, - /*compass*/ - { .compatible = "ak8975" }, - { .compatible = "ak8963" }, - { .compatible = "ak09911" }, - { .compatible = "mmc314x" }, - - /* gyroscop*/ - { .compatible = "l3g4200d_gyro" }, - { .compatible = "l3g20d_gyro" }, - { .compatible = "ewtsa_gyro" }, - { .compatible = "k3g" }, + /*compass*/ + { .compatible = "ak8975" }, + { .compatible = "ak8963" }, + { .compatible = "ak09911" }, + { .compatible = "mmc314x" }, + + /* gyroscop*/ + { .compatible = "l3g4200d_gyro" }, + { .compatible = "l3g20d_gyro" }, + { .compatible = "ewtsa_gyro" }, + { .compatible = "k3g" }, { .compatible = "lsm330_gyro" }, - - /*light sensor*/ - { .compatible = "light_cm3217" }, - { .compatible = "light_cm3232" }, - { .compatible = "light_al3006" }, - { .compatible = "ls_stk3171" }, - { .compatible = "ls_ap321xx" }, - - { .compatible = "ls_photoresistor" }, - { .compatible = "ls_us5152" }, - - /*temperature sensor*/ - { .compatible = "tmp_ms5607" }, - - /*pressure sensor*/ - { .compatible = "pr_ms5607" }, - - /*hall sensor*/ - { .compatible = "hall_och165t" }, - { } -}; - - -static struct i2c_driver sensor_driver = { - .probe = sensor_probe, - .remove = sensor_remove, - .shutdown = sensor_shut_down, - .id_table = sensor_id, + + /*light sensor*/ + { .compatible = "light_cm3217" }, + { .compatible = "light_cm3232" }, + { .compatible = "light_al3006" }, + { .compatible = "ls_stk3171" }, + { .compatible = "ls_ap321xx" }, + + { .compatible = "ls_photoresistor" }, + { .compatible = "ls_us5152" }, + + /*temperature sensor*/ + { .compatible = "tmp_ms5607" }, + + /*pressure sensor*/ + { .compatible = "pr_ms5607" }, + + /*hall sensor*/ + { .compatible = "hall_och165t" }, + { } +}; + + +static struct i2c_driver sensor_driver = { + .probe = sensor_probe, + .remove = sensor_remove, + .shutdown = sensor_shut_down, + .id_table = sensor_id, .driver = { .owner = THIS_MODULE, .name = "sensors", .of_match_table = of_match_ptr(sensor_dt_ids), .pm = SENSOR_PM_OPS, - }, -}; - -static int __init sensor_init(void) -{ - int res = i2c_add_driver(&sensor_driver); - struct proc_dir_entry *sensor_proc_entry; - pr_info("%s: Probe name %s\n", __func__, sensor_driver.driver.name); - if (res) - pr_err("%s failed\n", __func__); - - sensor_proc_entry = proc_create("driver/sensor_dbg", 0660, NULL, &sensor_proc_fops); - printk("%s\n", SENSOR_VERSION_AND_TIME); - return res; -} - -static void __exit sensor_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&sensor_driver); -} - -late_initcall(sensor_init); -module_exit(sensor_exit); - -MODULE_AUTHOR("ROCKCHIP Corporation:lw@rock-chips.com"); -MODULE_DESCRIPTION("User space character device interface for sensors"); -MODULE_LICENSE("GPL"); - + }, +}; + +static int __init sensor_init(void) +{ + int res = i2c_add_driver(&sensor_driver); + struct proc_dir_entry *sensor_proc_entry; + pr_info("%s: Probe name %s\n", __func__, sensor_driver.driver.name); + if (res) + pr_err("%s failed\n", __func__); + + sensor_proc_entry = proc_create("driver/sensor_dbg", 0660, NULL, &sensor_proc_fops); + printk("%s\n", SENSOR_VERSION_AND_TIME); + return res; +} + +static void __exit sensor_exit(void) +{ + pr_info("%s\n", __func__); + i2c_del_driver(&sensor_driver); +} + +late_initcall(sensor_init); +module_exit(sensor_exit); + +MODULE_AUTHOR("ROCKCHIP Corporation:lw@rock-chips.com"); +MODULE_DESCRIPTION("User space character device interface for sensors"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/input/sensors/sensor-i2c.c b/drivers/input/sensors/sensor-i2c.c index f54835096e88..d9cdf372ba6f 100755 --- a/drivers/input/sensors/sensor-i2c.c +++ b/drivers/input/sensors/sensor-i2c.c @@ -1,245 +1,245 @@ -/* drivers/input/sensors/sensor-i2c.c - sensor i2c handle - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - -#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 = ® - 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; iadapter, 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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + +#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 = ® + 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; iadapter, 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); + diff --git a/drivers/input/sensors/temperature/tmp_ms5607.c b/drivers/input/sensors/temperature/tmp_ms5607.c index 015386adef5b..aea422286ba7 100755 --- a/drivers/input/sensors/temperature/tmp_ms5607.c +++ b/drivers/input/sensors/temperature/tmp_ms5607.c @@ -1,309 +1,309 @@ -/* drivers/input/sensors/temperature/tmp_ms5607.c - * - * Copyright (C) 2012-2015 ROCKCHIP. - * Author: luowei - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif -#include - - -#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 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#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); + diff --git a/include/linux/sensor-dev.h b/include/linux/sensor-dev.h index b6a48b161cf3..c5616f6d90ae 100755 --- a/include/linux/sensor-dev.h +++ b/include/linux/sensor-dev.h @@ -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 -- 2.34.1