-# sensor drivers\r
-obj-$(CONFIG_ANGLE_DEVICE) += angle/\r
-obj-$(CONFIG_GSENSOR_DEVICE) += accel/\r
-obj-$(CONFIG_COMPASS_DEVICE) += compass/\r
-obj-$(CONFIG_GYROSCOPE_DEVICE) += gyro/\r
-obj-$(CONFIG_LIGHT_DEVICE) += lsensor/\r
-obj-$(CONFIG_PROXIMITY_DEVICE) += psensor/\r
-obj-$(CONFIG_TEMPERATURE_DEVICE) += temperature/\r
-obj-$(CONFIG_PRESSURE_DEVICE) += pressure/\r
-obj-$(CONFIG_HALL_DEVICE) += hall/\r
-\r
-\r
-obj-$(CONFIG_SENSOR_DEVICE) += sensor-i2c.o\r
-obj-$(CONFIG_SENSOR_DEVICE) += sensor-dev.o\r
+# 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
-/* drivers/input/sensors/access/dmard10.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: guoyi <gy@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-/* Default register settings */\r
-#define RBUFF_SIZE 12 /* Rx buffer size */\r
-\r
-#define REG_ACTR 0x00\r
-#define REG_WDAL 0x01\r
-#define REG_TAPNS 0x0f\r
-#define REG_MISC2 0x1f\r
-#define REG_AFEM 0x0c\r
-#define REG_CKSEL 0x0d\r
-#define REG_INTC 0x0e\r
-#define REG_STADR 0x12\r
-#define REG_STAINT 0x1C\r
-#define REG_PD 0x21\r
-#define REG_TCGYZ 0x26\r
-#define REG_X_OUT 0x41\r
-\r
-#define MODE_Off 0x00\r
-#define MODE_ResetAtOff 0x01\r
-#define MODE_Standby 0x02\r
-#define MODE_ResetAtStandby 0x03\r
-#define MODE_Active 0x06\r
-#define MODE_Trigger 0x0a\r
-#define MODE_ReadOTP 0x12\r
-#define MODE_WriteOTP 0x22\r
-#define MODE_WriteOTPBuf 0x42\r
-#define MODE_ResetDataPath 0x82\r
-\r
-#define VALUE_STADR 0x55\r
-#define VALUE_STAINT 0xAA\r
-#define VALUE_AFEM_AFEN_Normal 0x8f// AFEN set 1 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1\r
-#define VALUE_AFEM_Normal 0x0f// AFEN set 0 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1\r
-#define VALUE_INTC 0x00// INTC[6:5]=b'00 \r
-#define VALUE_INTC_Interrupt_En 0x20// INTC[6:5]=b'01 (Data ready interrupt enable, active high at INT0)\r
-#define VALUE_CKSEL_ODR_0_204 0x04// ODR[3:0]=b'0000 (0.78125Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_1_204 0x14// ODR[3:0]=b'0001 (1.5625Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_3_204 0x24// ODR[3:0]=b'0010 (3.125Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_6_204 0x34// ODR[3:0]=b'0011 (6.25Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_12_204 0x44// ODR[3:0]=b'0100 (12.5Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_25_204 0x54// ODR[3:0]=b'0101 (25Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_50_204 0x64// ODR[3:0]=b'0110 (50Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_100_204 0x74// ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-\r
-#define VALUE_TAPNS_NoFilter 0x00 // TAP1/TAP2 NO FILTER\r
-#define VALUE_TAPNS_Ave_2 0x11 // TAP1/TAP2 Average 2\r
-#define VALUE_TAPNS_Ave_4 0x22 // TAP1/TAP2 Average 4\r
-#define VALUE_TAPNS_Ave_8 0x33 // TAP1/TAP2 Average 8\r
-#define VALUE_TAPNS_Ave_16 0x44 // TAP1/TAP2 Average 16\r
-#define VALUE_TAPNS_Ave_32 0x55 // TAP1/TAP2 Average 32\r
-#define VALUE_MISC2_OSCA_EN 0x08\r
-#define VALUE_PD_RST 0x52\r
-\r
-\r
-//#define DMARD10_REG_INTSU 0x47\r
-//#define DMARD10_REG_MODE 0x44\r
-//#define DMARD10_REG_SR 0x44\r
-\r
-\r
-#define DMARD10_REG_DS 0X49\r
-#define DMARD10_REG_ID 0X0F\r
-#define DMARD10_REG_IT 0X4D\r
-#define DMARD10_REG_INTSRC1_C 0X4A\r
-#define DMARD10_REG_INTSRC1_S 0X4B\r
-#define MMAIO 0xA1\r
-\r
-// IOCTLs for DMARD10 library \r
-#define ECS_IOCTL_INIT _IO(MMAIO, 0x01)\r
-#define ECS_IOCTL_RESET _IO(MMAIO, 0x04)\r
-#define ECS_IOCTL_CLOSE _IO(MMAIO, 0x02)\r
-#define ECS_IOCTL_START _IO(MMAIO, 0x03)\r
-#define ECS_IOCTL_GETDATA _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])\r
-#define SENSOR_CALIBRATION _IOWR(MMAIO, 0x05 , int[SENSOR_DATA_SIZE])\r
- \r
-// IOCTLs for APPs \r
-#define ECS_IOCTL_APP_SET_RATE _IOW(MMAIO, 0x10, char)\r
-\r
- //rate\r
-#define DMARD10_RANGE 2000000\r
-\r
-#define DMARD10_RATE_32 32\r
-/*\r
-#define DMARD10_RATE_64 64\r
-#define DMARD10_RATE_120 128\r
-#define DMARD10_RATE_MIN DMARD10_RATE_1\r
-#define DMARD10_RATE_MAX DMARD10_RATE_120\r
-*/\r
-/*status*/\r
-#define DMARD10_OPEN 1\r
-#define DMARD10_CLOSE 0\r
-#define DMARD10_NORMAL 2\r
-#define DMARD10_LOWPOWER 3\r
-\r
-\r
-\r
-#define DMARD10_IIC_ADDR 0x18 \r
-#define DMARD10_REG_LEN 11\r
-\r
-\r
-#define DMARD10_FATOR 15 \r
-\r
-\r
-#define DMARD10_X_OUT 0x41\r
-#define SENSOR_DATA_SIZE 3\r
-#define DMARD10_SENSOR_RATE_1 0\r
-#define DMARD10_SENSOR_RATE_2 1\r
-#define DMARD10_SENSOR_RATE_3 2\r
-#define DMARD10_SENSOR_RATE_4 3\r
-\r
-#define POWER_OR_RATE 1\r
-#define SW_RESET 1\r
-#define DMARD10_INTERRUPUT 1\r
-#define DMARD10_POWERDOWN 0 \r
-#define DMARD10_POWERON 1 \r
-\r
-//g-senor layout configuration, choose one of the following configuration\r
-\r
-#define AVG_NUM 16\r
-#define SENSOR_DATA_SIZE 3 \r
-#define DEFAULT_SENSITIVITY 1024\r
-\r
-\r
-\r
-#define DMARD10_ENABLE 1\r
-\r
-#define DMARD10_REG_X_OUT 0x12\r
-#define DMARD10_REG_Y_OUT 0x1\r
-#define DMARD10_REG_Z_OUT 0x2\r
-#define DMARD10_REG_TILT 0x3\r
-#define DMARD10_REG_SRST 0x4\r
-#define DMARD10_REG_SPCNT 0x5\r
-#define DMARD10_REG_INTSU 0x6\r
-#define DMARD10_REG_MODE 0x7\r
-#define DMARD10_REG_SR 0x8\r
-#define DMARD10_REG_PDET 0x9\r
-#define DMARD10_REG_PD 0xa\r
-\r
-#define DMARD10_RANGE 4000000\r
-#define DMARD10_PRECISION 10\r
-#define DMARD10_BOUNDARY (0x1 << (DMARD10_PRECISION - 1)) \r
-#define DMARD10_GRAVITY_STEP (DMARD10_RANGE / DMARD10_BOUNDARY)\r
-\r
-\r
-struct sensor_axis_average {\r
- int x_average;\r
- int y_average;\r
- int z_average;\r
- int count;\r
-};\r
-\r
-static struct sensor_axis_average axis_average;\r
-int gsensor_reset(struct i2c_client *client){\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- \r
- char buffer[7], buffer2[2];\r
- /* 1. check D10 , VALUE_STADR = 0x55 , VALUE_STAINT = 0xAA */\r
- buffer[0] = REG_STADR;\r
- buffer2[0] = REG_STAINT;\r
- \r
- sensor_rx_data(client, buffer, 2);\r
- sensor_rx_data(client, buffer2, 2);\r
- \r
- if( buffer[0] == VALUE_STADR || buffer2[0] == VALUE_STAINT){\r
- DBG(KERN_INFO " REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d\n", buffer[0], buffer2[0]);\r
- DBG(KERN_INFO " %s DMT_DEVICE_NAME registered I2C driver!\n",__FUNCTION__);\r
- }\r
- else{\r
- DBG(KERN_INFO " %s gsensor I2C err @@@ REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d \n", __func__, buffer[0], buffer2[0]);\r
- return -1;\r
- }\r
- /* 2. Powerdown reset */\r
- buffer[0] = REG_PD;\r
- buffer[1] = VALUE_PD_RST;\r
- sensor_tx_data(client, buffer, 2);\r
- /* 3. ACTR => Standby mode => Download OTP to parameter reg => Standby mode => Reset data path => Standby mode */\r
- buffer[0] = REG_ACTR;\r
- buffer[1] = MODE_Standby;\r
- buffer[2] = MODE_ReadOTP;\r
- buffer[3] = MODE_Standby;\r
- buffer[4] = MODE_ResetDataPath;\r
- buffer[5] = MODE_Standby;\r
- sensor_tx_data(client, buffer, 6);\r
- /* 4. OSCA_EN = 1 ,TSTO = b'000(INT1 = normal, TEST0 = normal) */\r
- buffer[0] = REG_MISC2;\r
- buffer[1] = VALUE_MISC2_OSCA_EN;\r
- sensor_tx_data(client, buffer, 2);\r
- /* 5. AFEN = 1(AFE will powerdown after ADC) */\r
- buffer[0] = REG_AFEM;\r
- buffer[1] = VALUE_AFEM_AFEN_Normal; \r
- buffer[2] = VALUE_CKSEL_ODR_100_204; \r
- buffer[3] = VALUE_INTC; \r
- buffer[4] = VALUE_TAPNS_Ave_2;\r
- buffer[5] = 0x00; // DLYC, no delay timing\r
- buffer[6] = 0x07; // INTD=1 (push-pull), INTA=1 (active high), AUTOT=1 (enable T)\r
- sensor_tx_data(client, buffer, 7);\r
- /* 6. write TCGYZ & TCGX */\r
- buffer[0] = REG_WDAL; // REG:0x01\r
- buffer[1] = 0x00; // set TC of Y,Z gain value\r
- buffer[2] = 0x00; // set TC of X gain value\r
- buffer[3] = 0x03; // Temperature coefficient of X,Y,Z gain\r
- sensor_tx_data(client, buffer, 4);\r
- \r
- buffer[0] = REG_ACTR; // REG:0x00\r
- buffer[1] = MODE_Standby; // Standby\r
- buffer[2] = MODE_WriteOTPBuf; // WriteOTPBuf \r
- buffer[3] = MODE_Standby; // Standby\r
- \r
- /* 7. Activation mode */\r
- buffer[0] = REG_ACTR;\r
- buffer[1] = MODE_Active;\r
- sensor_tx_data(client, buffer, 2);\r
- printk("\n dmard10 gsensor _reset SUCCESS!!\n");\r
- return 0;\r
-}\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int status = 0;\r
- gsensor_reset(client);\r
- sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- status = DMARD10_ENABLE; //dmard10\r
- sensor->ops->ctrl_data |= status; \r
- }\r
- else\r
- {\r
- status = ~DMARD10_ENABLE; //dmard10\r
- sensor->ops->ctrl_data &= status;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
- \r
- return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- DBG("%s:DMARD10_REG_TILT=0x%x\n",__func__,sensor_read_reg(client, DMARD10_REG_TILT));\r
-\r
- result = sensor_write_reg(client, DMARD10_REG_SR, (0x01<<5)| 0x02); //32 Samples/Second Active and Auto-Sleep Mode\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- if(sensor->pdata->irq_enable) //open interrupt\r
- {\r
- result = sensor_write_reg(client, DMARD10_REG_INTSU, 1<<4);//enable int,GINT=1\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- }\r
- \r
- sensor->ops->ctrl_data = 1<<6; //Interrupt output INT is push-pull\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- \r
- memset(&axis_average, 0, sizeof(struct sensor_axis_average));\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)\r
-{\r
- s64 result;\r
- \r
- \r
- result = ((int)high_byte << 8)|((int)low_byte);\r
- \r
- if (result < DMARD10_BOUNDARY){\r
- result = result* DMARD10_GRAVITY_STEP;\r
- }else{\r
- result = ~( ((~result & (0x7fff>>(16-DMARD10_PRECISION)) ) + 1)* DMARD10_GRAVITY_STEP) + 1;\r
- }\r
- \r
- return result;\r
-\r
-}\r
-\r
-static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
-\r
- /* Report acceleration sensor information */\r
- input_report_abs(sensor->input_dev, ABS_X, axis->x);\r
- input_report_abs(sensor->input_dev, ABS_Y, axis->y);\r
- input_report_abs(sensor->input_dev, ABS_Z, axis->z);\r
- input_sync(sensor->input_dev);\r
- DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);\r
-\r
- return 0;\r
-}\r
-#define DMARD10_COUNT_AVERAGE 2\r
-#define GSENSOR_MIN 2\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- struct sensor_platform_data *pdata = sensor->pdata;\r
- int ret = 0;\r
- int x,y,z;\r
- struct sensor_axis axis;\r
- char buffer[8] = {0}; \r
- char value = 0;\r
- \r
- if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 8);\r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- *buffer = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-\r
- //this gsensor need 6 bytes buffer\r
- x = sensor_convert_data(sensor->client, buffer[3], buffer[2]); //buffer[1]:high bit \r
- y = sensor_convert_data(sensor->client, buffer[5], buffer[4]);\r
- z = sensor_convert_data(sensor->client, buffer[7], buffer[6]); \r
- \r
- axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;\r
- axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z; \r
- axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;\r
-\r
- \r
- axis_average.x_average += axis.x;\r
- axis_average.y_average += axis.y;\r
- axis_average.z_average += axis.z;\r
- axis_average.count++;\r
- \r
- if(axis_average.count >= DMARD10_COUNT_AVERAGE)\r
- {\r
- axis.x = axis_average.x_average / axis_average.count; \r
- axis.y = axis_average.y_average / axis_average.count; \r
- axis.z = axis_average.z_average / axis_average.count;\r
- \r
- DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);\r
- \r
- memset(&axis_average, 0, sizeof(struct sensor_axis_average));\r
- \r
- //Report event only while value is changed to save some power\r
- 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))\r
- {\r
- gsensor_report_value(client, &axis);\r
-\r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&(sensor->data_mutex) );\r
- sensor->axis = axis;\r
- mutex_unlock(&(sensor->data_mutex) );\r
- }\r
- }\r
- \r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- DBG("%s:sensor int status :0x%x\n",__func__,value);\r
- }\r
- \r
- return ret;\r
-}\r
-\r
-\r
-struct sensor_operate gsensor_dmard10_ops = {\r
- .name = "gs_dmard10",\r
- .type = SENSOR_TYPE_ACCEL, //sensor type and it should be correct\r
- .id_i2c = ACCEL_ID_DMARD10, //i2c id number\r
- .read_reg = DMARD10_REG_X_OUT, //read data\r
- .read_len = 8, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = DMARD10_PRECISION, //12 bit\r
- .ctrl_reg = DMARD10_REG_MODE, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
- .range = {-DMARD10_RANGE,DMARD10_RANGE}, //range\r
- .trig = IRQF_TRIGGER_LOW|IRQF_ONESHOT, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *gsensor_get_ops(void)\r
-{\r
- return &gsensor_dmard10_ops;\r
-}\r
-\r
-\r
-static int __init gsensor_dmard10_init(void)\r
-{\r
- struct sensor_operate *ops = gsensor_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops); \r
- return result;\r
-}\r
-\r
-static void __exit gsensor_dmard10_exit(void)\r
-{\r
- struct sensor_operate *ops = gsensor_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);\r
-}\r
-\r
-\r
-module_init(gsensor_dmard10_init);\r
-module_exit(gsensor_dmard10_exit);\r
-\r
-\r
-\r
+/* drivers/input/sensors/access/dmard10.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: guoyi <gy@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+/* Default register settings */
+#define RBUFF_SIZE 12 /* Rx buffer size */
+
+#define REG_ACTR 0x00
+#define REG_WDAL 0x01
+#define REG_TAPNS 0x0f
+#define REG_MISC2 0x1f
+#define REG_AFEM 0x0c
+#define REG_CKSEL 0x0d
+#define REG_INTC 0x0e
+#define REG_STADR 0x12
+#define REG_STAINT 0x1C
+#define REG_PD 0x21
+#define REG_TCGYZ 0x26
+#define REG_X_OUT 0x41
+
+#define MODE_Off 0x00
+#define MODE_ResetAtOff 0x01
+#define MODE_Standby 0x02
+#define MODE_ResetAtStandby 0x03
+#define MODE_Active 0x06
+#define MODE_Trigger 0x0a
+#define MODE_ReadOTP 0x12
+#define MODE_WriteOTP 0x22
+#define MODE_WriteOTPBuf 0x42
+#define MODE_ResetDataPath 0x82
+
+#define VALUE_STADR 0x55
+#define VALUE_STAINT 0xAA
+#define VALUE_AFEM_AFEN_Normal 0x8f// AFEN set 1 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
+#define VALUE_AFEM_Normal 0x0f// AFEN set 0 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
+#define VALUE_INTC 0x00// INTC[6:5]=b'00
+#define VALUE_INTC_Interrupt_En 0x20// INTC[6:5]=b'01 (Data ready interrupt enable, active high at INT0)
+#define VALUE_CKSEL_ODR_0_204 0x04// ODR[3:0]=b'0000 (0.78125Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_1_204 0x14// ODR[3:0]=b'0001 (1.5625Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_3_204 0x24// ODR[3:0]=b'0010 (3.125Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_6_204 0x34// ODR[3:0]=b'0011 (6.25Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_12_204 0x44// ODR[3:0]=b'0100 (12.5Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_25_204 0x54// ODR[3:0]=b'0101 (25Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_50_204 0x64// ODR[3:0]=b'0110 (50Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_100_204 0x74// ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ)
+
+#define VALUE_TAPNS_NoFilter 0x00 // TAP1/TAP2 NO FILTER
+#define VALUE_TAPNS_Ave_2 0x11 // TAP1/TAP2 Average 2
+#define VALUE_TAPNS_Ave_4 0x22 // TAP1/TAP2 Average 4
+#define VALUE_TAPNS_Ave_8 0x33 // TAP1/TAP2 Average 8
+#define VALUE_TAPNS_Ave_16 0x44 // TAP1/TAP2 Average 16
+#define VALUE_TAPNS_Ave_32 0x55 // TAP1/TAP2 Average 32
+#define VALUE_MISC2_OSCA_EN 0x08
+#define VALUE_PD_RST 0x52
+
+
+//#define DMARD10_REG_INTSU 0x47
+//#define DMARD10_REG_MODE 0x44
+//#define DMARD10_REG_SR 0x44
+
+
+#define DMARD10_REG_DS 0X49
+#define DMARD10_REG_ID 0X0F
+#define DMARD10_REG_IT 0X4D
+#define DMARD10_REG_INTSRC1_C 0X4A
+#define DMARD10_REG_INTSRC1_S 0X4B
+#define MMAIO 0xA1
+
+// IOCTLs for DMARD10 library
+#define ECS_IOCTL_INIT _IO(MMAIO, 0x01)
+#define ECS_IOCTL_RESET _IO(MMAIO, 0x04)
+#define ECS_IOCTL_CLOSE _IO(MMAIO, 0x02)
+#define ECS_IOCTL_START _IO(MMAIO, 0x03)
+#define ECS_IOCTL_GETDATA _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])
+#define SENSOR_CALIBRATION _IOWR(MMAIO, 0x05 , int[SENSOR_DATA_SIZE])
+
+// IOCTLs for APPs
+#define ECS_IOCTL_APP_SET_RATE _IOW(MMAIO, 0x10, char)
+
+ //rate
+#define DMARD10_RANGE 2000000
+
+#define DMARD10_RATE_32 32
+/*
+#define DMARD10_RATE_64 64
+#define DMARD10_RATE_120 128
+#define DMARD10_RATE_MIN DMARD10_RATE_1
+#define DMARD10_RATE_MAX DMARD10_RATE_120
+*/
+/*status*/
+#define DMARD10_OPEN 1
+#define DMARD10_CLOSE 0
+#define DMARD10_NORMAL 2
+#define DMARD10_LOWPOWER 3
+
+
+
+#define DMARD10_IIC_ADDR 0x18
+#define DMARD10_REG_LEN 11
+
+
+#define DMARD10_FATOR 15
+
+
+#define DMARD10_X_OUT 0x41
+#define SENSOR_DATA_SIZE 3
+#define DMARD10_SENSOR_RATE_1 0
+#define DMARD10_SENSOR_RATE_2 1
+#define DMARD10_SENSOR_RATE_3 2
+#define DMARD10_SENSOR_RATE_4 3
+
+#define POWER_OR_RATE 1
+#define SW_RESET 1
+#define DMARD10_INTERRUPUT 1
+#define DMARD10_POWERDOWN 0
+#define DMARD10_POWERON 1
+
+//g-senor layout configuration, choose one of the following configuration
+
+#define AVG_NUM 16
+#define SENSOR_DATA_SIZE 3
+#define DEFAULT_SENSITIVITY 1024
+
+
+
+#define DMARD10_ENABLE 1
+
+#define DMARD10_REG_X_OUT 0x12
+#define DMARD10_REG_Y_OUT 0x1
+#define DMARD10_REG_Z_OUT 0x2
+#define DMARD10_REG_TILT 0x3
+#define DMARD10_REG_SRST 0x4
+#define DMARD10_REG_SPCNT 0x5
+#define DMARD10_REG_INTSU 0x6
+#define DMARD10_REG_MODE 0x7
+#define DMARD10_REG_SR 0x8
+#define DMARD10_REG_PDET 0x9
+#define DMARD10_REG_PD 0xa
+
+#define DMARD10_RANGE 4000000
+#define DMARD10_PRECISION 10
+#define DMARD10_BOUNDARY (0x1 << (DMARD10_PRECISION - 1))
+#define DMARD10_GRAVITY_STEP (DMARD10_RANGE / DMARD10_BOUNDARY)
+
+
+struct sensor_axis_average {
+ int x_average;
+ int y_average;
+ int z_average;
+ int count;
+};
+
+static struct sensor_axis_average axis_average;
+int gsensor_reset(struct i2c_client *client){
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+
+ char buffer[7], buffer2[2];
+ /* 1. check D10 , VALUE_STADR = 0x55 , VALUE_STAINT = 0xAA */
+ buffer[0] = REG_STADR;
+ buffer2[0] = REG_STAINT;
+
+ sensor_rx_data(client, buffer, 2);
+ sensor_rx_data(client, buffer2, 2);
+
+ if( buffer[0] == VALUE_STADR || buffer2[0] == VALUE_STAINT){
+ DBG(KERN_INFO " REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d\n", buffer[0], buffer2[0]);
+ DBG(KERN_INFO " %s DMT_DEVICE_NAME registered I2C driver!\n",__FUNCTION__);
+ }
+ else{
+ DBG(KERN_INFO " %s gsensor I2C err @@@ REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d \n", __func__, buffer[0], buffer2[0]);
+ return -1;
+ }
+ /* 2. Powerdown reset */
+ buffer[0] = REG_PD;
+ buffer[1] = VALUE_PD_RST;
+ sensor_tx_data(client, buffer, 2);
+ /* 3. ACTR => Standby mode => Download OTP to parameter reg => Standby mode => Reset data path => Standby mode */
+ buffer[0] = REG_ACTR;
+ buffer[1] = MODE_Standby;
+ buffer[2] = MODE_ReadOTP;
+ buffer[3] = MODE_Standby;
+ buffer[4] = MODE_ResetDataPath;
+ buffer[5] = MODE_Standby;
+ sensor_tx_data(client, buffer, 6);
+ /* 4. OSCA_EN = 1 ,TSTO = b'000(INT1 = normal, TEST0 = normal) */
+ buffer[0] = REG_MISC2;
+ buffer[1] = VALUE_MISC2_OSCA_EN;
+ sensor_tx_data(client, buffer, 2);
+ /* 5. AFEN = 1(AFE will powerdown after ADC) */
+ buffer[0] = REG_AFEM;
+ buffer[1] = VALUE_AFEM_AFEN_Normal;
+ buffer[2] = VALUE_CKSEL_ODR_100_204;
+ buffer[3] = VALUE_INTC;
+ buffer[4] = VALUE_TAPNS_Ave_2;
+ buffer[5] = 0x00; // DLYC, no delay timing
+ buffer[6] = 0x07; // INTD=1 (push-pull), INTA=1 (active high), AUTOT=1 (enable T)
+ sensor_tx_data(client, buffer, 7);
+ /* 6. write TCGYZ & TCGX */
+ buffer[0] = REG_WDAL; // REG:0x01
+ buffer[1] = 0x00; // set TC of Y,Z gain value
+ buffer[2] = 0x00; // set TC of X gain value
+ buffer[3] = 0x03; // Temperature coefficient of X,Y,Z gain
+ sensor_tx_data(client, buffer, 4);
+
+ buffer[0] = REG_ACTR; // REG:0x00
+ buffer[1] = MODE_Standby; // Standby
+ buffer[2] = MODE_WriteOTPBuf; // WriteOTPBuf
+ buffer[3] = MODE_Standby; // Standby
+
+ /* 7. Activation mode */
+ buffer[0] = REG_ACTR;
+ buffer[1] = MODE_Active;
+ sensor_tx_data(client, buffer, 2);
+ printk("\n dmard10 gsensor _reset SUCCESS!!\n");
+ return 0;
+}
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int status = 0;
+ gsensor_reset(client);
+ sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+ //register setting according to chip datasheet
+ if(enable)
+ {
+ status = DMARD10_ENABLE; //dmard10
+ sensor->ops->ctrl_data |= status;
+ }
+ else
+ {
+ status = ~DMARD10_ENABLE; //dmard10
+ sensor->ops->ctrl_data &= status;
+ }
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ return result;
+
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ DBG("%s:DMARD10_REG_TILT=0x%x\n",__func__,sensor_read_reg(client, DMARD10_REG_TILT));
+
+ result = sensor_write_reg(client, DMARD10_REG_SR, (0x01<<5)| 0x02); //32 Samples/Second Active and Auto-Sleep Mode
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ if(sensor->pdata->irq_enable) //open interrupt
+ {
+ result = sensor_write_reg(client, DMARD10_REG_INTSU, 1<<4);//enable int,GINT=1
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+ }
+
+ sensor->ops->ctrl_data = 1<<6; //Interrupt output INT is push-pull
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+
+ memset(&axis_average, 0, sizeof(struct sensor_axis_average));
+
+ return result;
+}
+
+
+static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
+{
+ s64 result;
+
+
+ result = ((int)high_byte << 8)|((int)low_byte);
+
+ if (result < DMARD10_BOUNDARY){
+ result = result* DMARD10_GRAVITY_STEP;
+ }else{
+ result = ~( ((~result & (0x7fff>>(16-DMARD10_PRECISION)) ) + 1)* DMARD10_GRAVITY_STEP) + 1;
+ }
+
+ return result;
+
+}
+
+static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+
+ /* Report acceleration sensor information */
+ input_report_abs(sensor->input_dev, ABS_X, axis->x);
+ input_report_abs(sensor->input_dev, ABS_Y, axis->y);
+ input_report_abs(sensor->input_dev, ABS_Z, axis->z);
+ input_sync(sensor->input_dev);
+ DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
+
+ return 0;
+}
+#define DMARD10_COUNT_AVERAGE 2
+#define GSENSOR_MIN 2
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ struct sensor_platform_data *pdata = sensor->pdata;
+ int ret = 0;
+ int x,y,z;
+ struct sensor_axis axis;
+ char buffer[8] = {0};
+ char value = 0;
+
+ if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
+ {
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+ return -1;
+ }
+
+ memset(buffer, 0, 8);
+ /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+ do {
+ *buffer = sensor->ops->read_reg;
+ ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+ if (ret < 0)
+ return ret;
+ } while (0);
+
+ //this gsensor need 6 bytes buffer
+ x = sensor_convert_data(sensor->client, buffer[3], buffer[2]); //buffer[1]:high bit
+ y = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
+ z = sensor_convert_data(sensor->client, buffer[7], buffer[6]);
+
+ axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
+ axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
+ axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
+
+
+ axis_average.x_average += axis.x;
+ axis_average.y_average += axis.y;
+ axis_average.z_average += axis.z;
+ axis_average.count++;
+
+ if(axis_average.count >= DMARD10_COUNT_AVERAGE)
+ {
+ axis.x = axis_average.x_average / axis_average.count;
+ axis.y = axis_average.y_average / axis_average.count;
+ axis.z = axis_average.z_average / axis_average.count;
+
+ DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
+
+ memset(&axis_average, 0, sizeof(struct sensor_axis_average));
+
+ //Report event only while value is changed to save some power
+ if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
+ {
+ gsensor_report_value(client, &axis);
+
+ /* »¥³âµØ»º´æÊý¾Ý. */
+ 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/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: Bruins <xwj@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define LSM303D_WHO_AM_I (0x0F)\r
-\r
-/* full scale setting - register & mask */\r
-#define LSM303D_CTRL_REG0 (0x1F)\r
-#define LSM303D_CTRL_REG1 (0x20)\r
-#define LSM303D_CTRL_REG2 (0x21)\r
-#define LSM303D_CTRL_REG3 (0x22)\r
-#define LSM303D_CTRL_REG4 (0x23)\r
-#define LSM303D_CTRL_REG5 (0x24)\r
-#define LSM303D_CTRL_REG6 (0x25)\r
-#define LSM303D_CTRL_REG7 (0x26)\r
-#define LSM303D_STATUS_REG (0x27)\r
-#define LSM303D_OUT_X_L (0x28)\r
-#define LSM303D_OUT_X_H (0x29)\r
-#define LSM303D_OUT_Y_L (0x2a)\r
-#define LSM303D_OUT_Y_H (0x2b)\r
-#define LSM303D_OUT_Z_L (0x2c)\r
-#define LSM303D_OUT_Z_H (0x2d)\r
-#define LSM303D_FIFO_CTRL_REG (0x2E)\r
-#define LSM303D_FIFO_SRC_REG (0X2F)\r
-\r
-#define LSM303D_IG_CFG1 (0x30)\r
-#define LSM303D_IG_SRC1 (0x31)\r
-#define LSM303D_IG_THS1 (0x32)\r
-#define LSM303D_IG_DURATION1 (0x33)\r
-\r
-#define LSM303D_IG_CFG2 (0x34)\r
-#define LSM303D_IG_SRC2 (0x35)\r
-#define LSM303D_IG_THS2 (0x36)\r
-#define LSM303D_IG_DURATION2 (0x37)\r
-\r
-\r
-#define LSM303D_DEVID (0x49) //chip id\r
-#define LSM303D_ACC_DISABLE (0x08)\r
-\r
-#define LSM303D_RANGE 2000000\r
-\r
-/* LSM303D */\r
-#define LSM303D_PRECISION 16\r
-#define LSM303D_BOUNDARY (0x1 << (LSM303D_PRECISION - 1))\r
-#define LSM303D_GRAVITY_STEP (LSM303D_RANGE / LSM303D_BOUNDARY)\r
-\r
-#define ODR3P25 0x10 /* 3.25Hz output data rate */\r
-#define ODR6P25 0x20 /* 6.25Hz output data rate */\r
-#define ODR12P5 0x30 /* 12.5Hz output data rate */\r
-#define ODR25 0x40 /* 25Hz output data rate */\r
-#define ODR50 0x50 /* 50Hz output data rate */\r
-#define ODR100 0x60 /* 100Hz output data rate */\r
-#define ODR200 0x70 /* 200Hz output data rate */\r
-#define ODR400 0x80 /* 400Hz output data rate */\r
-#define ODR800 0x90 /* 800Hz output data rate */\r
-#define ODR1600 0xA0 /* 1600Hz output data rate */\r
-\r
-\r
-struct sensor_reg_data {\r
- char reg;\r
- char data;\r
-};\r
-\r
-/****************operate according to sensor chip:start************/\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int status = 0;\r
- \r
- sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-\r
- sensor->ops->ctrl_data |= ODR100; //100HZ,if 0 then power down\r
- \r
- //register setting according to chip datasheet \r
- if(!enable)\r
- { \r
- status = LSM303D_ACC_DISABLE; //lis3dh \r
- sensor->ops->ctrl_data |= status; \r
- }\r
- else\r
- {\r
- status = ~LSM303D_ACC_DISABLE; //lis3dh\r
- sensor->ops->ctrl_data &= status;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
- \r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int i;\r
-\r
- struct sensor_reg_data reg_data[] = \r
- {\r
- {LSM303D_CTRL_REG0,0x00},\r
- {LSM303D_CTRL_REG1,0x07},\r
- {LSM303D_CTRL_REG2,0x00},\r
- {LSM303D_CTRL_REG3,0x00},\r
- {LSM303D_CTRL_REG4,0x00},\r
- {LSM303D_CTRL_REG5,0x78}, //High resolution output mode:11,\r
- {LSM303D_CTRL_REG6,0x20},\r
- {LSM303D_CTRL_REG7,0x00},\r
- {LSM303D_FIFO_CTRL_REG,0x00},\r
- {LSM303D_IG_CFG1,0xFF}, //6 direction position recognition \r
- {LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold \r
- {LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f\r
- \r
- /*\r
- {LSM303D_CTRL_REG7,0x00}, \r
- {LSM303D_CTRL_REG4,0x08}, //High resolution output mode: 1, Normal mode \r
- {LSM303D_CTRL_REG6,0x40}, \r
- \r
- {LSM303D_FIFO_CTRL_REG,0x00}, // \r
- {LSM303D_IG_CFG1,0xFF}, //6 direction position recognition \r
- {LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold \r
- {LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f\r
- */\r
- }; \r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- sensor->status_cur = SENSOR_OFF;\r
- \r
- for(i=0;i<(sizeof(reg_data)/sizeof(struct sensor_reg_data));i++)\r
- {\r
- result = sensor_write_reg(client, reg_data[i].reg, reg_data[i].data);\r
- if(result)\r
- {\r
- printk("%s:line=%d,i=%d,error\n",__func__,__LINE__,i);\r
- return result;\r
- }\r
- }\r
-\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
-\r
- result = sensor_write_reg(client, LSM303D_CTRL_REG3, 0x20); \r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- i = sensor_read_reg(client,LSM303D_CTRL_REG5);\r
- \r
- result = sensor_write_reg(client, LSM303D_CTRL_REG5, (i|0x01));\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)\r
-{\r
- s64 result;\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- \r
- switch (sensor->devid) { \r
- case LSM303D_DEVID: \r
- result = ((int)high_byte << 8) | (int)low_byte;\r
- if (result < LSM303D_BOUNDARY)\r
- result = result* LSM303D_GRAVITY_STEP;\r
- else\r
- result = ~( ((~result & (0x7fff>>(16-LSM303D_PRECISION)) ) + 1) \r
- * LSM303D_GRAVITY_STEP) + 1;\r
- break;\r
-\r
- default:\r
- printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);\r
- return -EFAULT;\r
- }\r
-\r
- return (int)result;\r
-}\r
-\r
-static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
-\r
- /* Report acceleration sensor information */\r
- input_report_abs(sensor->input_dev, ABS_X, axis->x);\r
- input_report_abs(sensor->input_dev, ABS_Y, axis->y);\r
- input_report_abs(sensor->input_dev, ABS_Z, axis->z);\r
- input_sync(sensor->input_dev);\r
- DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);\r
-\r
- return 0;\r
-}\r
-\r
-#define GSENSOR_MIN 10\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- struct sensor_platform_data *pdata = sensor->pdata;\r
- int ret = 0;\r
- int x,y,z;\r
- struct sensor_axis axis; \r
- char buffer[6] = {0}; \r
- char value = 0;\r
- \r
- if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 6);\r
-\r
- value = sensor_read_reg(client, LSM303D_STATUS_REG);\r
- if((value & 0x0f) == 0)\r
- {\r
- printk("%s:line=%d,value=0x%x,data is not ready\n",__func__,__LINE__,value);\r
- return -1;\r
- }\r
- \r
- \r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- *buffer = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-\r
- //this gsensor need 6 bytes buffer\r
- x = sensor_convert_data(sensor->client, buffer[1], buffer[0]); //buffer[1]:high bit \r
- y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);\r
- z = sensor_convert_data(sensor->client, buffer[5], buffer[4]); \r
-\r
- axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;\r
- axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z; \r
- axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;\r
-\r
- DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);\r
- //printk( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);\r
-\r
- //Report event only while value is changed to save some power\r
- 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))\r
- {\r
- gsensor_report_value(client, &axis);\r
-\r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&(sensor->data_mutex) );\r
- sensor->axis = axis;\r
- mutex_unlock(&(sensor->data_mutex) );\r
- }\r
-\r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- DBG("%s:sensor int status :0x%x\n",__func__,value);\r
- }\r
- \r
- return ret;\r
-}\r
-\r
-struct sensor_operate gsensor_lsm303d_ops = {\r
- .name = "lsm303d",\r
- .type = SENSOR_TYPE_ACCEL, //sensor type and it should be correct\r
- .id_i2c = ACCEL_ID_LSM303D, //i2c id number\r
- .read_reg = (LSM303D_OUT_X_L | 0x80), //read data\r
- .read_len = 6, //data length\r
- .id_reg = LSM303D_WHO_AM_I, //read device id from this register\r
- .id_data = LSM303D_DEVID, //device id\r
- .precision = LSM303D_PRECISION, //16 bits\r
- .ctrl_reg = LSM303D_CTRL_REG1, //enable or disable \r
- .int_status_reg = LSM303D_IG_SRC1, //intterupt status register\r
- .range = {-LSM303D_RANGE,LSM303D_RANGE}, //range\r
- .trig = (IRQF_TRIGGER_LOW|IRQF_ONESHOT), \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *gsensor_get_ops(void)\r
-{\r
- return &gsensor_lsm303d_ops;\r
-}\r
-\r
-\r
-static int __init gsensor_lis3dh_init(void)\r
-{\r
- struct sensor_operate *ops = gsensor_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit gsensor_lis3dh_exit(void)\r
-{\r
- struct sensor_operate *ops = gsensor_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);\r
-}\r
-\r
-\r
-module_init(gsensor_lis3dh_init);\r
-module_exit(gsensor_lis3dh_exit);\r
-\r
-\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: Bruins <xwj@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define LSM303D_WHO_AM_I (0x0F)
+
+/* full scale setting - register & mask */
+#define LSM303D_CTRL_REG0 (0x1F)
+#define LSM303D_CTRL_REG1 (0x20)
+#define LSM303D_CTRL_REG2 (0x21)
+#define LSM303D_CTRL_REG3 (0x22)
+#define LSM303D_CTRL_REG4 (0x23)
+#define LSM303D_CTRL_REG5 (0x24)
+#define LSM303D_CTRL_REG6 (0x25)
+#define LSM303D_CTRL_REG7 (0x26)
+#define LSM303D_STATUS_REG (0x27)
+#define LSM303D_OUT_X_L (0x28)
+#define LSM303D_OUT_X_H (0x29)
+#define LSM303D_OUT_Y_L (0x2a)
+#define LSM303D_OUT_Y_H (0x2b)
+#define LSM303D_OUT_Z_L (0x2c)
+#define LSM303D_OUT_Z_H (0x2d)
+#define LSM303D_FIFO_CTRL_REG (0x2E)
+#define LSM303D_FIFO_SRC_REG (0X2F)
+
+#define LSM303D_IG_CFG1 (0x30)
+#define LSM303D_IG_SRC1 (0x31)
+#define LSM303D_IG_THS1 (0x32)
+#define LSM303D_IG_DURATION1 (0x33)
+
+#define LSM303D_IG_CFG2 (0x34)
+#define LSM303D_IG_SRC2 (0x35)
+#define LSM303D_IG_THS2 (0x36)
+#define LSM303D_IG_DURATION2 (0x37)
+
+
+#define LSM303D_DEVID (0x49) //chip id
+#define LSM303D_ACC_DISABLE (0x08)
+
+#define LSM303D_RANGE 2000000
+
+/* LSM303D */
+#define LSM303D_PRECISION 16
+#define LSM303D_BOUNDARY (0x1 << (LSM303D_PRECISION - 1))
+#define LSM303D_GRAVITY_STEP (LSM303D_RANGE / LSM303D_BOUNDARY)
+
+#define ODR3P25 0x10 /* 3.25Hz output data rate */
+#define ODR6P25 0x20 /* 6.25Hz output data rate */
+#define ODR12P5 0x30 /* 12.5Hz output data rate */
+#define ODR25 0x40 /* 25Hz output data rate */
+#define ODR50 0x50 /* 50Hz output data rate */
+#define ODR100 0x60 /* 100Hz output data rate */
+#define ODR200 0x70 /* 200Hz output data rate */
+#define ODR400 0x80 /* 400Hz output data rate */
+#define ODR800 0x90 /* 800Hz output data rate */
+#define ODR1600 0xA0 /* 1600Hz output data rate */
+
+
+struct sensor_reg_data {
+ char reg;
+ char data;
+};
+
+/****************operate according to sensor chip:start************/
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int status = 0;
+
+ sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ sensor->ops->ctrl_data |= ODR100; //100HZ,if 0 then power down
+
+ //register setting according to chip datasheet
+ if(!enable)
+ {
+ status = LSM303D_ACC_DISABLE; //lis3dh
+ sensor->ops->ctrl_data |= status;
+ }
+ else
+ {
+ status = ~LSM303D_ACC_DISABLE; //lis3dh
+ sensor->ops->ctrl_data &= status;
+ }
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int i;
+
+ struct sensor_reg_data reg_data[] =
+ {
+ {LSM303D_CTRL_REG0,0x00},
+ {LSM303D_CTRL_REG1,0x07},
+ {LSM303D_CTRL_REG2,0x00},
+ {LSM303D_CTRL_REG3,0x00},
+ {LSM303D_CTRL_REG4,0x00},
+ {LSM303D_CTRL_REG5,0x78}, //High resolution output mode:11,
+ {LSM303D_CTRL_REG6,0x20},
+ {LSM303D_CTRL_REG7,0x00},
+ {LSM303D_FIFO_CTRL_REG,0x00},
+ {LSM303D_IG_CFG1,0xFF}, //6 direction position recognition
+ {LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold
+ {LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f
+
+ /*
+ {LSM303D_CTRL_REG7,0x00},
+ {LSM303D_CTRL_REG4,0x08}, //High resolution output mode: 1, Normal mode
+ {LSM303D_CTRL_REG6,0x40},
+
+ {LSM303D_FIFO_CTRL_REG,0x00}, //
+ {LSM303D_IG_CFG1,0xFF}, //6 direction position recognition
+ {LSM303D_IG_THS1,0x7F}, //Interrupt 1 threshold
+ {LSM303D_IG_DURATION1,0x7F}, //Duration value 0x00->ox7f
+ */
+ };
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ for(i=0;i<(sizeof(reg_data)/sizeof(struct sensor_reg_data));i++)
+ {
+ result = sensor_write_reg(client, reg_data[i].reg, reg_data[i].data);
+ if(result)
+ {
+ printk("%s:line=%d,i=%d,error\n",__func__,__LINE__,i);
+ return result;
+ }
+ }
+
+
+ if(sensor->pdata->irq_enable)
+ {
+
+ result = sensor_write_reg(client, LSM303D_CTRL_REG3, 0x20);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ i = sensor_read_reg(client,LSM303D_CTRL_REG5);
+
+ result = sensor_write_reg(client, LSM303D_CTRL_REG5, (i|0x01));
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ }
+
+ return result;
+}
+
+
+static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
+{
+ s64 result;
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+
+ switch (sensor->devid) {
+ case LSM303D_DEVID:
+ result = ((int)high_byte << 8) | (int)low_byte;
+ if (result < LSM303D_BOUNDARY)
+ result = result* LSM303D_GRAVITY_STEP;
+ else
+ result = ~( ((~result & (0x7fff>>(16-LSM303D_PRECISION)) ) + 1)
+ * LSM303D_GRAVITY_STEP) + 1;
+ break;
+
+ default:
+ printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);
+ return -EFAULT;
+ }
+
+ return (int)result;
+}
+
+static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+
+ /* Report acceleration sensor information */
+ input_report_abs(sensor->input_dev, ABS_X, axis->x);
+ input_report_abs(sensor->input_dev, ABS_Y, axis->y);
+ input_report_abs(sensor->input_dev, ABS_Z, axis->z);
+ input_sync(sensor->input_dev);
+ DBG("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);
+
+ return 0;
+}
+
+#define GSENSOR_MIN 10
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ struct sensor_platform_data *pdata = sensor->pdata;
+ int ret = 0;
+ int x,y,z;
+ struct sensor_axis axis;
+ char buffer[6] = {0};
+ char value = 0;
+
+ if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6
+ {
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+ return -1;
+ }
+
+ memset(buffer, 0, 6);
+
+ value = sensor_read_reg(client, LSM303D_STATUS_REG);
+ if((value & 0x0f) == 0)
+ {
+ printk("%s:line=%d,value=0x%x,data is not ready\n",__func__,__LINE__,value);
+ return -1;
+ }
+
+
+ /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+ do {
+ *buffer = sensor->ops->read_reg;
+ ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+ if (ret < 0)
+ return ret;
+ } while (0);
+
+ //this gsensor need 6 bytes buffer
+ x = sensor_convert_data(sensor->client, buffer[1], buffer[0]); //buffer[1]:high bit
+ y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);
+ z = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
+
+ axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
+ axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
+ axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
+
+ DBG( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
+ //printk( "%s: axis = %d %d %d \n", __func__, axis.x, axis.y, axis.z);
+
+ //Report event only while value is changed to save some power
+ if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
+ {
+ gsensor_report_value(client, &axis);
+
+ /* »¥³âµØ»º´æÊý¾Ý. */
+ 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);
+
+
+
+
-obj-$(CONFIG_ANGLE_KXTIK) += angle_kxtik.o\r
-obj-$(CONFIG_ANGLE_LIS3DH) += angle_lis3dh.o\r
+obj-$(CONFIG_ANGLE_KXTIK) += angle_kxtik.o
+obj-$(CONFIG_ANGLE_LIS3DH) += angle_lis3dh.o
-/* drivers/input/sensors/access/akm09911.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-\r
-#define SENSOR_DATA_SIZE 9\r
-#define YPR_DATA_SIZE 16\r
-#define RWBUF_SIZE 16\r
-\r
-#define ACC_DATA_FLAG 0\r
-#define MAG_DATA_FLAG 1\r
-#define ORI_DATA_FLAG 2\r
-#define AKM_NUM_SENSORS 3\r
-\r
-#define ACC_DATA_READY (1<<(ACC_DATA_FLAG))\r
-#define MAG_DATA_READY (1<<(MAG_DATA_FLAG))\r
-#define ORI_DATA_READY (1<<(ORI_DATA_FLAG))\r
-\r
-/*Constant definitions of the AK09911.*/\r
-#define AK09911_MEASUREMENT_TIME_US 10000\r
-\r
-#define AK09911_MODE_SNG_MEASURE 0x01\r
-#define AK09911_MODE_SELF_TEST 0x10\r
-#define AK09911_MODE_FUSE_ACCESS 0x1F\r
-#define AK09911_MODE_POWERDOWN 0x00\r
-#define AK09911_RESET_DATA 0x01\r
-\r
-\r
-/* Device specific constant values */\r
-#define AK09911_REG_WIA1 0x00\r
-#define AK09911_REG_WIA2 0x01\r
-#define AK09911_REG_INFO1 0x02\r
-#define AK09911_REG_INFO2 0x03\r
-#define AK09911_REG_ST1 0x10\r
-#define AK09911_REG_HXL 0x11\r
-#define AK09911_REG_HXH 0x12\r
-#define AK09911_REG_HYL 0x13\r
-#define AK09911_REG_HYH 0x14\r
-#define AK09911_REG_HZL 0x15\r
-#define AK09911_REG_HZH 0x16\r
-#define AK09911_REG_TMPS 0x17\r
-#define AK09911_REG_ST2 0x18\r
-#define AK09911_REG_CNTL1 0x30\r
-#define AK09911_REG_CNTL2 0x31\r
-#define AK09911_REG_CNTL3 0x32\r
-\r
-\r
-#define AK09911_FUSE_ASAX 0x60\r
-#define AK09911_FUSE_ASAY 0x61\r
-#define AK09911_FUSE_ASAZ 0x62\r
-\r
-#define AK09911_INFO_SIZE 2\r
-#define AK09911_CONF_SIZE 3\r
-\r
-\r
-\r
-#define COMPASS_IOCTL_MAGIC 'c'\r
-\r
-/* IOCTLs for AKM library */\r
-#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)\r
-#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)\r
-#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */\r
-#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)\r
-#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8])\r
-#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])\r
-#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)\r
-#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)\r
-#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)\r
-#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])\r
-#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)\r
-#define ECS_IOCTL_GET_INFO _IOR(COMPASS_IOCTL_MAGIC, 0x0C, short)\r
-#define ECS_IOCTL_GET_CONF _IOR(COMPASS_IOCTL_MAGIC, 0x0D, short)\r
-#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)\r
-#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)\r
-\r
-\r
-\r
-#define AK09911_DEVICE_ID 0x05\r
-static struct i2c_client *this_client;\r
-static struct miscdevice compass_dev_device;\r
-\r
-static short g_akm_rbuf[12];\r
-static char g_sensor_info[AK09911_INFO_SIZE];\r
-static char g_sensor_conf[AK09911_CONF_SIZE];\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE; \r
- }\r
- else\r
- {\r
- sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
- \r
- return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
-\r
- this_client = client; \r
-\r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- result = misc_register(&compass_dev_device);\r
- if (result < 0) {\r
- printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
- result = -1;\r
- }\r
-\r
- g_sensor_info[0] = AK09911_REG_WIA1;\r
- result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- \r
- g_sensor_conf[0] = AK09911_FUSE_ASAX;\r
- result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
- return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- char buffer[SENSOR_DATA_SIZE] = {0}; \r
- unsigned char *stat;\r
- unsigned char *stat2; \r
- int ret = 0; \r
- char value = 0;\r
- int i;\r
-\r
- if(sensor->ops->read_len < SENSOR_DATA_SIZE) //sensor->ops->read_len = 8\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, SENSOR_DATA_SIZE);\r
- \r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- *buffer = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-\r
- stat = &buffer[0];\r
- stat2 = &buffer[7];\r
- \r
- /*\r
+/* drivers/input/sensors/access/akm09911.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+
+#define 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.
- */\r
- if ((*stat & 0x01) != 0x01) {\r
- DBG(KERN_ERR "%s:ST is not set\n",__func__);\r
- return -1;\r
- }\r
-#if 0\r
+ */
+ 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;
* corrupted.
* DERR bit is self-clearing when ST2 register is read.
*/
- if (*stat2 & 0x04)\r
- {\r
- DBG(KERN_ERR "%s:compass data error\n",__func__);\r
- return -2;\r
- }\r
- \r
+ 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.
* An error is returned.
* HOFL bit clears when a new measurement starts.
*/
- if (*stat2 & 0x08)\r
- { \r
- DBG(KERN_ERR "%s:compass data overflow\n",__func__);\r
- return -3;\r
- }\r
-#endif\r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&sensor->data_mutex); \r
- memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
- mutex_unlock(&sensor->data_mutex);\r
- DBG("%s:",__func__);\r
- for(i=0; i<sensor->ops->read_len; i++)\r
- DBG("0x%x,",buffer[i]);\r
- DBG("\n");\r
-\r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- DBG("%s:sensor int status :0x%x\n",__func__,value);\r
- }\r
-\r
- \r
- //trigger next measurement \r
- ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(ret)\r
- {\r
- printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);\r
- return ret;\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-static void compass_set_YPR(int *rbuf)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(this_client); \r
-\r
- /* No events are reported */\r
- if (!rbuf[0]) {\r
- printk("%s:Don't waste a time.",__func__);\r
- return;\r
- }\r
-\r
- DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);\r
- \r
- /* Report magnetic sensor information */\r
- if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) {\r
- input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]);\r
- input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]);\r
- input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]);\r
- input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);\r
- DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11], rbuf[4]);\r
- }\r
- \r
- /* Report acceleration sensor information */\r
- if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {\r
- input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);\r
- input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);\r
- input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);\r
- input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);\r
- \r
- DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);\r
- }\r
- \r
- /* Report magnetic vector information */\r
- if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) {\r
- input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]);\r
- input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]);\r
- input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]); \r
- input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]);\r
- \r
- DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]);\r
- }\r
- \r
- input_sync(sensor->input_dev);\r
-\r
- memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL\r
-}\r
-\r
-\r
-\r
-static int compass_dev_open(struct inode *inode, struct file *file)\r
-{\r
- struct sensor_private_data* sensor = \r
- (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- int result = 0;\r
- DBG("%s\n",__func__);\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int compass_dev_release(struct inode *inode, struct file *file)\r
-{\r
- struct sensor_private_data* sensor = \r
- (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- int result = 0; \r
- DBG("%s\n",__func__);\r
-\r
- return result;\r
-}\r
-\r
-static int compass_akm_set_mode(struct i2c_client *client, char mode)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- int result = 0; \r
-\r
- switch(mode & 0x1f)\r
- {\r
- case AK09911_MODE_SNG_MEASURE:\r
- case AK09911_MODE_SELF_TEST: \r
- case AK09911_MODE_FUSE_ACCESS: \r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if(sensor->pdata->irq_enable)\r
- {\r
- //DBG("%s:enable irq=%d\n",__func__,client->irq);\r
- //enable_irq(client->irq);\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- \r
- sensor->status_cur = SENSOR_ON;\r
- }\r
-\r
- break;\r
-\r
- case AK09911_MODE_POWERDOWN: \r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if(sensor->pdata->irq_enable)\r
- { \r
- //DBG("%s:disable irq=%d\n",__func__,client->irq);\r
- //disable_irq_nosync(client->irq);//disable irq\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
-\r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- break;\r
-\r
- }\r
- \r
- switch(mode & 0x1f)\r
- {\r
- case AK09911_MODE_SNG_MEASURE: \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode); \r
- break;\r
- case AK09911_MODE_SELF_TEST: \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- break;\r
- case AK09911_MODE_FUSE_ACCESS:\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- break;\r
- case AK09911_MODE_POWERDOWN:\r
- /* Set powerdown mode */\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- udelay(100);\r
- break;\r
- default:\r
- printk("%s: Unknown mode(%d)", __func__, mode);\r
- result = -EINVAL;\r
- break;\r
- }\r
- DBG("%s:mode=0x%x\n",__func__,mode);\r
- return result;\r
-\r
-}\r
-\r
-static int compass_akm_reset(struct i2c_client *client)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- int result = 0; \r
- \r
- if(sensor->pdata->reset_pin > 0)\r
- {\r
- gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);\r
- udelay(10);\r
- gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);\r
- }\r
- else \r
- {\r
- /* Set measure mode */\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);\r
- if(result)\r
- printk("%s:fail to Set measure mode\n",__func__);\r
- }\r
- \r
- udelay(100);\r
- \r
- return result;\r
-\r
-}\r
-\r
-\r
-\r
-static int compass_akm_get_openstatus(void)\r
-{ \r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));\r
- return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-static int compass_akm_get_closestatus(void)\r
-{ \r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));\r
- return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long compass_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
- struct i2c_client *client = this_client;\r
- void __user *argp = (void __user *)arg;\r
- int result = 0;\r
- struct akm_platform_data compass;\r
- \r
- /* NOTE: In this function the size of "char" should be 1-byte. */\r
- char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */\r
- char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */\r
- char mode; /* for SET_MODE*/\r
- int value[YPR_DATA_SIZE]; /* for SET_YPR */\r
- int status; /* for OPEN/CLOSE_STATUS */\r
- int ret = -1; /* Return value. */\r
- \r
- //int8_t sensor_buf[SENSOR_DATA_SIZE]; /* for GETDATA */\r
- //int32_t ypr_buf[YPR_DATA_SIZE]; /* for SET_YPR */\r
- int16_t acc_buf[3]; /* for GET_ACCEL */\r
- int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */\r
- char layout; /* for GET_LAYOUT */\r
- char outbit; /* for GET_OUTBIT */\r
-\r
- switch (cmd) {\r
- case ECS_IOCTL_WRITE:\r
- case ECS_IOCTL_READ:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_SET_MODE:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&mode, argp, sizeof(mode))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_SET_YPR:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&value, argp, sizeof(value))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GETDATA:\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- case ECS_IOCTL_GET_CLOSE_STATUS:\r
- case ECS_IOCTL_GET_DELAY:\r
- case ECS_IOCTL_GET_LAYOUT:\r
- case ECS_IOCTL_GET_OUTBIT:\r
- case ECS_IOCTL_GET_ACCEL:\r
- case ECS_IOCTL_GET_INFO:\r
- case ECS_IOCTL_GET_CONF:\r
- /* Just check buffer pointer */\r
- if (argp == NULL) {\r
- printk("%s:invalid argument\n",__func__);\r
- return -EINVAL;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- switch (cmd) {\r
- case ECS_IOCTL_WRITE:\r
- DBG("%s:ECS_IOCTL_WRITE start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
- mutex_unlock(&sensor->operation_mutex);\r
- return -EINVAL;\r
- }\r
- ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);\r
- if (ret < 0) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:fait to tx data\n",__func__);\r
- return ret;\r
- } \r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_READ: \r
- DBG("%s:ECS_IOCTL_READ start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:data is error\n",__func__);\r
- return -EINVAL;\r
- }\r
- ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);\r
- if (ret < 0) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:fait to rx data\n",__func__);\r
- return ret;\r
- } \r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_SET_MODE:\r
- DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); \r
- mutex_lock(&sensor->operation_mutex);\r
- if(sensor->ops->ctrl_data != mode)\r
- {\r
- ret = compass_akm_set_mode(client, mode);\r
- if (ret < 0) {\r
- printk("%s:fait to set mode\n",__func__); \r
- mutex_unlock(&sensor->operation_mutex);\r
- return ret;\r
- }\r
- \r
- sensor->ops->ctrl_data = mode;\r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_GETDATA:\r
- DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);\r
- mutex_lock(&sensor->data_mutex); \r
- memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer\r
- mutex_unlock(&sensor->data_mutex);\r
- break;\r
- case ECS_IOCTL_SET_YPR: \r
- DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);\r
- mutex_lock(&sensor->data_mutex);\r
- compass_set_YPR(value); \r
- mutex_unlock(&sensor->data_mutex);\r
- break;\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- status = compass_akm_get_openstatus(); \r
- DBG("%s:openstatus=%d\n",__func__,status);\r
- break;\r
- case ECS_IOCTL_GET_CLOSE_STATUS:\r
- status = compass_akm_get_closestatus(); \r
- DBG("%s:closestatus=%d\n",__func__,status);\r
- break;\r
- case ECS_IOCTL_GET_DELAY:\r
- DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- delay[0] = sensor->flags.delay;\r
- delay[1] = sensor->flags.delay;\r
- delay[2] = sensor->flags.delay;\r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- \r
- case ECS_IOCTL_GET_PLATFORM_DATA: \r
- DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);\r
- // memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));\r
- // memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));\r
- ret = copy_to_user(argp, &compass, sizeof(compass));\r
- if(ret < 0)\r
- {\r
- printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
- return ret;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_LAYOUT:\r
- DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);\r
+ 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; i<sensor->ops->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;\r
- case ECS_IOCTL_GET_OUTBIT:\r
- DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);\r
- outbit = 1; //sensor->pdata->outbit;\r
- break;\r
- case ECS_IOCTL_RESET:\r
- DBG("%s:ECS_IOCTL_RESET start\n",__func__);\r
- ret = compass_akm_reset(client);\r
- if (ret < 0)\r
- return ret;\r
- break;\r
- case ECS_IOCTL_GET_ACCEL:\r
- DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- acc_buf[0] = g_akm_rbuf[6];\r
- acc_buf[1] = g_akm_rbuf[7];\r
- acc_buf[2] = g_akm_rbuf[8];\r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_GET_INFO:\r
- ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info));\r
- if(ret < 0)\r
- {\r
- printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
- return ret;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_CONF:\r
- ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf));\r
- if(ret < 0)\r
- {\r
- printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
- return ret;\r
- }\r
- break;\r
-\r
- default:\r
- return -ENOTTY;\r
- }\r
-\r
- switch (cmd) {\r
- case ECS_IOCTL_READ:\r
- if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GETDATA:\r
- if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- case ECS_IOCTL_GET_CLOSE_STATUS:\r
- if (copy_to_user(argp, &status, sizeof(status))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_DELAY:\r
- if (copy_to_user(argp, &delay, sizeof(delay))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_LAYOUT:\r
- if (copy_to_user(argp, &layout, sizeof(layout))) {\r
- printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_OUTBIT:\r
- if (copy_to_user(argp, &outbit, sizeof(outbit))) {\r
- printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_ACCEL:\r
- if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {\r
- printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
- return -EFAULT;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-static struct file_operations compass_dev_fops =\r
-{\r
- .owner = THIS_MODULE,\r
- .open = compass_dev_open,\r
- .release = compass_dev_release, \r
- .unlocked_ioctl = compass_dev_ioctl,\r
-};\r
-\r
-\r
-static struct miscdevice compass_dev_device =\r
-{ \r
- .minor = MISC_DYNAMIC_MINOR,\r
- .name = "akm_dev",\r
- .fops = &compass_dev_fops,\r
-};\r
-\r
-struct sensor_operate compass_akm09911_ops = {\r
- .name = "akm09911",\r
- .type = SENSOR_TYPE_COMPASS, //it is important\r
- .id_i2c = COMPASS_ID_AK09911,\r
- .read_reg = AK09911_REG_ST1, //read data\r
- .read_len = SENSOR_DATA_SIZE, //data length\r
- .id_reg = AK09911_REG_WIA2, //read id\r
- .id_data = AK09911_DEVICE_ID,\r
- .precision = 8, //12 bits\r
- .ctrl_reg = AK09911_REG_CNTL2, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //not exist\r
- .range = {-0xffff,0xffff},\r
- .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT\r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value, \r
- .misc_dev = NULL, //private misc support\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *compass_get_ops(void)\r
-{\r
- return &compass_akm09911_ops; \r
-}\r
-\r
-\r
-static int __init compass_akm09911_init(void)\r
-{\r
- struct sensor_operate *ops = compass_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
- \r
- return result;\r
-}\r
-\r
-static void __exit compass_akm09911_exit(void)\r
-{\r
- struct sensor_operate *ops = compass_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, compass_get_ops);\r
-}\r
-\r
-\r
-module_init(compass_akm09911_init);\r
-module_exit(compass_akm09911_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/access/akm8963.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
+/* drivers/input/sensors/access/akm8963.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
#define AKM_SENSOR_INFO_SIZE 2
#define AKM_SENSOR_CONF_SIZE 3
-#define SENSOR_DATA_SIZE 8\r
-#define YPR_DATA_SIZE 12\r
-#define RWBUF_SIZE 16\r
-\r
-#define ACC_DATA_FLAG 0\r
-#define MAG_DATA_FLAG 1\r
-#define ORI_DATA_FLAG 2\r
-#define AKM_NUM_SENSORS 3\r
-\r
-#define ACC_DATA_READY (1<<(ACC_DATA_FLAG))\r
-#define MAG_DATA_READY (1<<(MAG_DATA_FLAG))\r
-#define ORI_DATA_READY (1<<(ORI_DATA_FLAG))\r
-\r
-/*! \name AK8963 constant definition\r
- \anchor AK8963_Def\r
- Constant definitions of the AK8963.*/\r
-#define AK8963_MEASUREMENT_TIME_US 10000\r
-\r
-/*! \name AK8963 operation mode\r
- \anchor AK8963_Mode\r
- Defines an operation mode of the AK8963.*/\r
-/*! @{*/\r
-#define AK8963_MODE_SNG_MEASURE 0x01\r
-#define AK8963_MODE_SELF_TEST 0x08\r
-#define AK8963_MODE_FUSE_ACCESS 0x0F\r
-#define AK8963_MODE_POWERDOWN 0x00\r
-\r
-/*! @}*/\r
-\r
-/*! \name AK8963 register address\r
-\anchor AK8963_REG\r
-Defines a register address of the AK8963.*/\r
-/*! @{*/\r
-#define AK8963_REG_WIA 0x00\r
-#define AK8963_REG_INFO 0x01\r
-#define AK8963_REG_ST1 0x02\r
-#define AK8963_REG_HXL 0x03\r
-#define AK8963_REG_HXH 0x04\r
-#define AK8963_REG_HYL 0x05\r
-#define AK8963_REG_HYH 0x06\r
-#define AK8963_REG_HZL 0x07\r
-#define AK8963_REG_HZH 0x08\r
-#define AK8963_REG_ST2 0x09\r
-#define AK8963_REG_CNTL1 0x0A\r
-#define AK8963_REG_CNTL2 0x0B\r
-#define AK8963_REG_ASTC 0x0C\r
-#define AK8963_REG_TS1 0x0D\r
-#define AK8963_REG_TS2 0x0E\r
-#define AK8963_REG_I2CDIS 0x0F\r
+#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
-/*! @}*/\r
-\r
-/*! \name AK8963 fuse-rom address\r
-\anchor AK8963_FUSE\r
-Defines a read-only address of the fuse ROM of the AK8963.*/\r
-/*! @{*/\r
-#define AK8963_FUSE_ASAX 0x10\r
-#define AK8963_FUSE_ASAY 0x11\r
-#define AK8963_FUSE_ASAZ 0x12\r
-/*! @}*/\r
-\r
-#define AK8963_INFO_DATA (0x03<<3)\r
-\r
-\r
-#define COMPASS_IOCTL_MAGIC 'c'\r
-\r
-/* IOCTLs for AKM library */\r
-#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)\r
-#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)\r
-#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */\r
-#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)\r
-#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])\r
-#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])\r
-#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)\r
-#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)\r
-#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)\r
-#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])\r
-#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)\r
-#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)\r
-#define ECS_IOCTL_GET_PROJECT_NAME _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])\r
-#define ECS_IOCTL_GET_MATRIX _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])\r
-#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)\r
+/*! @}*/
+
+/*! \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])
-\r
-#define AK8963_DEVICE_ID 0x48\r
-static struct i2c_client *this_client;\r
-static struct miscdevice compass_dev_device;\r
-\r
-static short g_akm_rbuf[12];\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- sensor->ops->ctrl_data = AK8963_MODE_SNG_MEASURE; \r
- }\r
- else\r
- {\r
- sensor->ops->ctrl_data = AK8963_MODE_POWERDOWN;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
- \r
- return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char info = 0;\r
-\r
- this_client = client; \r
-\r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- info = sensor_read_reg(client, AK8963_REG_INFO); \r
- if((info & (0x0f<<3)) != AK8963_INFO_DATA)\r
- {\r
- printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);\r
- return -1;\r
- }\r
-\r
- result = misc_register(&compass_dev_device);\r
- if (result < 0) {\r
- printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
- result = -1;\r
- }\r
- \r
- DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
- return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- char buffer[8] = {0}; \r
- unsigned char *stat;\r
- unsigned char *stat2; \r
- int ret = 0; \r
- char value = 0;\r
- int i;\r
-\r
- if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 8);\r
- \r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- *buffer = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-\r
- stat = &buffer[0];\r
- stat2 = &buffer[7];\r
- \r
- /*\r
+
+#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.
- */\r
- if ((*stat & 0x01) != 0x01) {\r
- DBG(KERN_ERR "%s:ST is not set\n",__func__);\r
- return -1;\r
- }\r
+ */
+ if ((*stat & 0x01) != 0x01) {
+ DBG(KERN_ERR "%s:ST is not set\n",__func__);
+ return -1;
+ }
/*
* ST2 : data error -
* corrupted.
* DERR bit is self-clearing when ST2 register is read.
*/
- if (*stat2 & 0x04)\r
- {\r
- DBG(KERN_ERR "%s:compass data error\n",__func__);\r
- return -2;\r
- }\r
- \r
+ 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.
* An error is returned.
* HOFL bit clears when a new measurement starts.
*/
- if (*stat2 & 0x08)\r
- { \r
- DBG(KERN_ERR "%s:compass data overflow\n",__func__);\r
- return -3;\r
- }\r
- \r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&sensor->data_mutex); \r
- memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
- mutex_unlock(&sensor->data_mutex);\r
- DBG("%s:",__func__);\r
- for(i=0; i<sensor->ops->read_len; i++)\r
- DBG("0x%x,",buffer[i]);\r
- DBG("\n");\r
-\r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- DBG("%s:sensor int status :0x%x\n",__func__,value);\r
- }\r
-\r
- \r
- //trigger next measurement \r
- ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(ret)\r
- {\r
- printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);\r
- return ret;\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-static void compass_set_YPR(int *rbuf)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(this_client); \r
-\r
- /* No events are reported */\r
- if (!rbuf[0]) {\r
- printk("%s:Don't waste a time.",__func__);\r
- return;\r
- }\r
-\r
- DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);\r
- \r
- /* Report magnetic sensor information */\r
+ 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; i<sensor->ops->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_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]);
}
- \r
- /* Report acceleration sensor information */\r
- if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {\r
- input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);\r
- input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);\r
- input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);\r
- input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);\r
- \r
- DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);\r
- }\r
- \r
- /* Report magnetic vector information */\r
+
+ /* 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]);
DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n", __func__, rbuf[5], rbuf[6], rbuf[7], rbuf[8]);
}
- \r
- input_sync(sensor->input_dev);\r
-\r
- memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL\r
-}\r
-\r
-\r
-\r
-static int compass_dev_open(struct inode *inode, struct file *file)\r
-{\r
- int result = 0;\r
- DBG("%s\n",__func__);\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int compass_dev_release(struct inode *inode, struct file *file)\r
-{\r
- int result = 0; \r
- DBG("%s\n",__func__);\r
-\r
- return result;\r
-}\r
-\r
-static int compass_akm_set_mode(struct i2c_client *client, char mode)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- int result = 0; \r
-\r
- switch(mode & 0x0f)\r
- {\r
- case AK8963_MODE_SNG_MEASURE:\r
- case AK8963_MODE_SELF_TEST: \r
- case AK8963_MODE_FUSE_ACCESS: \r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if(sensor->pdata->irq_enable)\r
- {\r
- //DBG("%s:enable irq=%d\n",__func__,client->irq);\r
- //enable_irq(client->irq);\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- \r
- sensor->status_cur = SENSOR_ON;\r
- }\r
-\r
- break;\r
-\r
- case AK8963_MODE_POWERDOWN: \r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if(sensor->pdata->irq_enable)\r
- { \r
- //DBG("%s:disable irq=%d\n",__func__,client->irq);\r
- //disable_irq_nosync(client->irq);//disable irq\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
-\r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- break;\r
-\r
- }\r
- \r
- switch(mode & 0x0f)\r
- {\r
- case AK8963_MODE_SNG_MEASURE: \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode); \r
- break;\r
- case AK8963_MODE_SELF_TEST: \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- break;\r
- case AK8963_MODE_FUSE_ACCESS:\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- break;\r
- case AK8963_MODE_POWERDOWN:\r
- /* Set powerdown mode */\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_MODE_POWERDOWN);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- udelay(100);\r
- break;\r
- default:\r
- printk("%s: Unknown mode(%d)", __func__, mode);\r
- result = -EINVAL;\r
- break;\r
- }\r
- DBG("%s:mode=0x%x\n",__func__,mode);\r
- return result;\r
-\r
-}\r
-\r
-static int compass_akm_reset(struct i2c_client *client)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- int result = 0; \r
- \r
- if(sensor->pdata->reset_pin > 0)\r
- {\r
- gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);\r
- udelay(10);\r
- gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);\r
- }\r
- else \r
- {\r
- /* Set measure mode */\r
- result = sensor_write_reg(client, AK8963_REG_CNTL2, AK8963_MODE_SNG_MEASURE);\r
- if(result)\r
- printk("%s:fail to Set measure mode\n",__func__);\r
- }\r
- \r
- udelay(100);\r
- \r
- return result;\r
-\r
-}\r
-\r
-\r
-\r
-static int compass_akm_get_openstatus(void)\r
-{ \r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));\r
- return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-static int compass_akm_get_closestatus(void)\r
-{ \r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));\r
- return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long compass_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
- struct i2c_client *client = this_client;\r
- void __user *argp = (void __user *)arg;\r
- int result = 0;\r
- struct akm_platform_data compass;\r
+
+ 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. */\r
- char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */\r
- char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */\r
- char mode; /* for SET_MODE*/\r
- int value[12]; /* for SET_YPR */\r
- int status; /* for OPEN/CLOSE_STATUS */\r
- int ret = -1; /* Return value. */\r
- \r
- //int8_t sensor_buf[SENSOR_DATA_SIZE]; /* for GETDATA */\r
- //int32_t ypr_buf[YPR_DATA_SIZE]; /* for SET_YPR */\r
- int16_t acc_buf[3]; /* for GET_ACCEL */\r
- int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */\r
-\r
- char layout; /* for GET_LAYOUT */\r
- char outbit; /* for GET_OUTBIT */\r
-\r
- switch (cmd) {\r
- case ECS_IOCTL_WRITE:\r
- case ECS_IOCTL_READ:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_SET_MODE:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&mode, argp, sizeof(mode))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_SET_YPR:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&value, argp, sizeof(value))) {\r
- return -EFAULT;\r
- }\r
- break;\r
+ /* 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:\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- case ECS_IOCTL_GET_CLOSE_STATUS:\r
- case ECS_IOCTL_GET_DELAY:\r
- case ECS_IOCTL_GET_LAYOUT:\r
- case ECS_IOCTL_GET_OUTBIT:\r
- case ECS_IOCTL_GET_ACCEL:\r
- /* Just check buffer pointer */\r
- if (argp == NULL) {\r
- printk("%s:invalid argument\n",__func__);\r
- return -EINVAL;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- switch (cmd) {\r
+ 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);
return ret;
}
break;
- case ECS_IOCTL_WRITE:\r
- DBG("%s:ECS_IOCTL_WRITE start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
- mutex_unlock(&sensor->operation_mutex);\r
- return -EINVAL;\r
- }\r
- ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);\r
- if (ret < 0) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:fait to tx data\n",__func__);\r
- return ret;\r
- } \r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_READ: \r
- DBG("%s:ECS_IOCTL_READ start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:data is error\n",__func__);\r
- return -EINVAL;\r
- }\r
- ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);\r
- if (ret < 0) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:fait to rx data\n",__func__);\r
- return ret;\r
- } \r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_SET_MODE:\r
- DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); \r
- mutex_lock(&sensor->operation_mutex);\r
- if(sensor->ops->ctrl_data != mode)\r
- {\r
- ret = compass_akm_set_mode(client, mode);\r
- if (ret < 0) {\r
- printk("%s:fait to set mode\n",__func__); \r
- mutex_unlock(&sensor->operation_mutex);\r
- return ret;\r
- }\r
- \r
- sensor->ops->ctrl_data = mode;\r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_GETDATA:\r
- DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);\r
- mutex_lock(&sensor->data_mutex); \r
- memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer\r
- mutex_unlock(&sensor->data_mutex);\r
- break;\r
- case ECS_IOCTL_SET_YPR: \r
- DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);\r
- mutex_lock(&sensor->data_mutex);\r
- compass_set_YPR(value); \r
- mutex_unlock(&sensor->data_mutex);\r
- break;\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- status = compass_akm_get_openstatus(); \r
- DBG("%s:openstatus=%d\n",__func__,status);\r
- break;\r
- case ECS_IOCTL_GET_CLOSE_STATUS:\r
- status = compass_akm_get_closestatus(); \r
- DBG("%s:closestatus=%d\n",__func__,status);\r
- break;\r
- case ECS_IOCTL_GET_DELAY:\r
- DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- delay[0] = sensor->flags.delay;\r
- delay[1] = sensor->flags.delay;\r
- delay[2] = sensor->flags.delay;\r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- \r
- case ECS_IOCTL_GET_PLATFORM_DATA: \r
- DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);\r
- //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));\r
- //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));\r
- ret = copy_to_user(argp, &compass, sizeof(compass));\r
- if(ret < 0)\r
- {\r
- printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
- return ret;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_LAYOUT:\r
- DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);\r
- layout = sensor->pdata->layout;\r
- break;\r
- case ECS_IOCTL_GET_OUTBIT:\r
- DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);\r
- outbit = 1; //sensor->pdata->outbit;\r
- break;\r
- case ECS_IOCTL_RESET:\r
- DBG("%s:ECS_IOCTL_RESET start\n",__func__);\r
- ret = compass_akm_reset(client);\r
- if (ret < 0)\r
- return ret;\r
- break;\r
- case ECS_IOCTL_GET_ACCEL:\r
- DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- acc_buf[0] = g_akm_rbuf[6];\r
- acc_buf[1] = g_akm_rbuf[7];\r
- acc_buf[2] = g_akm_rbuf[8];\r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
-\r
- default:\r
- return -ENOTTY;\r
- }\r
-\r
- switch (cmd) {\r
- case ECS_IOCTL_READ:\r
- if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GETDATA:\r
- if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- case ECS_IOCTL_GET_CLOSE_STATUS:\r
- if (copy_to_user(argp, &status, sizeof(status))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_DELAY:\r
- if (copy_to_user(argp, &delay, sizeof(delay))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_LAYOUT:\r
- if (copy_to_user(argp, &layout, sizeof(layout))) {\r
- printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_OUTBIT:\r
- if (copy_to_user(argp, &outbit, sizeof(outbit))) {\r
- printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_ACCEL:\r
- if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {\r
- printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
- return -EFAULT;\r
- }\r
- break;\r
+ 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__);
return -EFAULT;
}
break;
- default:\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-static struct file_operations compass_dev_fops =\r
-{\r
- .owner = THIS_MODULE,\r
- .open = compass_dev_open,\r
- .release = compass_dev_release, \r
- .unlocked_ioctl = compass_dev_ioctl,\r
-};\r
-\r
-\r
-static struct miscdevice compass_dev_device =\r
-{ \r
- .minor = MISC_DYNAMIC_MINOR,\r
- .name = "akm8963_dev",\r
- .fops = &compass_dev_fops,\r
-};\r
-\r
-struct sensor_operate compass_akm8963_ops = {\r
- .name = "akm8963",\r
- .type = SENSOR_TYPE_COMPASS, //it is important\r
- .id_i2c = COMPASS_ID_AK8963,\r
- .read_reg = AK8963_REG_ST1, //read data\r
- .read_len = SENSOR_DATA_SIZE, //data length\r
- .id_reg = AK8963_REG_WIA, //read id\r
- .id_data = AK8963_DEVICE_ID,\r
- .precision = 8, //12 bits\r
- .ctrl_reg = AK8963_REG_CNTL1, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //not exist\r
- .range = {-0xffff,0xffff},\r
- .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT\r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value, \r
- .misc_dev = NULL, //private misc support\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *compass_get_ops(void)\r
-{\r
- return &compass_akm8963_ops; \r
-}\r
-\r
-\r
-static int __init compass_akm8963_init(void)\r
-{\r
- struct sensor_operate *ops = compass_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
- \r
- return result;\r
-}\r
-\r
-static void __exit compass_akm8963_exit(void)\r
-{\r
- struct sensor_operate *ops = compass_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, compass_get_ops);\r
-}\r
-\r
-\r
-module_init(compass_akm8963_init);\r
-module_exit(compass_akm8963_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/access/akm8975.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-\r
-#include <linux/sensor-dev.h>\r
-\r
-#define SENSOR_DATA_SIZE 8\r
-\r
-\r
-/*! \name AK8975 operation mode\r
- \anchor AK8975_Mode\r
- Defines an operation mode of the AK8975.*/\r
-/*! @{*/\r
-#define AK8975_MODE_SNG_MEASURE 0x01\r
-#define AK8975_MODE_SELF_TEST 0x08\r
-#define AK8975_MODE_FUSE_ACCESS 0x0F\r
-#define AK8975_MODE_POWERDOWN 0x00\r
-/*! @}*/\r
-\r
-#define SENSOR_DATA_SIZE 8 /* Rx buffer size, i.e from ST1 to ST2 */\r
-#define RWBUF_SIZE 16 /* Read/Write buffer size.*/\r
-\r
-\r
-/*! \name AK8975 register address\r
-\anchor AK8975_REG\r
-Defines a register address of the AK8975.*/\r
-/*! @{*/\r
-#define AK8975_REG_WIA 0x00\r
-#define AK8975_REG_INFO 0x01\r
-#define AK8975_REG_ST1 0x02\r
-#define AK8975_REG_HXL 0x03\r
-#define AK8975_REG_HXH 0x04\r
-#define AK8975_REG_HYL 0x05\r
-#define AK8975_REG_HYH 0x06\r
-#define AK8975_REG_HZL 0x07\r
-#define AK8975_REG_HZH 0x08\r
-#define AK8975_REG_ST2 0x09\r
-#define AK8975_REG_CNTL 0x0A\r
-#define AK8975_REG_RSV 0x0B\r
-#define AK8975_REG_ASTC 0x0C\r
-#define AK8975_REG_TS1 0x0D\r
-#define AK8975_REG_TS2 0x0E\r
-#define AK8975_REG_I2CDIS 0x0F\r
-/*! @}*/\r
-\r
-/*! \name AK8975 fuse-rom address\r
-\anchor AK8975_FUSE\r
-Defines a read-only address of the fuse ROM of the AK8975.*/\r
-/*! @{*/\r
-#define AK8975_FUSE_ASAX 0x10\r
-#define AK8975_FUSE_ASAY 0x11\r
-#define AK8975_FUSE_ASAZ 0x12\r
-/*! @}*/\r
-\r
-#define AK8975_INFO_DATA (0x01<<3)\r
-\r
-\r
-#define COMPASS_IOCTL_MAGIC 'c'\r
-\r
-/* IOCTLs for AKM library */\r
-#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)\r
-#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)\r
-#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */\r
-#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)\r
-#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])\r
-#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])\r
-#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)\r
-#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)\r
-#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)\r
-#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])\r
-#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)\r
-#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)\r
-#define ECS_IOCTL_GET_PROJECT_NAME _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])\r
-#define ECS_IOCTL_GET_MATRIX _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])\r
-#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)\r
-\r
-\r
-#define AK8975_DEVICE_ID 0x48\r
-static struct i2c_client *this_client;\r
-static struct miscdevice compass_dev_device;\r
-\r
-\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- sensor->ops->ctrl_data = AK8975_MODE_SNG_MEASURE; \r
- }\r
- else\r
- {\r
- sensor->ops->ctrl_data = AK8975_MODE_POWERDOWN;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
- \r
- return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int info = 0;\r
-\r
- this_client = client; \r
-\r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- \r
- info = sensor_read_reg(client, AK8975_REG_INFO);\r
- if((info & (0x0f<<3)) != AK8975_INFO_DATA)\r
- \r
- {\r
- printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);\r
- return -1;\r
- }\r
-\r
- result = misc_register(&compass_dev_device);\r
- if (result < 0) {\r
- printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
- result = -1;\r
- }\r
- \r
- DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
- return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- char buffer[8] = {0}; \r
- unsigned char *stat;\r
- unsigned char *stat2; \r
- int ret = 0; \r
- char value = 0;\r
- int i;\r
-\r
- if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 8);\r
- \r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- *buffer = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-\r
- stat = &buffer[0];\r
- stat2 = &buffer[7];\r
- \r
- /*\r
+/* drivers/input/sensors/access/akm8975.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include <linux/sensor-dev.h>
+
+#define 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.
- */\r
- if ((*stat & 0x01) != 0x01) {\r
- DBG(KERN_ERR "%s:ST is not set\n",__func__);\r
- return -1;\r
- }\r
+ */
+ if ((*stat & 0x01) != 0x01) {
+ DBG(KERN_ERR "%s:ST is not set\n",__func__);
+ return -1;
+ }
/*
* ST2 : data error -
* corrupted.
* DERR bit is self-clearing when ST2 register is read.
*/
- if (*stat2 & 0x04)\r
- {\r
- DBG(KERN_ERR "%s:compass data error\n",__func__);\r
- return -2;\r
- }\r
- \r
+ 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.
* An error is returned.
* HOFL bit clears when a new measurement starts.
*/
- if (*stat2 & 0x08)\r
- { \r
- DBG(KERN_ERR "%s:compass data overflow\n",__func__);\r
- return -3;\r
- }\r
- \r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&sensor->data_mutex); \r
- memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
- mutex_unlock(&sensor->data_mutex);\r
- DBG("%s:",__func__);\r
- for(i=0; i<sensor->ops->read_len; i++)\r
- DBG("0x%x,",buffer[i]);\r
- DBG("\n");\r
-\r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- DBG("%s:sensor int status :0x%x\n",__func__,value);\r
- }\r
-\r
- \r
- //trigger next measurement \r
- ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(ret)\r
- {\r
- printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);\r
- return ret;\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-static void compass_set_YPR(short *rbuf)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(this_client); \r
- \r
- /* Report magnetic sensor information */\r
- if (atomic_read(&sensor->flags.m_flag)) {\r
- input_report_abs(sensor->input_dev, ABS_RX, rbuf[0]);\r
- input_report_abs(sensor->input_dev, ABS_RY, rbuf[1]);\r
- input_report_abs(sensor->input_dev, ABS_RZ, rbuf[2]);\r
- input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);\r
- DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[0], rbuf[1], rbuf[2], rbuf[4]);\r
- }\r
- \r
- /* Report acceleration sensor information */\r
- if (atomic_read(&sensor->flags.a_flag)) {\r
- input_report_abs(sensor->input_dev, ABS_X, rbuf[6]);\r
- input_report_abs(sensor->input_dev, ABS_Y, rbuf[7]);\r
- input_report_abs(sensor->input_dev, ABS_Z, rbuf[8]);\r
- input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[5]);\r
- \r
- DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[6], rbuf[7], rbuf[8], rbuf[5]);\r
- }\r
- \r
- /* Report magnetic vector information */\r
- if (atomic_read(&sensor->flags.mv_flag)) {\r
- input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[9]);\r
- input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[10]);\r
- input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[11]);\r
- \r
- DBG("%s:mv_flag:x=%d,y=%d,BRAKE=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11]);\r
- }\r
- \r
- input_sync(sensor->input_dev);\r
-}\r
-\r
-\r
-static int compass_dev_open(struct inode *inode, struct file *file)\r
-{\r
- int result = 0;\r
- DBG("%s\n",__func__);\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int compass_dev_release(struct inode *inode, struct file *file)\r
-{\r
- int result = 0; \r
- DBG("%s\n",__func__);\r
-\r
- return result;\r
-}\r
-\r
-static int compass_akm_set_mode(struct i2c_client *client, char mode)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- int result = 0; \r
-\r
- switch(mode)\r
- {\r
- case AK8975_MODE_SNG_MEASURE:\r
- case AK8975_MODE_SELF_TEST: \r
- case AK8975_MODE_FUSE_ACCESS: \r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if(sensor->pdata->irq_enable)\r
- {\r
- //DBG("%s:enable irq=%d\n",__func__,client->irq);\r
- //enable_irq(client->irq);\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- \r
- sensor->status_cur = SENSOR_ON;\r
- }\r
-\r
- break;\r
-\r
- case AK8975_MODE_POWERDOWN: \r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if(sensor->pdata->irq_enable)\r
- { \r
- //DBG("%s:disable irq=%d\n",__func__,client->irq);\r
- //disable_irq_nosync(client->irq);//disable irq\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
-\r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- break;\r
-\r
- }\r
- \r
- switch(mode)\r
- {\r
- case AK8975_MODE_SNG_MEASURE: \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SNG_MEASURE);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode); \r
- break;\r
- case AK8975_MODE_SELF_TEST: \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SELF_TEST);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- break;\r
- case AK8975_MODE_FUSE_ACCESS:\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_FUSE_ACCESS);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- break;\r
- case AK8975_MODE_POWERDOWN:\r
- /* Set powerdown mode */\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_POWERDOWN);\r
- if(result)\r
- printk("%s:i2c error,mode=%d\n",__func__,mode);\r
- udelay(100);\r
- break;\r
- default:\r
- printk("%s: Unknown mode(%d)", __func__, mode);\r
- result = -EINVAL;\r
- break;\r
- }\r
- DBG("%s:mode=%d\n",__func__,mode);\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int compass_akm_get_openstatus(void)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));\r
- return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-static int compass_akm_get_closestatus(void)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
- wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));\r
- return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long compass_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
- struct i2c_client *client = this_client;\r
- void __user *argp = (void __user *)arg;\r
- int result = 0;\r
- struct akm_platform_data compass;\r
- \r
- /* NOTE: In this function the size of "char" should be 1-byte. */\r
- char compass_data[SENSOR_DATA_SIZE];/* for GETDATA */\r
- char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */\r
- char mode; /* for SET_MODE*/\r
- short value[12]; /* for SET_YPR */\r
- short delay; /* for GET_DELAY */\r
- int status; /* for OPEN/CLOSE_STATUS */\r
- int ret = -1; /* Return value. */\r
- \r
- switch (cmd) {\r
- case ECS_IOCTL_WRITE:\r
- case ECS_IOCTL_READ:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_SET_MODE:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&mode, argp, sizeof(mode))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_SET_YPR:\r
- if (argp == NULL) {\r
- return -EINVAL;\r
- }\r
- if (copy_from_user(&value, argp, sizeof(value))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
- \r
- switch (cmd) {\r
- case ECS_IOCTL_WRITE:\r
- DBG("%s:ECS_IOCTL_WRITE start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
- mutex_unlock(&sensor->operation_mutex);\r
- return -EINVAL;\r
- }\r
- ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);\r
- if (ret < 0) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:fait to tx data\n",__func__);\r
- return ret;\r
- } \r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_READ: \r
- DBG("%s:ECS_IOCTL_READ start\n",__func__);\r
- mutex_lock(&sensor->operation_mutex);\r
- if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:data is error\n",__func__);\r
- return -EINVAL;\r
- }\r
- ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);\r
- if (ret < 0) { \r
- mutex_unlock(&sensor->operation_mutex); \r
- printk("%s:fait to rx data\n",__func__);\r
- return ret;\r
- } \r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_SET_MODE: \r
- DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); \r
- mutex_lock(&sensor->operation_mutex);\r
- if(sensor->ops->ctrl_data != mode)\r
- {\r
- ret = compass_akm_set_mode(client, mode);\r
- if (ret < 0) {\r
- printk("%s:fait to set mode\n",__func__); \r
- mutex_unlock(&sensor->operation_mutex);\r
- return ret;\r
- }\r
- \r
- sensor->ops->ctrl_data = mode;\r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- break;\r
- case ECS_IOCTL_GETDATA: \r
- DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);\r
- mutex_lock(&sensor->data_mutex); \r
- memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer\r
- mutex_unlock(&sensor->data_mutex);\r
- break;\r
- case ECS_IOCTL_SET_YPR: \r
- DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);\r
- mutex_lock(&sensor->data_mutex);\r
- compass_set_YPR(value); \r
- mutex_unlock(&sensor->data_mutex);\r
- break;\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- status = compass_akm_get_openstatus(); \r
- DBG("%s:openstatus=%d\n",__func__,status);\r
- break;\r
+ 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; i<sensor->ops->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(); \r
- DBG("%s:closestatus=%d\n",__func__,status);\r
- break;\r
- case ECS_IOCTL_GET_DELAY:\r
- delay = sensor->flags.delay;\r
- break;\r
- case ECS_IOCTL_GET_PLATFORM_DATA: \r
- DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);\r
- //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));\r
- //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));\r
- ret = copy_to_user(argp, &compass, sizeof(compass));\r
- if(ret < 0)\r
- {\r
- printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
- return ret;\r
- }\r
- break;\r
- \r
- default:\r
- return -ENOTTY;\r
- }\r
- \r
- switch (cmd) {\r
- case ECS_IOCTL_READ:\r
- if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GETDATA:\r
- if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_OPEN_STATUS:\r
- case ECS_IOCTL_GET_CLOSE_STATUS:\r
- if (copy_to_user(argp, &status, sizeof(status))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- case ECS_IOCTL_GET_DELAY:\r
- if (copy_to_user(argp, &delay, sizeof(delay))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-static struct file_operations compass_dev_fops =\r
-{\r
- .owner = THIS_MODULE,\r
- .open = compass_dev_open,\r
- .release = compass_dev_release, \r
- .unlocked_ioctl = compass_dev_ioctl,\r
-};\r
-\r
-\r
-static struct miscdevice compass_dev_device =\r
-{ \r
- .minor = MISC_DYNAMIC_MINOR,\r
- .name = "akm8975_dev",\r
- .fops = &compass_dev_fops,\r
-};\r
-\r
-struct sensor_operate compass_akm8975_ops = {\r
- .name = "akm8975",\r
- .type = SENSOR_TYPE_COMPASS, //it is important\r
- .id_i2c = COMPASS_ID_AK8975,\r
- .read_reg = AK8975_REG_ST1, //read data\r
- .read_len = SENSOR_DATA_SIZE, //data length\r
- .id_reg = AK8975_REG_WIA, //read id\r
- .id_data = AK8975_DEVICE_ID,\r
- .precision = 8, //12 bits\r
- .ctrl_reg = AK8975_REG_CNTL, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //not exist\r
- .range = {-0xffff,0xffff},\r
- .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT\r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value, \r
- .misc_dev = NULL, //private misc support\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *compass_get_ops(void)\r
-{\r
- return &compass_akm8975_ops; \r
-}\r
-\r
-\r
-static int __init compass_akm8975_init(void)\r
-{\r
- struct sensor_operate *ops = compass_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
- \r
- return result;\r
-}\r
-\r
-static void __exit compass_akm8975_exit(void)\r
-{\r
- struct sensor_operate *ops = compass_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, compass_get_ops);\r
-}\r
-\r
-\r
-module_init(compass_akm8975_init);\r
-module_exit(compass_akm8975_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/gyro/Ewtsa.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: zhangaihui <zah@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-/** This define controls compilation of the master device interface */\r
-/*#define EWTSA_MASTER_DEVICE*/\r
-/* configurable */\r
-#define GYRO_MOUNT_SWAP_XY 0 /* swap X, Y */\r
-#define GYRO_MOUNT_REVERSE_X 0 /* reverse X */\r
-#define GYRO_MOUNT_REVERSE_Y 0 /* reverse Y */\r
-#define GYRO_MOUNT_REVERSE_Z 0 /* reverse Z */\r
-\r
-/* macro defines */\r
-/*#define CHIP_ID 0x68*/\r
-#define DEVICE_NAME "ewtsa"\r
-#define EWTSA_ON 1\r
-#define EWTSA_OFF 0\r
-#define SLEEP_PIN 14\r
-#define DRDY_PIN 12\r
-#define DIAG_PIN 11\r
-#define MAX_VALUE 32768\r
-\r
-/* ewtsa_delay parameter */\r
-#define DELAY_THRES_MIN 1\r
-#define DELAY_THRES_1 4\r
-#define DELAY_THRES_2 9 /* msec x 90% */\r
-#define DELAY_THRES_3 18\r
-#define DELAY_THRES_4 45\r
-#define DELAY_THRES_5 90\r
-#define DELAY_THRES_6 128\r
-#define DELAY_THRES_MAX 255\r
-#define DELAY_DLPF_2 2\r
-#define DELAY_DLPF_3 3\r
-#define DELAY_DLPF_4 4\r
-#define DELAY_DLPF_5 5\r
-#define DELAY_DLPF_6 6\r
-#define DELAY_INTMIN_THRES 9\r
-\r
-#define DATA_RATE_1 0x01\r
-\r
-/* ewtsa_sleep parameter */\r
-#define SLEEP_OFF 0\r
-#define SLEEP_ON 1\r
-\r
-/* event mode */\r
-#define EWTSA_POLLING_MODE 0\r
-#define EWTSA_INTERUPT_MODE 1\r
-\r
-/* ewtsa register address */\r
-#define REG_SMPL 0x15\r
-#define REG_FS_DLPF 0x16\r
-#define REG_INT_CFG 0x17\r
-#define REG_INT_STATUS 0x1A\r
-#define REG_SELF_O_C 0x29\r
-#define REG_PWR_MGM 0x3E\r
-#define REG_MBURST_ALL 0xFF\r
-#define GYRO_DATA_REG 0x1D\r
-\r
-/* ewtsa register param */\r
-#define SELF_O_C_ENABLE 0x00\r
-#define SELF_O_C_DISABLE 0x01\r
-#define SLEEP_CTRL_ACTIVATE 0x40\r
-#define SLEEP_CTRL_SLEEP 0x00\r
-#define INT_CFG_INT_ENABLE 0x01\r
-#define INT_CFG_INT_DISABLE 0x00\r
-\r
-/* ewtsa interrupt control */\r
-#define EWSTA_INT_CLEAR 0x00\r
-#define EWSTA_INT_SKIP 0x01\r
-\r
-/* wait time(ms)*/\r
-#define EWTSA_BOOST_TIME_0 500\r
-\r
-/* sleep setting range */\r
-#define EWTSA_SLP_MIN 0\r
-#define EWTSA_SLP_MAX 1\r
-\r
-/* delay setting range */\r
-#define EWTSA_DLY_MIN 1\r
-#define EWTSA_DLY_MAX 255\r
-\r
-/* range setting range */\r
-#define EWTSA_RNG_MIN 0\r
-#define EWTSA_RNG_MAX 3\r
-\r
-/* soc setting range */\r
-#define EWTSA_SOC_MIN 0\r
-#define EWTSA_SOC_MAX 1\r
-\r
-/* event setting range */\r
-#define EWTSA_EVE_MIN 0\r
-#define EWTSA_EVE_MAX 1\r
-\r
-/* init param */\r
-#define SLEEP_INIT_VAL (SLEEP_ON)\r
-#define DELAY_INIT_VAL 10\r
-#define RANGE_INIT_VAL 2 /*range 1000*/\r
-#define DLPF_INIT_VAL (DELAY_DLPF_2)\r
-#define CALIB_FUNC_INIT_VAL (EWTSA_ON)\r
-\r
-/*config store counter num*/\r
-#define CONFIG_COUNTER_MIN (6+9)\r
-#define CONFIG_COUNTER_MAX (32+9)\r
-\r
-/*command name */\r
-#define COMMAND_NAME_SOC 0\r
-#define COMMAND_NAME_DLY 1\r
-#define COMMAND_NAME_RNG 2\r
-#define COMMAND_NAME_EVE 3\r
-#define COMMAND_NAME_SLP 4\r
-#define COMMAND_NAME_NUM 5\r
-\r
-#define EWTSA_delay DELAY_INIT_VAL\r
-#define EWTSA_range RANGE_INIT_VAL\r
-#define EWTSA_calib EWTSA_ON\r
-\r
-/****************operate according to sensor chip:start************/\r
-static int i2c_read_byte(struct i2c_client *thisClient, unsigned char regAddr, char *pReadData)\r
+/* drivers/input/sensors/gyro/Ewtsa.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: zhangaihui <zah@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+/** This define controls compilation of the master device interface */
+/*#define EWTSA_MASTER_DEVICE*/
+/* configurable */
+#define GYRO_MOUNT_SWAP_XY 0 /* swap X, Y */
+#define GYRO_MOUNT_REVERSE_X 0 /* reverse X */
+#define GYRO_MOUNT_REVERSE_Y 0 /* reverse Y */
+#define GYRO_MOUNT_REVERSE_Z 0 /* reverse Z */
+
+/* macro defines */
+/*#define CHIP_ID 0x68*/
+#define DEVICE_NAME "ewtsa"
+#define EWTSA_ON 1
+#define EWTSA_OFF 0
+#define SLEEP_PIN 14
+#define DRDY_PIN 12
+#define DIAG_PIN 11
+#define MAX_VALUE 32768
+
+/* ewtsa_delay parameter */
+#define DELAY_THRES_MIN 1
+#define DELAY_THRES_1 4
+#define DELAY_THRES_2 9 /* msec x 90% */
+#define DELAY_THRES_3 18
+#define DELAY_THRES_4 45
+#define DELAY_THRES_5 90
+#define DELAY_THRES_6 128
+#define DELAY_THRES_MAX 255
+#define DELAY_DLPF_2 2
+#define DELAY_DLPF_3 3
+#define DELAY_DLPF_4 4
+#define DELAY_DLPF_5 5
+#define DELAY_DLPF_6 6
+#define DELAY_INTMIN_THRES 9
+
+#define DATA_RATE_1 0x01
+
+/* ewtsa_sleep parameter */
+#define SLEEP_OFF 0
+#define SLEEP_ON 1
+
+/* event mode */
+#define EWTSA_POLLING_MODE 0
+#define EWTSA_INTERUPT_MODE 1
+
+/* ewtsa register address */
+#define REG_SMPL 0x15
+#define REG_FS_DLPF 0x16
+#define REG_INT_CFG 0x17
+#define REG_INT_STATUS 0x1A
+#define REG_SELF_O_C 0x29
+#define REG_PWR_MGM 0x3E
+#define REG_MBURST_ALL 0xFF
+#define GYRO_DATA_REG 0x1D
+
+/* ewtsa register param */
+#define SELF_O_C_ENABLE 0x00
+#define SELF_O_C_DISABLE 0x01
+#define SLEEP_CTRL_ACTIVATE 0x40
+#define SLEEP_CTRL_SLEEP 0x00
+#define INT_CFG_INT_ENABLE 0x01
+#define INT_CFG_INT_DISABLE 0x00
+
+/* ewtsa interrupt control */
+#define EWSTA_INT_CLEAR 0x00
+#define EWSTA_INT_SKIP 0x01
+
+/* wait time(ms)*/
+#define EWTSA_BOOST_TIME_0 500
+
+/* sleep setting range */
+#define EWTSA_SLP_MIN 0
+#define EWTSA_SLP_MAX 1
+
+/* delay setting range */
+#define EWTSA_DLY_MIN 1
+#define EWTSA_DLY_MAX 255
+
+/* range setting range */
+#define EWTSA_RNG_MIN 0
+#define EWTSA_RNG_MAX 3
+
+/* soc setting range */
+#define EWTSA_SOC_MIN 0
+#define EWTSA_SOC_MAX 1
+
+/* event setting range */
+#define EWTSA_EVE_MIN 0
+#define EWTSA_EVE_MAX 1
+
+/* init param */
+#define SLEEP_INIT_VAL (SLEEP_ON)
+#define DELAY_INIT_VAL 10
+#define RANGE_INIT_VAL 2 /*range 1000*/
+#define DLPF_INIT_VAL (DELAY_DLPF_2)
+#define CALIB_FUNC_INIT_VAL (EWTSA_ON)
+
+/*config store counter num*/
+#define CONFIG_COUNTER_MIN (6+9)
+#define CONFIG_COUNTER_MAX (32+9)
+
+/*command name */
+#define COMMAND_NAME_SOC 0
+#define COMMAND_NAME_DLY 1
+#define COMMAND_NAME_RNG 2
+#define COMMAND_NAME_EVE 3
+#define COMMAND_NAME_SLP 4
+#define COMMAND_NAME_NUM 5
+
+#define EWTSA_delay DELAY_INIT_VAL
+#define EWTSA_range RANGE_INIT_VAL
+#define EWTSA_calib EWTSA_ON
+
+/****************operate according to sensor chip:start************/
+static int i2c_read_byte(struct i2c_client *thisClient, unsigned char regAddr, char *pReadData)
{
int ret = 0;
-
+
ret = i2c_master_send( thisClient, (char*)®Addr, 1);
if(ret < 0)
{
- printk("EWTSA send cAddress=0x%x error!\n", regAddr);\r
+ 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);\r
+ printk("EWTSAread *pReadData=0x%x error!\n", *pReadData);
return ret;
}
return 1;
-}\r
-static int i2c_write_byte(struct i2c_client *thisClient, unsigned char regAddr, unsigned char writeData)\r
+}
+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);\r
+ printk("EWTSA send regAddr=0x%x error!\n", regAddr);
return ret;
}
return 1;
}
-
+
return 1;
-}\r
-\r
-static int ewtsa_system_restart(struct i2c_client *client)\r
+}
+
+static int ewtsa_system_restart(struct i2c_client *client)
{
int err;
- char reg;\r
- char smpl , dlpf;\r
-\r
- err = i2c_write_byte(client, ( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_DISABLE);\r
+ 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) {\r
- smpl = ( unsigned char)DELAY_INTMIN_THRES;\r
+ if (EWTSA_delay <= ( unsigned char)DELAY_THRES_2) {
+ smpl = ( unsigned char)DELAY_INTMIN_THRES;
}else{
- smpl = ( unsigned char)(EWTSA_delay - ( unsigned char)1);\r
- }\r
- err = i2c_write_byte(client, ( unsigned char)REG_SMPL, ( unsigned char)smpl);\r
+ 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){\r
- dlpf = ( unsigned char)DELAY_DLPF_6;\r
- }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_5) {\r
- dlpf = ( unsigned char)DELAY_DLPF_5;\r
- }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_4){\r
- dlpf = ( unsigned char)DELAY_DLPF_4;\r
- }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_3) {\r
- dlpf = ( unsigned char)DELAY_DLPF_3;\r
+ 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;\r
+ dlpf = ( unsigned char)DELAY_DLPF_2;
}
- reg = ( unsigned char)(( unsigned char)(EWTSA_range << 3) | dlpf | ( unsigned char)0x80 ) ;\r
-\r
- err = i2c_write_byte(client, REG_FS_DLPF, reg);\r
+ 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) { \r
- printk("EWTSA_set_calibration() start \n");\r
- err = i2c_write_byte(client,( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_ENABLE);\r
- if (err < 0) {\r
- return err;\r
- }\r
- mdelay(500); \r
- printk("EWTSA_set_calibration() end \n");\r
- \r
+ 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;\r
+ 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;
}
-\r
-static int ewtsa_disable(struct i2c_client *client)\r
+
+static int ewtsa_enable(struct i2c_client *client)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- \r
- gpio_direction_output(sensor->pdata->standby_pin, GPIO_HIGH);\r
-\r
- DBG("%s: end \n",__func__); \r
-\r
- return 0; \r
+ 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;
}
-\r
-static int ewtsa_enable(struct i2c_client *client)\r
+
+void gyro_dev_reset(struct i2c_client *client)
{
- int err;\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- \r
- gpio_direction_output(sensor->pdata->standby_pin, GPIO_LOW);\r
- err = i2c_write_byte(client, ( unsigned char)REG_PWR_MGM, ( unsigned char)SLEEP_CTRL_ACTIVATE);////0x44\r
- if (err < 0){\r
- //return err;\r
- err = ewtsa_system_restart(client);///restart; only when i2c error\r
- if (err < 0){\r
- return err;\r
- }\r
- }\r
-\r
- err = i2c_write_byte(client, ( unsigned char) REG_INT_CFG, ( unsigned char)INT_CFG_INT_ENABLE);\r
- if (err < 0) {\r
- return err;\r
- }\r
- DBG("%s: end \n",__func__); \r
- return 0;\r
+ 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);
}
-\r
-void gyro_dev_reset(struct i2c_client *client)\r
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
-\r
- \r
- DBG("%s\n",__func__);\r
- gpio_direction_output(sensor->pdata->standby_pin, GPIO_HIGH);\r
- msleep(100); \r
- gpio_direction_output(sensor->pdata->standby_pin, GPIO_LOW);\r
- msleep(100); \r
-}\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
/*
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int status = 0;\r
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int status = 0;
*/
int result = 0;
- if(enable)\r
- { \r
- result=ewtsa_enable(client);\r
- }\r
- else\r
- {\r
- result=ewtsa_disable(client);\r
- }\r
-\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0; \r
+ 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]; \r
- unsigned char data = 0;\r
- int i = 0;\r
- char pReadData=0;\r
+ unsigned char buf[5];
+ unsigned char data = 0;
+ int i = 0;
+ char pReadData=0;
*/
- sensor->status_cur = SENSOR_OFF;\r
- gyro_dev_reset(client);\r
- ewtsa_system_restart(client);\r
- return result;\r
-}\r
-\r
-\r
-static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
-\r
- /* Report GYRO information */\r
- input_report_rel(sensor->input_dev, ABS_RX, axis->x);\r
- input_report_rel(sensor->input_dev, ABS_RY, axis->y);\r
- input_report_rel(sensor->input_dev, ABS_RZ, axis->z);\r
- input_sync(sensor->input_dev);\r
- DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);\r
-\r
- return 0;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- struct sensor_platform_data *pdata = sensor->pdata;\r
- int ret = 0;\r
- int x = 0, y = 0, z = 0;\r
- struct sensor_axis axis;\r
- char buffer[6] = {0}; \r
- int i = 0;\r
+ 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; */
-\r
- memset(buffer, 0, 6);\r
-#if 0 \r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- buffer[0] = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-#else\r
-\r
- for(i=0; i<6; i++)\r
+
+ 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]);\r
- }\r
-#endif\r
- \r
- x = (short) (((buffer[0]) << 8) | buffer[1]);\r
- y = (short) (((buffer[2]) << 8) | buffer[3]);\r
- z = (short) (((buffer[4]) << 8) | buffer[5]);\r
-
- //printk("%s: x=%d y=%d z=%d \n",__func__, x,y,z);\r
+ 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))\r
- { \r
- gyro_report_value(client, &axis); \r
-\r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&(sensor->data_mutex) );\r
- sensor->axis = axis;\r
- mutex_unlock(&(sensor->data_mutex) );\r
- } \r
- \r
- return ret;\r
-}\r
-\r
-\r
-struct sensor_operate gyro_ewtsa_ops = {\r
- .name = "ewtsa",\r
- .type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct\r
- .id_i2c = GYRO_ID_EWTSA, //i2c id number\r
- .read_reg = GYRO_DATA_REG, //read data\r
- .read_len = 6, //data length\r
- .id_reg = -1, //read device id from this register\r
- .id_data = -1, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = REG_PWR_MGM, //enable or disable \r
- .int_status_reg = REG_INT_STATUS, //intterupt status register,if no exist then -1\r
- .range = {-32768,32768}, //range\r
- .trig = IRQF_TRIGGER_HIGH|IRQF_ONESHOT, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *gyro_get_ops(void)\r
-{\r
- return &gyro_ewtsa_ops;\r
-}\r
-\r
-\r
-static int __init gyro_ewtsa_init(void)\r
-{\r
- struct sensor_operate *ops = gyro_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit gyro_ewtsa_exit(void)\r
-{\r
- struct sensor_operate *ops = gyro_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);\r
-}\r
-\r
-\r
-module_init(gyro_ewtsa_init);\r
-module_exit(gyro_ewtsa_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/l3g4200d.h>\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define L3G4200D_ENABLE 0x08\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int status = 0;\r
- \r
- sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-\r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- status = L3G4200D_ENABLE; //l3g20d \r
- sensor->ops->ctrl_data |= status; \r
- }\r
- else\r
- {\r
- status = ~L3G4200D_ENABLE; //l3g20d\r
- sensor->ops->ctrl_data &= status;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0; \r
- unsigned char buf[5]; \r
- unsigned char data = 0;\r
- int i = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- \r
- buf[0] = 0x07; //27\r
- buf[1] = 0x00; \r
- buf[2] = 0x00; \r
- buf[3] = 0x20; //0x00\r
- buf[4] = 0x00; \r
- for(i=0; i<5; i++)\r
- {\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg+i, buf[i]);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- }\r
- \r
- result = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- if (result >= 0)\r
- data = result & 0x000F;\r
-
- sensor->ops->ctrl_data = data + ODR100_BW12_5; \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
-\r
- /* Report GYRO information */\r
- input_report_rel(sensor->input_dev, ABS_RX, axis->x);\r
- input_report_rel(sensor->input_dev, ABS_RY, axis->y);\r
- input_report_rel(sensor->input_dev, ABS_RZ, axis->z);\r
- input_sync(sensor->input_dev);\r
- DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);\r
-\r
- return 0;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- struct sensor_platform_data *pdata = sensor->pdata;\r
- int ret = 0;\r
- int x = 0, y = 0, z = 0;\r
- struct sensor_axis axis;\r
- char buffer[6] = {0}; \r
- int i = 0;\r
- int value = 0;\r
- \r
- if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 6);\r
-#if 0 \r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- buffer[0] = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-#else\r
-\r
- for(i=0; i<6; i++)\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/l3g4200d.h>
+#include <linux/sensor-dev.h>
+
+
+#define L3G4200D_ENABLE 0x08
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int status = 0;
+
+ sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ //register setting according to chip datasheet
+ if(enable)
{
- //buffer[i] = sensor->ops->read_reg + i; \r
- buffer[i] = sensor_read_reg(client, sensor->ops->read_reg + i);\r
- }\r
-#endif\r
- x = (short) (((buffer[1]) << 8) | buffer[0]);\r
- y = (short) (((buffer[3]) << 8) | buffer[2]);\r
- z = (short) (((buffer[5]) << 8) | buffer[4]);\r
+ 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))\r
- { \r
- gyro_report_value(client, &axis); \r
-\r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&(sensor->data_mutex) );\r
- sensor->axis = axis;\r
- mutex_unlock(&(sensor->data_mutex) );\r
- } \r
-\r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- DBG("%s:sensor int status :0x%x\n",__func__,value);\r
- }\r
- \r
- return ret;\r
-}\r
-\r
-\r
-static struct sensor_operate gyro_l3g20d_ops = {\r
- .name = "l3g20d",\r
- .type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct\r
- .id_i2c = GYRO_ID_L3G20D, //i2c id number\r
- .read_reg = GYRO_DATA_REG, //read data\r
- .read_len = 6, //data length\r
- .id_reg = GYRO_WHO_AM_I, //read device id from this register\r
- .id_data = GYRO_DEVID_L3G20D, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = GYRO_CTRL_REG1, //enable or disable \r
- .int_status_reg = GYRO_INT_SRC, //intterupt status register,if no exist then -1\r
- .range = {-32768,32768}, //range\r
- .trig = IRQF_TRIGGER_LOW|IRQF_ONESHOT, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *gyro_get_ops(void)\r
-{\r
- return &gyro_l3g20d_ops;\r
-}\r
-\r
-\r
-static int __init gyro_l3g20d_init(void)\r
-{\r
- struct sensor_operate *ops = gyro_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit gyro_l3g20d_exit(void)\r
-{\r
- struct sensor_operate *ops = gyro_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);\r
-}\r
-\r
-\r
-module_init(gyro_l3g20d_init);\r
-module_exit(gyro_l3g20d_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/l3g4200d.h>\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define L3G4200D_ENABLE 0x08\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int status = 0;\r
- \r
- sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-\r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- status = L3G4200D_ENABLE; //l3g4200d \r
- sensor->ops->ctrl_data |= status; \r
- }\r
- else\r
- {\r
- status = ~L3G4200D_ENABLE; //l3g4200d\r
- sensor->ops->ctrl_data &= status;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0; \r
- unsigned char buf[5]; \r
- unsigned char data = 0;\r
- int i = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- \r
- buf[0] = 0x07; //27\r
- buf[1] = 0x00; \r
- buf[2] = 0x00; \r
- buf[3] = 0x20; //0x00\r
- buf[4] = 0x00; \r
- for(i=0; i<5; i++)\r
- {\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg+i, buf[i]);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- }\r
- \r
- result = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- if (result >= 0)\r
- data = result & 0x000F;\r
-
- sensor->ops->ctrl_data = data + ODR100_BW12_5; \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int gyro_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
-\r
- /* Report GYRO information */\r
- input_report_rel(sensor->input_dev, ABS_RX, axis->x);\r
- input_report_rel(sensor->input_dev, ABS_RY, axis->y);\r
- input_report_rel(sensor->input_dev, ABS_RZ, axis->z);\r
- input_sync(sensor->input_dev);\r
- DBG("gyro x==%d y==%d z==%d\n",axis->x,axis->y,axis->z);\r
-\r
- return 0;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- struct sensor_platform_data *pdata = sensor->pdata;\r
- int ret = 0;\r
- int x = 0, y = 0, z = 0;\r
- struct sensor_axis axis;\r
- char buffer[6] = {0}; \r
- int i = 0;\r
- int value = 0;\r
- \r
- if(sensor->ops->read_len < 6) //sensor->ops->read_len = 6\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 6);\r
-#if 0 \r
- /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
- do {\r
- buffer[0] = sensor->ops->read_reg;\r
- ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
- if (ret < 0)\r
- return ret;\r
- } while (0);\r
-#else\r
-\r
- for(i=0; i<6; i++)\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/l3g4200d.h>
+#include <linux/sensor-dev.h>
+
+
+#define L3G4200D_ENABLE 0x08
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int status = 0;
+
+ sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ //register setting according to chip datasheet
+ if(enable)
{
- //buffer[i] = sensor->ops->read_reg + i; \r
- buffer[i] = sensor_read_reg(client, sensor->ops->read_reg + i);\r
- }\r
-#endif\r
- x = (short) (((buffer[1]) << 8) | buffer[0]);\r
- y = (short) (((buffer[3]) << 8) | buffer[2]);\r
- z = (short) (((buffer[5]) << 8) | buffer[4]);\r
+ 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))\r
- { \r
- gyro_report_value(client, &axis); \r
-\r
- /* »¥³âµØ»º´æÊý¾Ý. */\r
- mutex_lock(&(sensor->data_mutex) );\r
- sensor->axis = axis;\r
- mutex_unlock(&(sensor->data_mutex) );\r
- } \r
-\r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- DBG("%s:sensor int status :0x%x\n",__func__,value);\r
- }\r
- \r
- return ret;\r
-}\r
-\r
-\r
-struct sensor_operate gyro_l3g4200d_ops = {\r
- .name = "l3g4200d",\r
- .type = SENSOR_TYPE_GYROSCOPE,//sensor type and it should be correct\r
- .id_i2c = GYRO_ID_L3G4200D, //i2c id number\r
- .read_reg = GYRO_DATA_REG, //read data\r
- .read_len = 6, //data length\r
- .id_reg = GYRO_WHO_AM_I, //read device id from this register\r
- .id_data = GYRO_DEVID_L3G4200D, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = GYRO_CTRL_REG1, //enable or disable \r
- .int_status_reg = GYRO_INT_SRC, //intterupt status register,if no exist then -1\r
- .range = {-32768,32768}, //range\r
- .trig = IRQF_TRIGGER_LOW|IRQF_ONESHOT, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *gyro_get_ops(void)\r
-{\r
- return &gyro_l3g4200d_ops;\r
-}\r
-\r
-\r
-static int __init gyro_l3g4200d_init(void)\r
-{\r
- struct sensor_operate *ops = gyro_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit gyro_l3g4200d_exit(void)\r
-{\r
- struct sensor_operate *ops = gyro_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);\r
-}\r
-\r
-\r
-module_init(gyro_l3g4200d_init);\r
-module_exit(gyro_l3g4200d_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define CM3217_ADDR_COM1 0x10\r
-#define CM3217_ADDR_COM2 0x11\r
-#define CM3217_ADDR_DATA_MSB 0x10\r
-#define CM3217_ADDR_DATA_LSB 0x11\r
-\r
-#define CM3217_COM1_VALUE 0xA7 // (GAIN1:GAIN0)=10, (IT_T1:IT_TO)=01,WMD=1,SD=1,\r
-#define CM3217_COM2_VALUE 0xA0 //100ms\r
-\r
-#define CM3217_CLOSE 0x01\r
-\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int status = 0;\r
- \r
- sensor->client->addr = sensor->ops->ctrl_reg; \r
- sensor->ops->ctrl_data = sensor_read_reg_normal(client);\r
- \r
- //register setting according to chip datasheet \r
- if(!enable)\r
- { \r
- status = CM3217_CLOSE; //cm3217 \r
- sensor->ops->ctrl_data |= status; \r
- }\r
- else\r
- {\r
- status = ~CM3217_CLOSE; //cm3217\r
- sensor->ops->ctrl_data &= status;\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg_normal(client, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
- \r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- \r
- sensor->client->addr = sensor->ops->ctrl_reg; \r
- sensor->ops->ctrl_data = CM3217_COM1_VALUE; \r
- result = sensor_write_reg_normal(client, sensor->ops->ctrl_data);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->client->addr = CM3217_ADDR_COM2; \r
- result = sensor_write_reg_normal(client, CM3217_COM2_VALUE);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int light_report_value(struct input_dev *input, int data)\r
-{\r
- unsigned char index = 0;\r
- \r
- if(data <= 10){\r
- index = 0;goto report;\r
- }\r
- else if(data <= 160){\r
- index = 1;goto report;\r
- }\r
- else if(data <= 225){\r
- index = 2;goto report;\r
- }\r
- else if(data <= 320){\r
- index = 3;goto report;\r
- }\r
- else if(data <= 640){\r
- index = 4;goto report;\r
- }\r
- else if(data <= 1280){\r
- index = 5;goto report;\r
- }\r
- else if(data <= 2600){\r
- index = 6;goto report;\r
- }\r
- else{\r
- index = 7;goto report;\r
- }\r
-\r
-report:\r
- input_report_abs(input, ABS_MISC, index);\r
- input_sync(input);\r
-\r
- return index;\r
-}\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char msb = 0, lsb = 0;\r
- int index = 0;\r
- \r
- sensor->client->addr = CM3217_ADDR_DATA_LSB;\r
- sensor_rx_data_normal(sensor->client, &lsb, 1);\r
- sensor->client->addr = CM3217_ADDR_DATA_MSB;\r
- sensor_rx_data_normal(sensor->client, &msb, 1);\r
- result = ((msb << 8) | lsb) & 0xffff;\r
- \r
- index = light_report_value(sensor->input_dev, result);\r
- DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, result,index);\r
- \r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- result= sensor_read_reg(client, sensor->ops->int_status_reg);\r
- if(result)\r
- {\r
- printk("%s:fail to clear sensor int status,ret=0x%x\n",__func__,result);\r
- }\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-struct sensor_operate light_cm3217_ops = {\r
- .name = "cm3217",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_CM3217, //i2c id number\r
- .read_reg = CM3217_ADDR_DATA_LSB, //read data\r
- .read_len = 2, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = CM3217_ADDR_COM1, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
- .range = {100,65535}, //range\r
- .brightness ={10,255}, // brightness\r
- .trig = SENSOR_UNKNOW_DATA, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_cm3217_ops;\r
-}\r
-\r
-\r
-static int __init light_cm3217_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit light_cm3217_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-\r
-module_init(light_cm3217_init);\r
-module_exit(light_cm3217_exit);\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define CM3217_ADDR_COM1 0x10
+#define CM3217_ADDR_COM2 0x11
+#define CM3217_ADDR_DATA_MSB 0x10
+#define CM3217_ADDR_DATA_LSB 0x11
+
+#define CM3217_COM1_VALUE 0xA7 // (GAIN1:GAIN0)=10, (IT_T1:IT_TO)=01,WMD=1,SD=1,
+#define CM3217_COM2_VALUE 0xA0 //100ms
+
+#define CM3217_CLOSE 0x01
+
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int status = 0;
+
+ sensor->client->addr = sensor->ops->ctrl_reg;
+ sensor->ops->ctrl_data = sensor_read_reg_normal(client);
+
+ //register setting according to chip datasheet
+ if(!enable)
+ {
+ status = CM3217_CLOSE; //cm3217
+ sensor->ops->ctrl_data |= status;
+ }
+ else
+ {
+ status = ~CM3217_CLOSE; //cm3217
+ sensor->ops->ctrl_data &= status;
+ }
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg_normal(client, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ sensor->client->addr = sensor->ops->ctrl_reg;
+ sensor->ops->ctrl_data = CM3217_COM1_VALUE;
+ result = sensor_write_reg_normal(client, sensor->ops->ctrl_data);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->client->addr = CM3217_ADDR_COM2;
+ result = sensor_write_reg_normal(client, CM3217_COM2_VALUE);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ return result;
+}
+
+
+static int light_report_value(struct input_dev *input, int data)
+{
+ unsigned char index = 0;
+
+ if(data <= 10){
+ index = 0;goto report;
+ }
+ else if(data <= 160){
+ index = 1;goto report;
+ }
+ else if(data <= 225){
+ index = 2;goto report;
+ }
+ else if(data <= 320){
+ index = 3;goto report;
+ }
+ else if(data <= 640){
+ index = 4;goto report;
+ }
+ else if(data <= 1280){
+ index = 5;goto report;
+ }
+ else if(data <= 2600){
+ index = 6;goto report;
+ }
+ else{
+ index = 7;goto report;
+ }
+
+report:
+ input_report_abs(input, ABS_MISC, index);
+ input_sync(input);
+
+ return index;
+}
+
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char msb = 0, lsb = 0;
+ int index = 0;
+
+ sensor->client->addr = CM3217_ADDR_DATA_LSB;
+ sensor_rx_data_normal(sensor->client, &lsb, 1);
+ sensor->client->addr = CM3217_ADDR_DATA_MSB;
+ sensor_rx_data_normal(sensor->client, &msb, 1);
+ result = ((msb << 8) | lsb) & 0xffff;
+
+ index = light_report_value(sensor->input_dev, result);
+ DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, result,index);
+
+ if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
+ {
+
+ result= sensor_read_reg(client, sensor->ops->int_status_reg);
+ if(result)
+ {
+ printk("%s:fail to clear sensor int status,ret=0x%x\n",__func__,result);
+ }
+ }
+
+ return result;
+}
+
+
+struct sensor_operate light_cm3217_ops = {
+ .name = "cm3217",
+ .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
+ .id_i2c = LIGHT_ID_CM3217, //i2c id number
+ .read_reg = CM3217_ADDR_DATA_LSB, //read data
+ .read_len = 2, //data length
+ .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
+ .id_data = SENSOR_UNKNOW_DATA, //device id
+ .precision = 8, //8 bits
+ .ctrl_reg = CM3217_ADDR_COM1, //enable or disable
+ .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
+ .range = {100,65535}, //range
+ .brightness ={10,255}, // brightness
+ .trig = SENSOR_UNKNOW_DATA,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *light_get_ops(void)
+{
+ return &light_cm3217_ops;
+}
+
+
+static int __init light_cm3217_init(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, light_get_ops);
+ return result;
+}
+
+static void __exit light_cm3217_exit(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, light_get_ops);
+}
+
+
+module_init(light_cm3217_init);
+module_exit(light_cm3217_exit);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define CM3232_CLOSE 0x01\r
-\r
-\r
-#define CM3232_ADDR_COM 0\r
-#define CM3232_ADDR_DATA 50 \r
-\r
-#define CM3232_DRV_NAME "cm3232"\r
-//command code\r
-#define COMMAND_CTRL 0\r
-#define COMMAND_ALS_DATA 50 //ALS: 15:8 MSB 8bits data\r
- //7:0 LSB 8bits data\r
-\r
-//ctrl bit\r
-#define ALS_RESET(x) (((x)&1)<<6) //0 = Reset disable; 1 = Reset enable\r
-#define ALS_IT(x) (((x)&7)<<2) //ALS integration time setting\r
-#define HIGH_SENSITIVITY(x) (((x)&1)<<1) //0 = Normal mode; 1 = High sensitivity mode\r
-#define SHUT_DOWN(x) (((x)&1)<<0) //ALS shut down setting: 0 = ALS Power on ; 1 = ALS Shut down\r
-\r
-#define ALS_IT100MS 0 //100ms\r
-#define ALS_IT200MS 1 //200ms\r
-#define ALS_IT400MS 2 //400ms\r
-#define ALS_IT800MS 3 //800ms\r
-#define ALS_IT1600MS 4 //1600ms\r
-#define ALS_IT3200MS 5 //3200ms\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- //int status = 0;\r
- \r
- //sensor->client->addr = sensor->ops->ctrl_reg; \r
- //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- //printk("%s: client addr = %#x\n\n", __func__, client->addr); \r
- //register setting according to chip datasheet \r
- if (enable) {\r
- sensor->ops->ctrl_data = ALS_RESET(1); \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result) {\r
- printk("%s:fail to active sensor\n",__func__);\r
- return -1;\r
- }\r
- }\r
-\r
- if(enable)\r
- { \r
- sensor->ops->ctrl_data = ALS_IT(ALS_IT200MS) | HIGH_SENSITIVITY(1);\r
- }\r
- else\r
- {\r
- sensor->ops->ctrl_data = SHUT_DOWN(1);\r
- }\r
-\r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
-\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
- \r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- return result;\r
-}\r
-\r
-\r
-static int light_report_value(struct input_dev *input, int data)\r
-{\r
- unsigned char index = 0;\r
- \r
- if(data <= 10){\r
- index = 0;goto report;\r
- }\r
- else if(data <= 160){\r
- index = 1;goto report;\r
- }\r
- else if(data <= 225){\r
- index = 2;goto report;\r
- }\r
- else if(data <= 320){\r
- index = 3;goto report;\r
- }\r
- else if(data <= 640){\r
- index = 4;goto report;\r
- }\r
- else if(data <= 1280){\r
- index = 5;goto report;\r
- }\r
- else if(data <= 2600){\r
- index = 6;goto report;\r
- }\r
- else{\r
- index = 7;goto report;\r
- }\r
-\r
-report:\r
- input_report_abs(input, ABS_MISC, index);\r
- input_sync(input);\r
- \r
- return index;\r
-}\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- //char msb = 0, lsb = 0;\r
- char data[2] = {0};\r
- unsigned short value = 0;\r
- int index = 0;\r
- \r
- //sensor->client->addr = CM3232_ADDR_DATA;\r
- data[0] = CM3232_ADDR_DATA;\r
- sensor_rx_data(sensor->client, data, 2);\r
- value = (data[1] << 8) | data[0] ;\r
-\r
- DBG("%s:result=%d\n",__func__,value);\r
- //printk("%s:result=%d\n",__func__,value);\r
- index = light_report_value(sensor->input_dev, value); \r
- DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
-\r
- if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
- {\r
- \r
- result= sensor_read_reg(client, sensor->ops->int_status_reg);\r
- if(result)\r
- {\r
- printk("%s:fail to clear sensor int status,ret=0x%x\n",__func__,result);\r
- }\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-struct sensor_operate light_cm3232_ops = {\r
- .name = "cm3232",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_CM3232, //i2c id number\r
- .read_reg = CM3232_ADDR_DATA, //read data\r
- .read_len = 2, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = CM3232_ADDR_COM, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
- .range = {100,65535}, //range\r
- .brightness = {10,255}, // brightness\r
- .trig = SENSOR_UNKNOW_DATA, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_cm3232_ops;\r
-}\r
-\r
-\r
-static int __init light_cm3232_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit light_cm3232_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-\r
-module_init(light_cm3232_init);\r
-module_exit(light_cm3232_exit);\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define CM3232_CLOSE 0x01
+
+
+#define CM3232_ADDR_COM 0
+#define CM3232_ADDR_DATA 50
+
+#define CM3232_DRV_NAME "cm3232"
+//command code
+#define COMMAND_CTRL 0
+#define COMMAND_ALS_DATA 50 //ALS: 15:8 MSB 8bits data
+ //7:0 LSB 8bits data
+
+//ctrl bit
+#define ALS_RESET(x) (((x)&1)<<6) //0 = Reset disable; 1 = Reset enable
+#define ALS_IT(x) (((x)&7)<<2) //ALS integration time setting
+#define HIGH_SENSITIVITY(x) (((x)&1)<<1) //0 = Normal mode; 1 = High sensitivity mode
+#define SHUT_DOWN(x) (((x)&1)<<0) //ALS shut down setting: 0 = ALS Power on ; 1 = ALS Shut down
+
+#define ALS_IT100MS 0 //100ms
+#define ALS_IT200MS 1 //200ms
+#define ALS_IT400MS 2 //400ms
+#define ALS_IT800MS 3 //800ms
+#define ALS_IT1600MS 4 //1600ms
+#define ALS_IT3200MS 5 //3200ms
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ //int status = 0;
+
+ //sensor->client->addr = sensor->ops->ctrl_reg;
+ //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+ //printk("%s: client addr = %#x\n\n", __func__, client->addr);
+ //register setting according to chip datasheet
+ if (enable) {
+ sensor->ops->ctrl_data = ALS_RESET(1);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result) {
+ printk("%s:fail to active sensor\n",__func__);
+ return -1;
+ }
+ }
+
+ if(enable)
+ {
+ sensor->ops->ctrl_data = ALS_IT(ALS_IT200MS) | HIGH_SENSITIVITY(1);
+ }
+ else
+ {
+ sensor->ops->ctrl_data = SHUT_DOWN(1);
+ }
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+ return result;
+}
+
+
+static int light_report_value(struct input_dev *input, int data)
+{
+ unsigned char index = 0;
+
+ if(data <= 10){
+ index = 0;goto report;
+ }
+ else if(data <= 160){
+ index = 1;goto report;
+ }
+ else if(data <= 225){
+ index = 2;goto report;
+ }
+ else if(data <= 320){
+ index = 3;goto report;
+ }
+ else if(data <= 640){
+ index = 4;goto report;
+ }
+ else if(data <= 1280){
+ index = 5;goto report;
+ }
+ else if(data <= 2600){
+ index = 6;goto report;
+ }
+ else{
+ index = 7;goto report;
+ }
+
+report:
+ input_report_abs(input, ABS_MISC, index);
+ input_sync(input);
+
+ return index;
+}
+
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ //char msb = 0, lsb = 0;
+ char data[2] = {0};
+ unsigned short value = 0;
+ int index = 0;
+
+ //sensor->client->addr = CM3232_ADDR_DATA;
+ data[0] = CM3232_ADDR_DATA;
+ sensor_rx_data(sensor->client, data, 2);
+ value = (data[1] << 8) | data[0] ;
+
+ DBG("%s:result=%d\n",__func__,value);
+ //printk("%s:result=%d\n",__func__,value);
+ index = light_report_value(sensor->input_dev, value);
+ DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
+
+ if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
+ {
+
+ result= sensor_read_reg(client, sensor->ops->int_status_reg);
+ if(result)
+ {
+ printk("%s:fail to clear sensor int status,ret=0x%x\n",__func__,result);
+ }
+ }
+
+ return result;
+}
+
+
+struct sensor_operate light_cm3232_ops = {
+ .name = "cm3232",
+ .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
+ .id_i2c = LIGHT_ID_CM3232, //i2c id number
+ .read_reg = CM3232_ADDR_DATA, //read data
+ .read_len = 2, //data length
+ .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
+ .id_data = SENSOR_UNKNOW_DATA, //device id
+ .precision = 8, //8 bits
+ .ctrl_reg = CM3232_ADDR_COM, //enable or disable
+ .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
+ .range = {100,65535}, //range
+ .brightness = {10,255}, // brightness
+ .trig = SENSOR_UNKNOW_DATA,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *light_get_ops(void)
+{
+ return &light_cm3232_ops;
+}
+
+
+static int __init light_cm3232_init(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, light_get_ops);
+ return result;
+}
+
+static void __exit light_cm3232_exit(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, light_get_ops);
+}
+
+
+module_init(light_cm3232_init);
+module_exit(light_cm3232_exit);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define ISL29023_REG_ADD_COMMAND1 0x00\r
-#define COMMMAND1_OPMODE_SHIFT 5\r
-#define COMMMAND1_OPMODE_MASK (7 << COMMMAND1_OPMODE_SHIFT)\r
-#define COMMMAND1_OPMODE_POWER_DOWN (0 << COMMMAND1_OPMODE_SHIFT)\r
-#define COMMMAND1_OPMODE_ALS_ONCE (1 << COMMMAND1_OPMODE_SHIFT)\r
-#define COMMMAND1_OPMODE_IR_ONCE (2 << COMMMAND1_OPMODE_SHIFT)\r
-#define COMMMAND1_OPMODE_ALS_CONTINUE (5 << COMMMAND1_OPMODE_SHIFT)\r
-#define COMMMAND1_OPMODE_IR_CONTINUE (6 << COMMMAND1_OPMODE_SHIFT)\r
-\r
-\r
-#define ISL29023_REG_ADD_COMMANDII 0x01\r
-#define COMMANDII_RESOLUTION_SHIFT 2\r
-#define COMMANDII_RESOLUTION_65536 (0x0 << COMMANDII_RESOLUTION_SHIFT)\r
-#define COMMANDII_RESOLUTION_4096 (0x1 << COMMANDII_RESOLUTION_SHIFT)\r
-#define COMMANDII_RESOLUTION_256 (0x2 << COMMANDII_RESOLUTION_SHIFT)\r
-#define COMMANDII_RESOLUTION_16 (0x3 << COMMANDII_RESOLUTION_SHIFT)\r
-#define COMMANDII_RESOLUTION_MASK (0x3 << COMMANDII_RESOLUTION_SHIFT)\r
-\r
-#define COMMANDII_RANGE_SHIFT 0\r
-#define COMMANDII_RANGE_1000 (0x0 << COMMANDII_RANGE_SHIFT)\r
-#define COMMANDII_RANGE_4000 (0x1 << COMMANDII_RANGE_SHIFT)\r
-#define COMMANDII_RANGE_16000 (0x2 << COMMANDII_RANGE_SHIFT)\r
-#define COMMANDII_RANGE_64000 (0x3 << COMMANDII_RANGE_SHIFT)\r
-#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)\r
-\r
-\r
-#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)\r
-\r
-#define COMMANDII_SCHEME_SHIFT 7\r
-#define COMMANDII_SCHEME_MASK (0x1 << COMMANDII_SCHEME_SHIFT)\r
-\r
-#define ISL29023_REG_ADD_DATA_LSB 0x02\r
-#define ISL29023_REG_ADD_DATA_MSB 0x03\r
-#define ISL29023_MAX_REGS ISL29023_REG_ADD_DATA_MSB\r
-\r
-#define ISL29023_REG_LT_LSB 0x04\r
-#define ISL29023_REG_LT_MSB 0x05\r
-#define ISL29023_REG_HT_LSB 0x06\r
-#define ISL29023_REG_HT_MSB 0x07\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- //int status = 0;\r
-\r
- sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- sensor->ops->ctrl_data &= 0x1f; \r
- sensor->ops->ctrl_data |= COMMMAND1_OPMODE_ALS_CONTINUE; \r
- }\r
- else\r
- {\r
- sensor->ops->ctrl_data &= 0x1f; \r
- //sensor->ops->ctrl_data |= COMMMAND1_OPMODE_POWER_DOWN; \r
- }\r
- \r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- if(enable)\r
- sensor->ops->report(sensor->client);\r
- \r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- result = sensor_write_reg(client, ISL29023_REG_ADD_COMMANDII, COMMANDII_RANGE_4000 | COMMANDII_RESOLUTION_4096);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int light_report_value(struct input_dev *input, int data)\r
-{\r
- unsigned char index = 0;\r
-\r
- if(data <= 2){\r
- index = 0;goto report;\r
- }\r
- else if(data <= 3){\r
- index = 2;goto report;\r
- }\r
- else if(data <= 5){\r
- index = 3;goto report;\r
- }\r
- else if(data <= 8){\r
- index = 4;goto report;\r
- }\r
- else if(data <= 11){\r
- index = 5;goto report;\r
- }\r
- else if(data <= 14){\r
- index = 6;goto report;\r
- }\r
- else if(data <= 17){\r
- index = 7;goto report;\r
- }\r
- else{\r
- index = 7;goto report;\r
- }\r
-\r
-report:\r
- input_report_abs(input, ABS_MISC, index);\r
- input_sync(input);\r
- \r
- return index;\r
-}\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int value = 0;\r
- char buffer[2] = {0}; \r
- char index = 0;\r
- \r
- if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 2);\r
-\r
- buffer[0] = sensor->ops->read_reg;\r
- result = sensor_rx_data(client, buffer, sensor->ops->read_len); \r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- value = (buffer[1] << 8) | buffer[0];\r
-\r
- \r
- index = light_report_value(sensor->input_dev, value);\r
-\r
- DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(sensor->ops->int_status_reg)\r
- { \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- }\r
- \r
- }\r
- \r
- \r
- return result;\r
-}\r
-\r
-struct sensor_operate light_isl29023_ops = {\r
- .name = "ls_isl29023",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_ISL29023, //i2c id number\r
- .read_reg = ISL29023_REG_ADD_DATA_LSB, //read data\r
- .read_len = 2, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 16, //8 bits\r
- .ctrl_reg = ISL29023_REG_ADD_COMMAND1, //enable or disable \r
- .int_status_reg = ISL29023_REG_ADD_COMMAND1, //intterupt status register\r
- .range = {100,65535}, //range\r
- .brightness ={10,255}, //brightness\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_isl29023_ops;\r
-}\r
-\r
-\r
-static int __init light_isl29023_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit light_isl29023_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-\r
-module_init(light_isl29023_init);\r
-module_exit(light_isl29023_exit);\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define ISL29023_REG_ADD_COMMAND1 0x00
+#define COMMMAND1_OPMODE_SHIFT 5
+#define COMMMAND1_OPMODE_MASK (7 << COMMMAND1_OPMODE_SHIFT)
+#define COMMMAND1_OPMODE_POWER_DOWN (0 << COMMMAND1_OPMODE_SHIFT)
+#define COMMMAND1_OPMODE_ALS_ONCE (1 << COMMMAND1_OPMODE_SHIFT)
+#define COMMMAND1_OPMODE_IR_ONCE (2 << COMMMAND1_OPMODE_SHIFT)
+#define COMMMAND1_OPMODE_ALS_CONTINUE (5 << COMMMAND1_OPMODE_SHIFT)
+#define COMMMAND1_OPMODE_IR_CONTINUE (6 << COMMMAND1_OPMODE_SHIFT)
+
+
+#define ISL29023_REG_ADD_COMMANDII 0x01
+#define COMMANDII_RESOLUTION_SHIFT 2
+#define COMMANDII_RESOLUTION_65536 (0x0 << COMMANDII_RESOLUTION_SHIFT)
+#define COMMANDII_RESOLUTION_4096 (0x1 << COMMANDII_RESOLUTION_SHIFT)
+#define COMMANDII_RESOLUTION_256 (0x2 << COMMANDII_RESOLUTION_SHIFT)
+#define COMMANDII_RESOLUTION_16 (0x3 << COMMANDII_RESOLUTION_SHIFT)
+#define COMMANDII_RESOLUTION_MASK (0x3 << COMMANDII_RESOLUTION_SHIFT)
+
+#define COMMANDII_RANGE_SHIFT 0
+#define COMMANDII_RANGE_1000 (0x0 << COMMANDII_RANGE_SHIFT)
+#define COMMANDII_RANGE_4000 (0x1 << COMMANDII_RANGE_SHIFT)
+#define COMMANDII_RANGE_16000 (0x2 << COMMANDII_RANGE_SHIFT)
+#define COMMANDII_RANGE_64000 (0x3 << COMMANDII_RANGE_SHIFT)
+#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)
+
+
+#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)
+
+#define COMMANDII_SCHEME_SHIFT 7
+#define COMMANDII_SCHEME_MASK (0x1 << COMMANDII_SCHEME_SHIFT)
+
+#define ISL29023_REG_ADD_DATA_LSB 0x02
+#define ISL29023_REG_ADD_DATA_MSB 0x03
+#define ISL29023_MAX_REGS ISL29023_REG_ADD_DATA_MSB
+
+#define ISL29023_REG_LT_LSB 0x04
+#define ISL29023_REG_LT_MSB 0x05
+#define ISL29023_REG_HT_LSB 0x06
+#define ISL29023_REG_HT_MSB 0x07
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ //int status = 0;
+
+ sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ //register setting according to chip datasheet
+ if(enable)
+ {
+ sensor->ops->ctrl_data &= 0x1f;
+ sensor->ops->ctrl_data |= COMMMAND1_OPMODE_ALS_CONTINUE;
+ }
+ else
+ {
+ sensor->ops->ctrl_data &= 0x1f;
+ //sensor->ops->ctrl_data |= COMMMAND1_OPMODE_POWER_DOWN;
+ }
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ if(enable)
+ sensor->ops->report(sensor->client);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ result = sensor_write_reg(client, ISL29023_REG_ADD_COMMANDII, COMMANDII_RANGE_4000 | COMMANDII_RESOLUTION_4096);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ return result;
+}
+
+
+static int light_report_value(struct input_dev *input, int data)
+{
+ unsigned char index = 0;
+
+ if(data <= 2){
+ index = 0;goto report;
+ }
+ else if(data <= 3){
+ index = 2;goto report;
+ }
+ else if(data <= 5){
+ index = 3;goto report;
+ }
+ else if(data <= 8){
+ index = 4;goto report;
+ }
+ else if(data <= 11){
+ index = 5;goto report;
+ }
+ else if(data <= 14){
+ index = 6;goto report;
+ }
+ else if(data <= 17){
+ index = 7;goto report;
+ }
+ else{
+ index = 7;goto report;
+ }
+
+report:
+ input_report_abs(input, ABS_MISC, index);
+ input_sync(input);
+
+ return index;
+}
+
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int value = 0;
+ char buffer[2] = {0};
+ char index = 0;
+
+ if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2
+ {
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+ return -1;
+ }
+
+ memset(buffer, 0, 2);
+
+ buffer[0] = sensor->ops->read_reg;
+ result = sensor_rx_data(client, buffer, sensor->ops->read_len);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ value = (buffer[1] << 8) | buffer[0];
+
+
+ index = light_report_value(sensor->input_dev, value);
+
+ DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
+
+ if(sensor->pdata->irq_enable)
+ {
+ if(sensor->ops->int_status_reg)
+ {
+ value = sensor_read_reg(client, sensor->ops->int_status_reg);
+ }
+
+ }
+
+
+ return result;
+}
+
+struct sensor_operate light_isl29023_ops = {
+ .name = "ls_isl29023",
+ .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
+ .id_i2c = LIGHT_ID_ISL29023, //i2c id number
+ .read_reg = ISL29023_REG_ADD_DATA_LSB, //read data
+ .read_len = 2, //data length
+ .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
+ .id_data = SENSOR_UNKNOW_DATA, //device id
+ .precision = 16, //8 bits
+ .ctrl_reg = ISL29023_REG_ADD_COMMAND1, //enable or disable
+ .int_status_reg = ISL29023_REG_ADD_COMMAND1, //intterupt status register
+ .range = {100,65535}, //range
+ .brightness ={10,255}, //brightness
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *light_get_ops(void)
+{
+ return &light_isl29023_ops;
+}
+
+
+static int __init light_isl29023_init(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, light_get_ops);
+ return result;
+}
+
+static void __exit light_isl29023_exit(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, light_get_ops);
+}
+
+
+module_init(light_isl29023_init);
+module_exit(light_isl29023_exit);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define CONFIG_REG (0x00)\r
-#define TIM_CTL_REG (0x01)\r
-#define ALS_CTL_REG (0x02)\r
-#define INT_STATUS_REG (0x03)\r
-#define PS_CTL_REG (0x04)\r
-#define PS_ALS_DATA_REG (0x05)\r
-#define ALS_WINDOWS_REG (0x08)\r
-\r
-//enable bit[ 0-1], in register CONFIG_REG\r
-#define ONLY_ALS_EN (0x00)\r
-#define ONLY_PROX_EN (0x01)\r
-#define ALL_PROX_ALS_EN (0x02)\r
-#define ALL_IDLE (0x03)\r
-\r
-#define POWER_MODE_MASK (0x0C)\r
-#define POWER_UP_MODE (0x00)\r
-#define POWER_DOWN_MODE (0x08)\r
-#define POWER_RESET_MODE (0x0C)\r
-\r
-static int sensor_power_updown(struct i2c_client *client, int on)\r
-{\r
- int result = 0;\r
- char value = 0;\r
- int i = 0;\r
- for(i=0; i<3; i++)\r
- {\r
- if(!on)\r
- {\r
- value = sensor_read_reg(client, CONFIG_REG);\r
- value &= ~POWER_MODE_MASK;\r
- value |= POWER_DOWN_MODE;\r
- result = sensor_write_reg(client, CONFIG_REG, value);\r
- if(result)\r
- return result;\r
- }\r
- else\r
- {\r
- value = sensor_read_reg(client, CONFIG_REG);\r
- value &= ~POWER_MODE_MASK;\r
- value |= POWER_UP_MODE;\r
- result = sensor_write_reg(client, CONFIG_REG, value);\r
- if(result)\r
- return result;\r
- }\r
- \r
- if(!result)\r
- break;\r
- }\r
-\r
- if(i>1)\r
- printk("%s:set %d times",__func__,i);\r
- \r
- return result;\r
-}\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
-\r
- if(enable) \r
- sensor_power_updown(client, 1);\r
-\r
- value = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- if( (value & 0x03) == ONLY_PROX_EN )\r
- {\r
- value &= ~0x03;\r
- value |= ALL_PROX_ALS_EN;\r
- }\r
- else if((value & 0x03) == ALL_IDLE )\r
- {\r
- value &= ~0x03;\r
- value |= ONLY_ALS_EN;\r
- }\r
-\r
- }\r
- else\r
- {\r
- if( (value & 0x03) == ONLY_ALS_EN )\r
- {\r
- value &= ~0x03;\r
- value |= ALL_IDLE;\r
- }\r
- else if((value & 0x03) == ALL_PROX_ALS_EN )\r
- {\r
- value &= ~0x03;\r
- value |= ONLY_PROX_EN;\r
- }\r
- \r
- }\r
- \r
- sensor->ops->ctrl_data = value;\r
- \r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- \r
- sensor_power_updown(client, 0);\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- value = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define CONFIG_REG (0x00)
+#define TIM_CTL_REG (0x01)
+#define ALS_CTL_REG (0x02)
+#define INT_STATUS_REG (0x03)
+#define PS_CTL_REG (0x04)
+#define PS_ALS_DATA_REG (0x05)
+#define ALS_WINDOWS_REG (0x08)
+
+//enable bit[ 0-1], in register CONFIG_REG
+#define ONLY_ALS_EN (0x00)
+#define ONLY_PROX_EN (0x01)
+#define ALL_PROX_ALS_EN (0x02)
+#define ALL_IDLE (0x03)
+
+#define POWER_MODE_MASK (0x0C)
+#define POWER_UP_MODE (0x00)
+#define POWER_DOWN_MODE (0x08)
+#define POWER_RESET_MODE (0x0C)
+
+static int sensor_power_updown(struct i2c_client *client, int on)
+{
+ int result = 0;
+ char value = 0;
+ int i = 0;
+ for(i=0; i<3; i++)
+ {
+ if(!on)
+ {
+ value = sensor_read_reg(client, CONFIG_REG);
+ value &= ~POWER_MODE_MASK;
+ value |= POWER_DOWN_MODE;
+ result = sensor_write_reg(client, CONFIG_REG, value);
+ if(result)
+ return result;
+ }
+ else
+ {
+ value = sensor_read_reg(client, CONFIG_REG);
+ value &= ~POWER_MODE_MASK;
+ value |= POWER_UP_MODE;
+ result = sensor_write_reg(client, CONFIG_REG, value);
+ if(result)
+ return result;
+ }
+
+ if(!result)
+ break;
+ }
+
+ if(i>1)
+ printk("%s:set %d times",__func__,i);
+
+ return result;
+}
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+
+ if(enable)
+ sensor_power_updown(client, 1);
+
+ value = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ //register setting according to chip datasheet
+ if(enable)
+ {
+ if( (value & 0x03) == ONLY_PROX_EN )
+ {
+ value &= ~0x03;
+ value |= ALL_PROX_ALS_EN;
+ }
+ else if((value & 0x03) == ALL_IDLE )
+ {
+ value &= ~0x03;
+ value |= ONLY_ALS_EN;
+ }
+
+ }
+ else
+ {
+ if( (value & 0x03) == ONLY_ALS_EN )
+ {
+ value &= ~0x03;
+ value |= ALL_IDLE;
+ }
+ else if((value & 0x03) == ALL_PROX_ALS_EN )
+ {
+ value &= ~0x03;
+ value |= ONLY_PROX_EN;
+ }
+
+ }
+
+ sensor->ops->ctrl_data = value;
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+
+ sensor_power_updown(client, 0);
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ value = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
//value = 0x69; //The ADC effective resolution = 17; Low lux threshold level = 9;
- result = sensor_write_reg(client, ALS_CTL_REG, value);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
+ 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% \r
- result = sensor_write_reg(client, ALS_WINDOWS_REG, value);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int light_report_value(struct input_dev *input, int data)\r
-{\r
- unsigned char index = 0;\r
- if(data <= 0){\r
- index = 0;goto report;\r
- }\r
- else if(data <= 2){\r
- index = 1;goto report;\r
- }\r
- else if(data <= 4){\r
- index = 2;goto report;\r
- }\r
- else if(data <= 8){\r
- index = 3;goto report;\r
- }\r
- else if(data <= 14){\r
- index = 4;goto report;\r
- }\r
- else if(data <= 20){\r
- index = 5;goto report;\r
- }\r
- else if(data <= 26){\r
- index = 6;goto report;\r
- }\r
- else{\r
- index = 7;goto report;\r
- }\r
-\r
-report:\r
- input_report_abs(input, ABS_MISC, index);\r
- input_sync(input);\r
-\r
- return index;\r
-}\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- char index = 0;\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(sensor->ops->int_status_reg)\r
- {\r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- }\r
- \r
- }\r
-\r
- value = sensor_read_reg(client, sensor->ops->read_reg);\r
- index = light_report_value(sensor->input_dev, value&0x3f); // bit0-5 is ls data;\r
- \r
- DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
- \r
- return result;\r
-}\r
-\r
-struct sensor_operate light_al3006_ops = {\r
- .name = "ls_al3006",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_AL3006, //i2c id number\r
- .read_reg = PS_ALS_DATA_REG, //read data\r
- .read_len = 1, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = CONFIG_REG, //enable or disable \r
- .int_status_reg = INT_STATUS_REG, //intterupt status register\r
- .range = {100,65535}, //range\r
- .brightness ={10,255}, // brightness\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_al3006_ops;\r
-}\r
-\r
-\r
-static int __init light_al3006_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit light_al3006_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-\r
-module_init(light_al3006_init);\r
-module_exit(light_al3006_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <mach/gpio.h>\r
-#include <mach/board.h> \r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
#define AP3212B_NUM_CACHABLE_REGS 23
-#define AP3216C_NUM_CACHABLE_REGS 26\r
-\r
+#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\r
-\r
+#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
-\r
+
#define AL3212_ADC_LSB 0x0c
#define AL3212_ADC_MSB 0x0d
-\r
+
#define AP3212B_ALS_LTHL 0x1a
#define AP3212B_ALS_LTHL_SHIFT (0)
#define AP3212B_ALS_LTHL_MASK 0xff
#define AP3212B_ALS_HTHH 0x1d
#define AP3212B_ALS_HTHH_SHIFT (0)
#define AP3212B_ALS_HTHH_MASK 0xff
-\r
-static u16 ap321xx_threshole[8] = {28,444,625,888,1778,3555,7222,0xffff};\r
-\r
+
+static u16 ap321xx_threshole[8] = {28,444,625,888,1778,3555,7222,0xffff};
+
/*
* register access helpers
*/
static int __ap321xx_read_reg(struct i2c_client *client,
u32 reg, u8 mask, u8 shift)
{
- u8 val;\r
-\r
- val = i2c_smbus_read_byte_data(client, reg);\r
- return (val & mask) >> shift;\r
+ 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;\r
+ int ret = 0;
u8 tmp;
-\r
- tmp = i2c_smbus_read_byte_data(client, reg);\r
+
+ tmp = i2c_smbus_read_byte_data(client, reg);
tmp &= ~mask;
tmp |= val << shift;
- ret = i2c_smbus_write_byte_data(client, reg, tmp);\r
- \r
- return ret;\r
+ ret = i2c_smbus_write_byte_data(client, reg, tmp);
+
+ return ret;
}
-\r
-\r
+
+
/*
* internally used functions
- */\r
+ */
/* range */
-static int ap321xx_set_range(struct i2c_client *client, int range)\r
+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);;
/* mode */
static int ap321xx_get_mode(struct i2c_client *client)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
int ret;
- ret = __ap321xx_read_reg(client, sensor->ops->ctrl_reg,\r
+ 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)\r
+static int ap321xx_set_mode(struct i2c_client *client, int mode)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int ret;\r
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int ret;
- ret = __ap321xx_write_reg(client, sensor->ops->ctrl_reg,\r
+ ret = __ap321xx_write_reg(client, sensor->ops->ctrl_reg,
AP3212B_MODE_MASK, AP3212B_MODE_SHIFT, mode);
return ret;
-}\r
-\r
+}
+
static int ap321xx_get_adc_value(struct i2c_client *client)
{
unsigned int lsb, msb, val;
- unsigned char index=0;\r
+ unsigned char index=0;
- lsb = i2c_smbus_read_byte_data(client, AL3212_ADC_LSB);\r
+ 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);\r
+ msb = i2c_smbus_read_byte_data(client, AL3212_ADC_MSB);
if (msb < 0)
return msb;
- val = msb << 8 | lsb;\r
+ val = msb << 8 | lsb;
for(index = 0; index < 7 && val > ap321xx_threshole[index];index++)
;
return index;
-}\r
-\r
-/* ALS low threshold */\r
+}
+
+/* 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;
return err;
}
-/* ALS high threshold */\r
+/* 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)
AP3212B_ALS_HTHH_MASK, AP3212B_ALS_HTHH_SHIFT, msb);
return err;
-}\r
-\r
+}
+
static int ap321xx_get_intstat(struct i2c_client *client)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ 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);\r
+
+ val = i2c_smbus_read_byte_data(client, sensor->ops->int_status_reg);
val &= AP3212B_INT_MASK;
return val >> AP3212B_INT_SHIFT;
-}\r
-\r
-static int ap321xx_product_detect(struct i2c_client *client)\r
+}
+
+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);\r
- }\r
- 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);\r
- }\r
+ //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);\r
+ //printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
return -EIO;
}
-\r
+
return 0;
-}\r
-\r
+}
+
static int ap321xx_init_client(struct i2c_client *client)
{
- /* set defaults */\r
+ /* set defaults */
ap321xx_set_range(client, 0);
ap321xx_set_mode(client, 0);
return 0;
-}\r
-\r
+}
+
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;
mode = 0;
ret = ap321xx_set_mode(client,mode);
}
-
+
return ret;
-}\r
-\r
+}
+
static void ap321xx_change_ls_threshold(struct i2c_client *client)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ 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);\r
+ 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]);
ap321xx_set_althres(client,0);
ap321xx_set_ahthres(client,ap321xx_threshole[value]);
}
-
- input_report_abs(sensor->input_dev, ABS_MISC, value);\r
- input_sync(sensor->input_dev);\r
-}\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- int result = 0;\r
- \r
- //register setting according to chip datasheet \r
- if (enable){\r
- result = ap321xx_lsensor_enable(client);\r
- if(!result){\r
- msleep(200);\r
- ap321xx_change_ls_threshold(client);\r
- }\r
- }\r
- else\r
- result = ap321xx_lsensor_disable(client);\r
-\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
-\r
- result = ap321xx_product_detect(client);\r
- if (result)\r
+
+ 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);\r
- return result;\r
- }\r
-\r
+ dev_err(&client->dev, "ret: %d, product version detect failed.\n",result);
+ return result;
+ }
+
/* initialize the AP3212B chip */
- result = ap321xx_init_client(client);\r
- if (result)\r
- return result;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- \r
- return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- int result = 0;\r
- u8 int_stat;\r
- \r
- int_stat = ap321xx_get_intstat(client);\r
+ 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)\r
+ if (int_stat & AP3212B_INT_AMASK)
{
- ap321xx_change_ls_threshold(client);\r
+ ap321xx_change_ls_threshold(client);
}
- \r
- return result;\r
-}\r
-\r
-struct sensor_operate light_ap321xx_ops = {\r
- .name = "ls_ap321xx",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_AP321XX, //i2c id number\r
- .read_reg = SENSOR_UNKNOW_DATA, //read data //there are two regs, we fix them in code.\r
- .read_len = 1, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register //there are 3 regs, we fix them in code.\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 16, //8 bits\r
- .ctrl_reg = AP3212B_MODE_COMMAND, //enable or disable \r
- .int_status_reg = AP3212B_INT_COMMAND, //intterupt status register\r
- .range = {100,65535}, //range\r
- .brightness ={10,255}, // brightness\r
- .trig = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_ap321xx_ops;\r
-}\r
-\r
-\r
-static int __init light_ap321xx_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit light_ap321xx_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-\r
-module_init(light_ap321xx_init);\r
-module_exit(light_ap321xx_exit);\r
-\r
-\r
+
+ 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);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define ALS_CMD 0x01\r
-#define ALS_DT1 0x02\r
-#define ALS_DT2 0X03\r
-#define ALS_THDH1 0X04\r
-#define ALS_THDH2 0X05\r
-#define ALS_THDL1 0X06\r
-#define ALS_THDL2 0X07\r
-#define STA_TUS 0X08\r
-#define PS_CMD 0X09\r
-#define PS_DT 0X0A\r
-#define PS_THDH 0X0B\r
-#define PS_THDL 0X0C\r
-#define SW_RESET 0X80\r
-\r
-//ALS_CMD\r
-#define ALS_SD_ENABLE (0<<0)\r
-#define ALS_SD_DISABLE (1<<0)\r
-#define ALS_INT_DISABLE (0<<1)\r
-#define ALS_INT_ENABLE (1<<1)\r
-#define ALS_1T_100MS (0<<2)\r
-#define ALS_2T_200MS (1<<2)\r
-#define ALS_4T_400MS (2<<2)\r
-#define ALS_8T_800MS (3<<2)\r
-#define ALS_RANGE_57671 (0<<6)\r
-#define ALS_RANGE_28836 (1<<6)\r
-\r
-//PS_CMD\r
-#define PS_SD_ENABLE (0<<0)\r
-#define PS_SD_DISABLE (1<<0)\r
-#define PS_INT_DISABLE (0<<1)\r
-#define PS_INT_ENABLE (1<<1)\r
-#define PS_10T_2MS (0<<2)\r
-#define PS_15T_3MS (1<<2)\r
-#define PS_20T_4MS (2<<2)\r
-#define PS_25T_5MS (3<<2)\r
-#define PS_CUR_100MA (0<<4)\r
-#define PS_CUR_200MA (1<<4)\r
-#define PS_SLP_10MS (0<<5)\r
-#define PS_SLP_30MS (1<<5)\r
-#define PS_SLP_90MS (2<<5)\r
-#define PS_SLP_270MS (3<<5)\r
-#define TRIG_PS_OR_LS (0<<7)\r
-#define TRIG_PS_AND_LS (1<<7)\r
-\r
-//STA_TUS\r
-#define STA_PS_INT (1<<5)\r
-#define STA_ALS_INT (1<<4)\r
-\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int status = 0;\r
-\r
- sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(!enable)\r
- { \r
- status = ALS_SD_DISABLE; \r
- sensor->ops->ctrl_data |= status; \r
- }\r
- else\r
- {\r
- status = ~ALS_SD_DISABLE;\r
- sensor->ops->ctrl_data &= status;\r
- }\r
- \r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- if(enable)\r
- sensor->ops->report(sensor->client);\r
- \r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- result = sensor_write_reg(client, SW_RESET, 0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- result = sensor_write_reg(client, ALS_THDH1, 0);//it is important,if not then als can not trig intterupt\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- result = sensor_write_reg(client, ALS_THDH2, 0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- } \r
-\r
- sensor->ops->ctrl_data |= ALS_1T_100MS;\r
-\r
- if(sensor->pdata->irq_enable)\r
- sensor->ops->ctrl_data |= ALS_INT_ENABLE;\r
- else\r
- sensor->ops->ctrl_data &= ~ALS_INT_ENABLE;\r
- \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int light_report_value(struct input_dev *input, int data)\r
-{\r
- unsigned char index = 0;\r
- if(data <= 100){\r
- index = 0;goto report;\r
- }\r
- else if(data <= 1600){\r
- index = 1;goto report;\r
- }\r
- else if(data <= 2250){\r
- index = 2;goto report;\r
- }\r
- else if(data <= 3200){\r
- index = 3;goto report;\r
- }\r
- else if(data <= 6400){\r
- index = 4;goto report;\r
- }\r
- else if(data <= 12800){\r
- index = 5;goto report;\r
- }\r
- else if(data <= 26000){\r
- index = 6;goto report;\r
- }\r
- else{\r
- index = 7;goto report;\r
- }\r
-\r
-report:\r
- input_report_abs(input, ABS_MISC, index);\r
- input_sync(input);\r
- \r
- return index;\r
-}\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int value = 0;\r
- char buffer[2] = {0}; \r
- char index = 0;\r
- \r
- if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 2);\r
-\r
- buffer[0] = sensor->ops->read_reg;\r
- result = sensor_rx_data(client, buffer, sensor->ops->read_len); \r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- value = (buffer[0] << 8) | buffer[1];\r
-\r
- \r
- index = light_report_value(sensor->input_dev, value);\r
-\r
- DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(sensor->ops->int_status_reg)\r
- { \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- }\r
- \r
- if(value & STA_ALS_INT)\r
- {\r
- value &= ~STA_ALS_INT;\r
- result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- }\r
- }\r
- \r
- \r
- return result;\r
-}\r
-\r
-struct sensor_operate light_stk3171_ops = {\r
- .name = "ls_stk3171",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_STK3171, //i2c id number\r
- .read_reg = ALS_DT1, //read data\r
- .read_len = 2, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 16, //8 bits\r
- .ctrl_reg = ALS_CMD, //enable or disable \r
- .int_status_reg = STA_TUS, //intterupt status register\r
- .range = {100,65535}, //range\r
- .brightness ={10,255}, //brightness\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_stk3171_ops;\r
-}\r
-\r
-\r
-static int __init light_stk3171_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit light_stk3171_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-\r
-module_init(light_stk3171_init);\r
-module_exit(light_stk3171_exit);\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define ALS_CMD 0x01
+#define ALS_DT1 0x02
+#define ALS_DT2 0X03
+#define ALS_THDH1 0X04
+#define ALS_THDH2 0X05
+#define ALS_THDL1 0X06
+#define ALS_THDL2 0X07
+#define STA_TUS 0X08
+#define PS_CMD 0X09
+#define PS_DT 0X0A
+#define PS_THDH 0X0B
+#define PS_THDL 0X0C
+#define SW_RESET 0X80
+
+//ALS_CMD
+#define ALS_SD_ENABLE (0<<0)
+#define ALS_SD_DISABLE (1<<0)
+#define ALS_INT_DISABLE (0<<1)
+#define ALS_INT_ENABLE (1<<1)
+#define ALS_1T_100MS (0<<2)
+#define ALS_2T_200MS (1<<2)
+#define ALS_4T_400MS (2<<2)
+#define ALS_8T_800MS (3<<2)
+#define ALS_RANGE_57671 (0<<6)
+#define ALS_RANGE_28836 (1<<6)
+
+//PS_CMD
+#define PS_SD_ENABLE (0<<0)
+#define PS_SD_DISABLE (1<<0)
+#define PS_INT_DISABLE (0<<1)
+#define PS_INT_ENABLE (1<<1)
+#define PS_10T_2MS (0<<2)
+#define PS_15T_3MS (1<<2)
+#define PS_20T_4MS (2<<2)
+#define PS_25T_5MS (3<<2)
+#define PS_CUR_100MA (0<<4)
+#define PS_CUR_200MA (1<<4)
+#define PS_SLP_10MS (0<<5)
+#define PS_SLP_30MS (1<<5)
+#define PS_SLP_90MS (2<<5)
+#define PS_SLP_270MS (3<<5)
+#define TRIG_PS_OR_LS (0<<7)
+#define TRIG_PS_AND_LS (1<<7)
+
+//STA_TUS
+#define STA_PS_INT (1<<5)
+#define STA_ALS_INT (1<<4)
+
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int status = 0;
+
+ sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ //register setting according to chip datasheet
+ if(!enable)
+ {
+ status = ALS_SD_DISABLE;
+ sensor->ops->ctrl_data |= status;
+ }
+ else
+ {
+ status = ~ALS_SD_DISABLE;
+ sensor->ops->ctrl_data &= status;
+ }
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ if(enable)
+ sensor->ops->report(sensor->client);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ result = sensor_write_reg(client, SW_RESET, 0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ result = sensor_write_reg(client, ALS_THDH1, 0);//it is important,if not then als can not trig intterupt
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ result = sensor_write_reg(client, ALS_THDH2, 0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->ops->ctrl_data |= ALS_1T_100MS;
+
+ if(sensor->pdata->irq_enable)
+ sensor->ops->ctrl_data |= ALS_INT_ENABLE;
+ else
+ sensor->ops->ctrl_data &= ~ALS_INT_ENABLE;
+
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ return result;
+}
+
+
+static int light_report_value(struct input_dev *input, int data)
+{
+ unsigned char index = 0;
+ if(data <= 100){
+ index = 0;goto report;
+ }
+ else if(data <= 1600){
+ index = 1;goto report;
+ }
+ else if(data <= 2250){
+ index = 2;goto report;
+ }
+ else if(data <= 3200){
+ index = 3;goto report;
+ }
+ else if(data <= 6400){
+ index = 4;goto report;
+ }
+ else if(data <= 12800){
+ index = 5;goto report;
+ }
+ else if(data <= 26000){
+ index = 6;goto report;
+ }
+ else{
+ index = 7;goto report;
+ }
+
+report:
+ input_report_abs(input, ABS_MISC, index);
+ input_sync(input);
+
+ return index;
+}
+
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int value = 0;
+ char buffer[2] = {0};
+ char index = 0;
+
+ if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2
+ {
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+ return -1;
+ }
+
+ memset(buffer, 0, 2);
+
+ buffer[0] = sensor->ops->read_reg;
+ result = sensor_rx_data(client, buffer, sensor->ops->read_len);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ value = (buffer[0] << 8) | buffer[1];
+
+
+ index = light_report_value(sensor->input_dev, value);
+
+ DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
+
+ if(sensor->pdata->irq_enable)
+ {
+ if(sensor->ops->int_status_reg)
+ {
+ value = sensor_read_reg(client, sensor->ops->int_status_reg);
+ }
+
+ if(value & STA_ALS_INT)
+ {
+ value &= ~STA_ALS_INT;
+ result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+ }
+ }
+
+
+ return result;
+}
+
+struct sensor_operate light_stk3171_ops = {
+ .name = "ls_stk3171",
+ .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
+ .id_i2c = LIGHT_ID_STK3171, //i2c id number
+ .read_reg = ALS_DT1, //read data
+ .read_len = 2, //data length
+ .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
+ .id_data = SENSOR_UNKNOW_DATA, //device id
+ .precision = 16, //8 bits
+ .ctrl_reg = ALS_CMD, //enable or disable
+ .int_status_reg = STA_TUS, //intterupt status register
+ .range = {100,65535}, //range
+ .brightness ={10,255}, //brightness
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *light_get_ops(void)
+{
+ return &light_stk3171_ops;
+}
+
+
+static int __init light_stk3171_init(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, light_get_ops);
+ return result;
+}
+
+static void __exit light_stk3171_exit(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, light_get_ops);
+}
+
+
+module_init(light_stk3171_init);
+module_exit(light_stk3171_exit);
+
+
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <mach/gpio.h>\r
-#include <mach/board.h> \r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-#include <linux/types.h>\r
-\r
-\r
-#define DRIVER_VERSION "1.0"\r
-\r
-#define PWR_MODE_DOWN_MASK 0x80\r
-#define PWR_MODE_OPERATE_MASK 0x7F\r
-\r
-\r
-/*us5152 Slave Addr*/\r
-#define LIGHT_ADDR 0x72 \r
-\r
-/*Interrupt PIN for S3C6410*/\r
-#define IRQ_LIGHT_INT IRQ_EINT(6)\r
-\r
-/*Register Set*/\r
-#define REGS_CR0 0x00\r
-#define REGS_CR1 0x01\r
-#define REGS_CR2 0x02\r
-#define REGS_CR3 0x03\r
-//ALS\r
-#define REGS_INT_LSB_TH_LO 0x04\r
-#define REGS_INT_MSB_TH_LO 0x05\r
-#define REGS_INT_LSB_TH_HI 0x06\r
-#define REGS_INT_MSB_TH_HI 0x07\r
-//ALS data\r
-#define REGS_LBS_SENSOR 0x0C\r
-#define REGS_MBS_SENSOR 0x0D\r
-\r
-#define REGS_CR10 0x10\r
-#define REGS_CR11 0x11\r
-#define REGS_VERSION_ID 0x1F\r
-#define REGS_CHIP_ID 0xB2\r
-\r
-/*ShutDown_EN*/\r
-#define CR0_OPERATION 0x0\r
-#define CR0_SHUTDOWN_EN 0x1\r
-\r
-#define CR0_SHUTDOWN_SHIFT (7)\r
-#define CR0_SHUTDOWN_MASK (0x1 << CR0_SHUTDOWN_SHIFT)\r
-\r
-/*OneShot_EN*/\r
-#define CR0_ONESHOT_EN 0x01\r
-\r
-#define CR0_ONESHOT_SHIFT (6)\r
-#define CR0_ONESHOT_MASK (0x1 << CR0_ONESHOT_SHIFT)\r
-\r
-/*Operation Mode*/\r
-#define CR0_OPMODE_ALSANDPS 0x0 \r
-#define CR0_OPMODE_ALSONLY 0x1 \r
-#define CR0_OPMODE_IRONLY 0x2 \r
-\r
-#define CR0_OPMODE_SHIFT (4)\r
-#define CR0_OPMODE_MASK (0x3 << CR0_OPMODE_SHIFT)\r
-\r
-/*all int flag (PROX, INT_A, INT_P)*/\r
-#define CR0_ALL_INT_CLEAR 0x0\r
-\r
-#define CR0_ALL_INT_SHIFT (1)\r
-#define CR0_ALL_INT_MASK (0x7 << CR0_ALL_INT_SHIFT)\r
-\r
-\r
-/*indicator of object proximity detection*/\r
-#define CR0_PROX_CLEAR 0x0\r
-\r
-#define CR0_PROX_SHIFT (3)\r
-#define CR0_PROX_MASK (0x1 << CR0_PROX_SHIFT)\r
-\r
-/*interrupt status of proximity sensor*/\r
-#define CR0_INTP_CLEAR 0x0\r
-\r
-#define CR0_INTP_SHIFT (2)\r
-#define CR0_INTP_MASK (0x1 << CR0_INTP_SHIFT)\r
-\r
-/*interrupt status of ambient sensor*/\r
-#define CR0_INTA_CLEAR 0x0\r
-\r
-#define CR0_INTA_SHIFT (1)\r
-#define CR0_INTA_MASK (0x1 << CR0_INTA_SHIFT)\r
-\r
-/*Word mode enable*/\r
-#define CR0_WORD_EN 0x1\r
-\r
-#define CR0_WORD_SHIFT (0)\r
-#define CR0_WORD_MASK (0x1 << CR0_WORD_SHIFT)\r
-\r
-\r
-/*ALS fault queue depth for interrupt enent output*/\r
-#define CR1_ALS_FQ_1 0x0 \r
-#define CR1_ALS_FQ_4 0x1 \r
-#define CR1_ALS_FQ_8 0x2\r
-#define CR1_ALS_FQ_16 0x3\r
-#define CR1_ALS_FQ_24 0x4\r
-#define CR1_ALS_FQ_32 0x5\r
-#define CR1_ALS_FQ_48 0x6\r
-#define CR1_ALS_FQ_63 0x7\r
-\r
-#define CR1_ALS_FQ_SHIFT (5)\r
-#define CR1_ALS_FQ_MASK (0x7 << CR1_ALS_FQ_SHIFT)\r
-\r
-/*resolution for ALS*/\r
-#define CR1_ALS_RES_12BIT 0x0 \r
-#define CR1_ALS_RES_14BIT 0x1 \r
-#define CR1_ALS_RES_16BIT 0x2\r
-#define CR1_ALS_RES_16BIT_2 0x3\r
-\r
-#define CR1_ALS_RES_SHIFT (3)\r
-#define CR1_ALS_RES_MASK (0x3 << CR1_ALS_RES_SHIFT)\r
-\r
-/*sensing amplifier selection for ALS*/\r
-#define CR1_ALS_GAIN_X1 0x0 \r
-#define CR1_ALS_GAIN_X2 0x1 \r
-#define CR1_ALS_GAIN_X4 0x2\r
-#define CR1_ALS_GAIN_X8 0x3\r
-#define CR1_ALS_GAIN_X16 0x4\r
-#define CR1_ALS_GAIN_X32 0x5\r
-#define CR1_ALS_GAIN_X64 0x6\r
-#define CR1_ALS_GAIN_X128 0x7\r
-\r
-#define CR1_ALS_GAIN_SHIFT (0)\r
-#define CR1_ALS_GAIN_MASK (0x7 << CR1_ALS_GAIN_SHIFT)\r
-\r
-\r
-/*PS fault queue depth for interrupt event output*/\r
-#define CR2_PS_FQ_1 0x0 \r
-#define CR2_PS_FQ_4 0x1 \r
-#define CR2_PS_FQ_8 0x2\r
-#define CR2_PS_FQ_15 0x3\r
-\r
-#define CR2_PS_FQ_SHIFT (6)\r
-#define CR2_PS_FQ_MASK (0x3 << CR2_PS_FQ_SHIFT)\r
-\r
-/*interrupt type setting */\r
-/*low active*/\r
-#define CR2_INT_LEVEL 0x0 \r
-/*low pulse*/\r
-#define CR2_INT_PULSE 0x1 \r
-\r
-#define CR2_INT_SHIFT (5)\r
-#define CR2_INT_MASK (0x1 << CR2_INT_SHIFT)\r
-\r
-/*resolution for PS*/\r
-#define CR2_PS_RES_12 0x0 \r
-#define CR2_PS_RES_14 0x1 \r
-#define CR2_PS_RES_16 0x2\r
-#define CR2_PS_RES_16_2 0x3\r
-\r
-#define CR2_PS_RES_SHIFT (3)\r
-#define CR2_PS_RES_MASK (0x3 << CR2_PS_RES_SHIFT)\r
-\r
-/*sensing amplifier selection for PS*/\r
-#define CR2_PS_GAIN_1 0x0 \r
-#define CR2_PS_GAIN_2 0x1 \r
-#define CR2_PS_GAIN_4 0x2\r
-#define CR2_PS_GAIN_8 0x3\r
-#define CR2_PS_GAIN_16 0x4\r
-#define CR2_PS_GAIN_32 0x5\r
-#define CR2_PS_GAIN_64 0x6\r
-#define CR2_PS_GAIN_128 0x7\r
-\r
-#define CR2_PS_GAIN_SHIFT (0)\r
-#define CR2_PS_GAIN_MASK (0x7 << CR2_PS_GAIN_SHIFT)\r
-\r
-/*wait-time slot selection*/\r
-#define CR3_WAIT_SEL_0 0x0 \r
-#define CR3_WAIT_SEL_4 0x1 \r
-#define CR3_WAIT_SEL_8 0x2\r
-#define CR3_WAIT_SEL_16 0x3\r
-\r
-#define CR3_WAIT_SEL_SHIFT (6)\r
-#define CR3_WAIT_SEL_MASK (0x3 << CR3_WAIT_SEL_SHIFT)\r
-\r
-/*IR-LED drive peak current setting*/\r
-#define CR3_LEDDR_12_5 0x0 \r
-#define CR3_LEDDR_25 0x1 \r
-#define CR3_LEDDR_50 0x2\r
-#define CR3_LEDDR_100 0x3\r
-\r
-#define CR3_LEDDR_SHIFT (4)\r
-#define CR3_LEDDR_MASK (0x3 << CR3_LEDDR_SHIFT)\r
-\r
-/*INT pin source selection*/\r
-#define CR3_INT_SEL_BATH 0x0 \r
-#define CR3_INT_SEL_ALS 0x1 \r
-#define CR3_INT_SEL_PS 0x2\r
-#define CR3_INT_SEL_PSAPP 0x3\r
-\r
-#define CR3_INT_SEL_SHIFT (2)\r
-#define CR3_INT_SEL_MASK (0x3 << CR3_INT_SEL_SHIFT)\r
-\r
-/*software reset for register and core*/\r
-#define CR3_SOFTRST_EN 0x1\r
-\r
-#define CR3_SOFTRST_SHIFT (0)\r
-#define CR3_SOFTRST_MASK (0x1 << CR3_SOFTRST_SHIFT)\r
-\r
-/*modulation frequency of LED driver*/\r
-#define CR10_FREQ_DIV2 0x0 \r
-#define CR10_FREQ_DIV4 0x1 \r
-#define CR10_FREQ_DIV8 0x2\r
-#define CR10_FREQ_DIV16 0x3\r
-\r
-#define CR10_FREQ_SHIFT (1)\r
-#define CR10_FREQ_MASK (0x3 << CR10_FREQ_SHIFT)\r
-\r
-/*50/60 Rejection enable*/\r
-#define CR10_REJ_5060_DIS 0x00\r
-#define CR10_REJ_5060_EN 0x01\r
-\r
-#define CR10_REJ_5060_SHIFT (0)\r
-#define CR10_REJ_5060_MASK (0x1 << CR10_REJ_5060_SHIFT)\r
-\r
-#define us5152_NUM_CACHABLE_REGS 0x12\r
-\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- //struct sensor_private_data *sensor =\r
- // (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- int i = 0;\r
- \r
- for(i=0; i<3; i++)\r
- {\r
- if(!enable)\r
- { \r
- value = sensor_read_reg(client, REGS_CR0);\r
- value |= PWR_MODE_DOWN_MASK; //ShutDown_EN=1\r
- result = sensor_write_reg(client, REGS_CR0, value);\r
- if(result)\r
- return result;\r
- }\r
- else\r
- { \r
- value = sensor_read_reg(client, REGS_CR0);\r
- value &= PWR_MODE_OPERATE_MASK ; //Operation_EN=0\r
- result = sensor_write_reg(client, REGS_CR0, value);\r
- if(result)\r
- return result;\r
- }\r
- \r
- if(!result)\r
- break;\r
- }\r
- \r
- if(i>1)\r
- printk("%s:set %d times",__func__,i);\r
-\r
- \r
- //TODO:? function to be added here\r
-\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- value = sensor_read_reg(client, REGS_CHIP_ID); //read chip ids\r
- printk("us5152 chip id is %x!\n", value);\r
-\r
- value = 0x01;//word accessing\r
- \r
- result = sensor_write_reg(client, REGS_CR0, value);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-static int us5152_value_report(struct input_dev *input, int data)\r
-{\r
- unsigned char index = 0;\r
- if(data <= 10){\r
- index = 0;goto report;\r
- }\r
- else if(data <= 160){\r
- index = 1;goto report;\r
- }\r
- else if(data <= 225){\r
- index = 2;goto report;\r
- }\r
- else if(data <= 320){\r
- index = 3;goto report;\r
- }\r
- else if(data <= 640){\r
- index = 4;goto report;\r
- }\r
- else if(data <= 1280){\r
- index = 5;goto report;\r
- }\r
- else if(data <= 2600){\r
- index = 6;goto report;\r
- }\r
- else{\r
- index = 7;goto report;\r
- }\r
-\r
-report:\r
- input_report_abs(input, ABS_MISC, index);\r
- input_sync(input);\r
- return index;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int value = 0;\r
- char index = 0;\r
- char buffer[2]= { 0 } ;\r
- int ret=0;\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(sensor->ops->int_status_reg >= 0)\r
- {\r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- }\r
- \r
- }\r
- \r
- //value = sensor_read_reg(client, sensor->ops->read_reg); //TODO:? to be changed\r
- if(sensor->ops->read_len< 2) //12bit\r
- {\r
- printk("us5152 data read para num error ; len = %d\n ",sensor->ops->read_len);\r
- return -1;\r
- }\r
- memset(buffer , 0 , 2);\r
- do\r
- {\r
- *buffer = sensor->ops->read_reg;\r
- ret=sensor_rx_data(client,buffer,sensor->ops->read_len);\r
- if(ret<0)\r
- return ret;\r
- }\r
- while(0);\r
- value=buffer[1];\r
- value =((value << 8) | buffer[0]) & 0xffff;\r
- index = us5152_value_report(sensor->input_dev, value); //now is 12bit \r
- \r
- //printk("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
- DBG("%s:%s result=%d,index=%d buffer[1]=0x%x , buffer[0]=0x%x \n",__func__,sensor->ops->name, value,index,buffer[1],buffer[0]);\r
- \r
- return result;\r
-}\r
-\r
-\r
-struct sensor_operate light_us5152_ops = {\r
- .name = "ls_us5152",\r
- .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
- .id_i2c = LIGHT_ID_US5152, //i2c id number\r
- .read_reg = REGS_LBS_SENSOR, //read data\r
- .read_len = 2, //data length\r
- .id_reg = REGS_CHIP_ID, //read device id from this register\r
- .id_data = 0x26, //device id\r
- .precision = 12, //12 bits\r
- .ctrl_reg = REGS_CR0, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
- .range = {0,10}, //range\r
- .brightness = {10,4095}, // brightness\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT , \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *light_get_ops(void)\r
-{\r
- return &light_us5152_ops;\r
-}\r
-\r
-\r
-static int __init us5152_init(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
-\r
- return result;\r
-}\r
-\r
-static void __exit us5152_exit(void)\r
-{\r
- struct sensor_operate *ops = light_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
-}\r
-\r
-MODULE_AUTHOR("Finley Huang finley_huang@upi-semi.com");\r
-MODULE_DESCRIPTION("us5152 ambient light sensor driver");\r
-MODULE_LICENSE("GPL");\r
-MODULE_VERSION(DRIVER_VERSION);\r
-\r
-module_init(us5152_init);\r
-module_exit(us5152_exit);\r
-\r
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+#include <linux/types.h>
+
+
+#define DRIVER_VERSION "1.0"
+
+#define PWR_MODE_DOWN_MASK 0x80
+#define PWR_MODE_OPERATE_MASK 0x7F
+
+
+/*us5152 Slave Addr*/
+#define LIGHT_ADDR 0x72
+
+/*Interrupt PIN for S3C6410*/
+#define IRQ_LIGHT_INT IRQ_EINT(6)
+
+/*Register Set*/
+#define REGS_CR0 0x00
+#define REGS_CR1 0x01
+#define REGS_CR2 0x02
+#define REGS_CR3 0x03
+//ALS
+#define REGS_INT_LSB_TH_LO 0x04
+#define REGS_INT_MSB_TH_LO 0x05
+#define REGS_INT_LSB_TH_HI 0x06
+#define REGS_INT_MSB_TH_HI 0x07
+//ALS data
+#define REGS_LBS_SENSOR 0x0C
+#define REGS_MBS_SENSOR 0x0D
+
+#define REGS_CR10 0x10
+#define REGS_CR11 0x11
+#define REGS_VERSION_ID 0x1F
+#define REGS_CHIP_ID 0xB2
+
+/*ShutDown_EN*/
+#define CR0_OPERATION 0x0
+#define CR0_SHUTDOWN_EN 0x1
+
+#define CR0_SHUTDOWN_SHIFT (7)
+#define CR0_SHUTDOWN_MASK (0x1 << CR0_SHUTDOWN_SHIFT)
+
+/*OneShot_EN*/
+#define CR0_ONESHOT_EN 0x01
+
+#define CR0_ONESHOT_SHIFT (6)
+#define CR0_ONESHOT_MASK (0x1 << CR0_ONESHOT_SHIFT)
+
+/*Operation Mode*/
+#define CR0_OPMODE_ALSANDPS 0x0
+#define CR0_OPMODE_ALSONLY 0x1
+#define CR0_OPMODE_IRONLY 0x2
+
+#define CR0_OPMODE_SHIFT (4)
+#define CR0_OPMODE_MASK (0x3 << CR0_OPMODE_SHIFT)
+
+/*all int flag (PROX, INT_A, INT_P)*/
+#define CR0_ALL_INT_CLEAR 0x0
+
+#define CR0_ALL_INT_SHIFT (1)
+#define CR0_ALL_INT_MASK (0x7 << CR0_ALL_INT_SHIFT)
+
+
+/*indicator of object proximity detection*/
+#define CR0_PROX_CLEAR 0x0
+
+#define CR0_PROX_SHIFT (3)
+#define CR0_PROX_MASK (0x1 << CR0_PROX_SHIFT)
+
+/*interrupt status of proximity sensor*/
+#define CR0_INTP_CLEAR 0x0
+
+#define CR0_INTP_SHIFT (2)
+#define CR0_INTP_MASK (0x1 << CR0_INTP_SHIFT)
+
+/*interrupt status of ambient sensor*/
+#define CR0_INTA_CLEAR 0x0
+
+#define CR0_INTA_SHIFT (1)
+#define CR0_INTA_MASK (0x1 << CR0_INTA_SHIFT)
+
+/*Word mode enable*/
+#define CR0_WORD_EN 0x1
+
+#define CR0_WORD_SHIFT (0)
+#define CR0_WORD_MASK (0x1 << CR0_WORD_SHIFT)
+
+
+/*ALS fault queue depth for interrupt enent output*/
+#define CR1_ALS_FQ_1 0x0
+#define CR1_ALS_FQ_4 0x1
+#define CR1_ALS_FQ_8 0x2
+#define CR1_ALS_FQ_16 0x3
+#define CR1_ALS_FQ_24 0x4
+#define CR1_ALS_FQ_32 0x5
+#define CR1_ALS_FQ_48 0x6
+#define CR1_ALS_FQ_63 0x7
+
+#define CR1_ALS_FQ_SHIFT (5)
+#define CR1_ALS_FQ_MASK (0x7 << CR1_ALS_FQ_SHIFT)
+
+/*resolution for ALS*/
+#define CR1_ALS_RES_12BIT 0x0
+#define CR1_ALS_RES_14BIT 0x1
+#define CR1_ALS_RES_16BIT 0x2
+#define CR1_ALS_RES_16BIT_2 0x3
+
+#define CR1_ALS_RES_SHIFT (3)
+#define CR1_ALS_RES_MASK (0x3 << CR1_ALS_RES_SHIFT)
+
+/*sensing amplifier selection for ALS*/
+#define CR1_ALS_GAIN_X1 0x0
+#define CR1_ALS_GAIN_X2 0x1
+#define CR1_ALS_GAIN_X4 0x2
+#define CR1_ALS_GAIN_X8 0x3
+#define CR1_ALS_GAIN_X16 0x4
+#define CR1_ALS_GAIN_X32 0x5
+#define CR1_ALS_GAIN_X64 0x6
+#define CR1_ALS_GAIN_X128 0x7
+
+#define CR1_ALS_GAIN_SHIFT (0)
+#define CR1_ALS_GAIN_MASK (0x7 << CR1_ALS_GAIN_SHIFT)
+
+
+/*PS fault queue depth for interrupt event output*/
+#define CR2_PS_FQ_1 0x0
+#define CR2_PS_FQ_4 0x1
+#define CR2_PS_FQ_8 0x2
+#define CR2_PS_FQ_15 0x3
+
+#define CR2_PS_FQ_SHIFT (6)
+#define CR2_PS_FQ_MASK (0x3 << CR2_PS_FQ_SHIFT)
+
+/*interrupt type setting */
+/*low active*/
+#define CR2_INT_LEVEL 0x0
+/*low pulse*/
+#define CR2_INT_PULSE 0x1
+
+#define CR2_INT_SHIFT (5)
+#define CR2_INT_MASK (0x1 << CR2_INT_SHIFT)
+
+/*resolution for PS*/
+#define CR2_PS_RES_12 0x0
+#define CR2_PS_RES_14 0x1
+#define CR2_PS_RES_16 0x2
+#define CR2_PS_RES_16_2 0x3
+
+#define CR2_PS_RES_SHIFT (3)
+#define CR2_PS_RES_MASK (0x3 << CR2_PS_RES_SHIFT)
+
+/*sensing amplifier selection for PS*/
+#define CR2_PS_GAIN_1 0x0
+#define CR2_PS_GAIN_2 0x1
+#define CR2_PS_GAIN_4 0x2
+#define CR2_PS_GAIN_8 0x3
+#define CR2_PS_GAIN_16 0x4
+#define CR2_PS_GAIN_32 0x5
+#define CR2_PS_GAIN_64 0x6
+#define CR2_PS_GAIN_128 0x7
+
+#define CR2_PS_GAIN_SHIFT (0)
+#define CR2_PS_GAIN_MASK (0x7 << CR2_PS_GAIN_SHIFT)
+
+/*wait-time slot selection*/
+#define CR3_WAIT_SEL_0 0x0
+#define CR3_WAIT_SEL_4 0x1
+#define CR3_WAIT_SEL_8 0x2
+#define CR3_WAIT_SEL_16 0x3
+
+#define CR3_WAIT_SEL_SHIFT (6)
+#define CR3_WAIT_SEL_MASK (0x3 << CR3_WAIT_SEL_SHIFT)
+
+/*IR-LED drive peak current setting*/
+#define CR3_LEDDR_12_5 0x0
+#define CR3_LEDDR_25 0x1
+#define CR3_LEDDR_50 0x2
+#define CR3_LEDDR_100 0x3
+
+#define CR3_LEDDR_SHIFT (4)
+#define CR3_LEDDR_MASK (0x3 << CR3_LEDDR_SHIFT)
+
+/*INT pin source selection*/
+#define CR3_INT_SEL_BATH 0x0
+#define CR3_INT_SEL_ALS 0x1
+#define CR3_INT_SEL_PS 0x2
+#define CR3_INT_SEL_PSAPP 0x3
+
+#define CR3_INT_SEL_SHIFT (2)
+#define CR3_INT_SEL_MASK (0x3 << CR3_INT_SEL_SHIFT)
+
+/*software reset for register and core*/
+#define CR3_SOFTRST_EN 0x1
+
+#define CR3_SOFTRST_SHIFT (0)
+#define CR3_SOFTRST_MASK (0x1 << CR3_SOFTRST_SHIFT)
+
+/*modulation frequency of LED driver*/
+#define CR10_FREQ_DIV2 0x0
+#define CR10_FREQ_DIV4 0x1
+#define CR10_FREQ_DIV8 0x2
+#define CR10_FREQ_DIV16 0x3
+
+#define CR10_FREQ_SHIFT (1)
+#define CR10_FREQ_MASK (0x3 << CR10_FREQ_SHIFT)
+
+/*50/60 Rejection enable*/
+#define CR10_REJ_5060_DIS 0x00
+#define CR10_REJ_5060_EN 0x01
+
+#define CR10_REJ_5060_SHIFT (0)
+#define CR10_REJ_5060_MASK (0x1 << CR10_REJ_5060_SHIFT)
+
+#define us5152_NUM_CACHABLE_REGS 0x12
+
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ //struct sensor_private_data *sensor =
+ // (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+ int i = 0;
+
+ for(i=0; i<3; i++)
+ {
+ if(!enable)
+ {
+ value = sensor_read_reg(client, REGS_CR0);
+ value |= PWR_MODE_DOWN_MASK; //ShutDown_EN=1
+ result = sensor_write_reg(client, REGS_CR0, value);
+ if(result)
+ return result;
+ }
+ else
+ {
+ value = sensor_read_reg(client, REGS_CR0);
+ value &= PWR_MODE_OPERATE_MASK ; //Operation_EN=0
+ result = sensor_write_reg(client, REGS_CR0, value);
+ if(result)
+ return result;
+ }
+
+ if(!result)
+ break;
+ }
+
+ if(i>1)
+ printk("%s:set %d times",__func__,i);
+
+
+ //TODO:? function to be added here
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ value = sensor_read_reg(client, REGS_CHIP_ID); //read chip ids
+ printk("us5152 chip id is %x!\n", value);
+
+ value = 0x01;//word accessing
+
+ result = sensor_write_reg(client, REGS_CR0, value);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ return result;
+}
+
+
+static int us5152_value_report(struct input_dev *input, int data)
+{
+ unsigned char index = 0;
+ if(data <= 10){
+ index = 0;goto report;
+ }
+ else if(data <= 160){
+ index = 1;goto report;
+ }
+ else if(data <= 225){
+ index = 2;goto report;
+ }
+ else if(data <= 320){
+ index = 3;goto report;
+ }
+ else if(data <= 640){
+ index = 4;goto report;
+ }
+ else if(data <= 1280){
+ index = 5;goto report;
+ }
+ else if(data <= 2600){
+ index = 6;goto report;
+ }
+ else{
+ index = 7;goto report;
+ }
+
+report:
+ input_report_abs(input, ABS_MISC, index);
+ input_sync(input);
+ return index;
+}
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int value = 0;
+ char index = 0;
+ char buffer[2]= { 0 } ;
+ int ret=0;
+
+ if(sensor->pdata->irq_enable)
+ {
+ if(sensor->ops->int_status_reg >= 0)
+ {
+ value = sensor_read_reg(client, sensor->ops->int_status_reg);
+ }
+
+ }
+
+ //value = sensor_read_reg(client, sensor->ops->read_reg); //TODO:? to be changed
+ if(sensor->ops->read_len< 2) //12bit
+ {
+ printk("us5152 data read para num error ; len = %d\n ",sensor->ops->read_len);
+ return -1;
+ }
+ memset(buffer , 0 , 2);
+ do
+ {
+ *buffer = sensor->ops->read_reg;
+ ret=sensor_rx_data(client,buffer,sensor->ops->read_len);
+ if(ret<0)
+ return ret;
+ }
+ while(0);
+ value=buffer[1];
+ value =((value << 8) | buffer[0]) & 0xffff;
+ index = us5152_value_report(sensor->input_dev, value); //now is 12bit
+
+ //printk("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
+ DBG("%s:%s result=%d,index=%d buffer[1]=0x%x , buffer[0]=0x%x \n",__func__,sensor->ops->name, value,index,buffer[1],buffer[0]);
+
+ return result;
+}
+
+
+struct sensor_operate light_us5152_ops = {
+ .name = "ls_us5152",
+ .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
+ .id_i2c = LIGHT_ID_US5152, //i2c id number
+ .read_reg = REGS_LBS_SENSOR, //read data
+ .read_len = 2, //data length
+ .id_reg = REGS_CHIP_ID, //read device id from this register
+ .id_data = 0x26, //device id
+ .precision = 12, //12 bits
+ .ctrl_reg = REGS_CR0, //enable or disable
+ .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
+ .range = {0,10}, //range
+ .brightness = {10,4095}, // brightness
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT ,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *light_get_ops(void)
+{
+ return &light_us5152_ops;
+}
+
+
+static int __init us5152_init(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, light_get_ops);
+
+ return result;
+}
+
+static void __exit us5152_exit(void)
+{
+ struct sensor_operate *ops = light_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, light_get_ops);
+}
+
+MODULE_AUTHOR("Finley Huang finley_huang@upi-semi.com");
+MODULE_DESCRIPTION("us5152 ambient light sensor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(us5152_init);
+module_exit(us5152_exit);
+
-/* drivers/input/sensors/pressure/ms5607.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define CMD_RESET 0x1E // ADC reset command \r
-#define CMD_ADC_READ 0x00 // ADC read command \r
-#define CMD_ADC_CONV 0x40 // ADC conversion command \r
-#define CMD_ADC_D1 0x00 // ADC D1 conversion \r
-#define CMD_ADC_D2 0x10 // ADC D2 conversion \r
-#define CMD_ADC_256 0x00 // ADC OSR=256 \r
-#define CMD_ADC_512 0x02 // ADC OSR=512 \r
-#define CMD_ADC_1024 0x04 // ADC OSR=1024 \r
-#define CMD_ADC_2048 0x06 // ADC OSR=2048 \r
-#define CMD_ADC_4096 0x08 // ADC OSR=4096 \r
-#define CMD_PROM_RD 0xA0 // Prom read command \r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int C[8] = {0};\r
-int g_ms5607_temp;\r
-int g_ms5607_pr_status;\r
-\r
-#if defined(CONFIG_TMP_MS5607)\r
-extern int g_ms5607_temp_status;\r
-#else\r
-static int g_ms5607_temp_status = SENSOR_OFF;\r
-#endif\r
-\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- int result = 0;\r
- int i = 0;\r
- char prom[16];\r
-\r
- if((enable) && (g_ms5607_temp_status == SENSOR_OFF))\r
- {\r
- result = sensor_write_reg_normal(client, CMD_RESET);\r
- if(result) \r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
-\r
- //Read PROM (128 bit of calibration words) \r
- memset(prom, 0, 16);\r
- prom[0]= CMD_PROM_RD;//CMD_PROM_RD; \r
- for(i=0; i<8; i++)\r
- {\r
- prom[i*2]= CMD_PROM_RD + i*2;\r
- result = sensor_rx_data(client, &prom[i*2], 2);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- }\r
-\r
- for (i=0;i<8;i++) \r
- {\r
- C[i] = prom[2*i] << 8 | prom[2*i + 1];\r
- //printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);\r
- //printk("\nC[%d]=%d,",i+1,C[i]);\r
- } \r
-\r
- }\r
- \r
- g_ms5607_pr_status = enable;\r
- \r
- return result;\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- g_ms5607_pr_status = sensor->status_cur;\r
- \r
- //Reset\r
- //result = sensor_write_reg_normal(client, CMD_RESET);\r
- //if(result) \r
- //printk("%s:line=%d,error\n",__func__,__LINE__); \r
- \r
- return result;\r
-}\r
-\r
-\r
-static int pressure_report_value(struct input_dev *input, int data)\r
-{\r
- //get pressure, high and temperature from register data\r
-\r
- input_report_abs(input, ABS_PRESSURE, data);\r
- input_sync(input);\r
- \r
- return 0;\r
-}\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- \r
- int result = 0;\r
- char buffer[3]; \r
- char index = 0;\r
- unsigned int D1=0, D2=0;\r
-\r
- int T2 = 0;\r
- long long OFF = 0; // offset at actual temperature \r
- long long SENS = 0; // sensitivity at actual temperature \r
- int dT = 0; // difference between actual and measured temperature\r
- long long OFF2 = 0;\r
- long long SENS2 = 0;\r
- int P = 0; // compensated pressure value \r
-\r
-\r
- memset(buffer, 0, 3);\r
- if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
-\r
- //D1 conversion\r
- sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);\r
- msleep(10);\r
-\r
- memset(buffer, 0, 3);\r
- buffer[0] = CMD_ADC_READ;\r
- result = sensor_rx_data(client, &buffer[0], 3);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];\r
- DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);\r
-\r
- //D2 conversion\r
- sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);\r
- msleep(10);\r
-\r
- memset(buffer, 0, 3);\r
- buffer[0] = CMD_ADC_READ;\r
- result = sensor_rx_data(client, &buffer[0], 3);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];\r
- DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);\r
-\r
- dT = D2 - ((unsigned int)C[5] << 8);\r
-\r
- g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));\r
-\r
- OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);\r
-\r
- SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);\r
-\r
- /*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/\r
- if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)\r
- {\r
- printk("%s:temperature is error\n",__func__);\r
- return -1;\r
- }\r
-\r
- if (g_ms5607_temp < 2000)\r
- {\r
- int tmp;\r
- tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);\r
-\r
- T2 = (int)((long long)(dT * dT) >> 31);\r
- OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;\r
- SENS2 = (long long)((tmp*tmp) << 1);\r
-\r
- if (g_ms5607_temp < -1500)\r
- {\r
- tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);\r
- OFF2 += 15 * tmp;\r
- SENS2 += 8 * tmp;\r
- }\r
- }\r
- else\r
- {\r
- T2=0;\r
- OFF2 = 0;\r
- SENS2 = 0;\r
- }\r
-\r
- g_ms5607_temp -= T2;\r
- OFF -= OFF2;\r
- SENS -= SENS2; \r
- P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);\r
-\r
- index = pressure_report_value(sensor->input_dev, P);\r
-\r
- DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);\r
- \r
- return result;\r
-}\r
-\r
-struct sensor_operate pressure_ms5607_ops = {\r
- .name = "pr_ms5607",\r
- .type = SENSOR_TYPE_PRESSURE, //sensor type and it should be correct\r
- .id_i2c = PRESSURE_ID_MS5607, //i2c id number\r
- .read_reg = SENSOR_UNKNOW_DATA, //read data\r
- .read_len = 3, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 24, //8 bits\r
- .ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
- .range = {100,65535}, //range\r
- .brightness = {10,255}, //brightness\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *pressure_get_ops(void)\r
-{\r
- return &pressure_ms5607_ops;\r
-}\r
-\r
-\r
-static int __init pressure_ms5607_init(void)\r
-{\r
- struct sensor_operate *ops = pressure_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, pressure_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit pressure_ms5607_exit(void)\r
-{\r
- struct sensor_operate *ops = pressure_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, pressure_get_ops);\r
-}\r
-\r
-\r
-module_init(pressure_ms5607_init);\r
-module_exit(pressure_ms5607_exit);\r
-\r
+/* drivers/input/sensors/pressure/ms5607.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define CMD_RESET 0x1E // ADC reset command
+#define CMD_ADC_READ 0x00 // ADC read command
+#define CMD_ADC_CONV 0x40 // ADC conversion command
+#define CMD_ADC_D1 0x00 // ADC D1 conversion
+#define CMD_ADC_D2 0x10 // ADC D2 conversion
+#define CMD_ADC_256 0x00 // ADC OSR=256
+#define CMD_ADC_512 0x02 // ADC OSR=512
+#define CMD_ADC_1024 0x04 // ADC OSR=1024
+#define CMD_ADC_2048 0x06 // ADC OSR=2048
+#define CMD_ADC_4096 0x08 // ADC OSR=4096
+#define CMD_PROM_RD 0xA0 // Prom read command
+
+
+/****************operate according to sensor chip:start************/
+
+static int C[8] = {0};
+int g_ms5607_temp;
+int g_ms5607_pr_status;
+
+#if defined(CONFIG_TMP_MS5607)
+extern int g_ms5607_temp_status;
+#else
+static int g_ms5607_temp_status = SENSOR_OFF;
+#endif
+
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ int result = 0;
+ int i = 0;
+ char prom[16];
+
+ if((enable) && (g_ms5607_temp_status == SENSOR_OFF))
+ {
+ result = sensor_write_reg_normal(client, CMD_RESET);
+ if(result)
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+
+ //Read PROM (128 bit of calibration words)
+ memset(prom, 0, 16);
+ prom[0]= CMD_PROM_RD;//CMD_PROM_RD;
+ for(i=0; i<8; i++)
+ {
+ prom[i*2]= CMD_PROM_RD + i*2;
+ result = sensor_rx_data(client, &prom[i*2], 2);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+ }
+
+ for (i=0;i<8;i++)
+ {
+ C[i] = prom[2*i] << 8 | prom[2*i + 1];
+ //printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
+ //printk("\nC[%d]=%d,",i+1,C[i]);
+ }
+
+ }
+
+ g_ms5607_pr_status = enable;
+
+ return result;
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+ g_ms5607_pr_status = sensor->status_cur;
+
+ //Reset
+ //result = sensor_write_reg_normal(client, CMD_RESET);
+ //if(result)
+ //printk("%s:line=%d,error\n",__func__,__LINE__);
+
+ return result;
+}
+
+
+static int pressure_report_value(struct input_dev *input, int data)
+{
+ //get pressure, high and temperature from register data
+
+ input_report_abs(input, ABS_PRESSURE, data);
+ input_sync(input);
+
+ return 0;
+}
+
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+
+ int result = 0;
+ char buffer[3];
+ char index = 0;
+ unsigned int D1=0, D2=0;
+
+ int T2 = 0;
+ long long OFF = 0; // offset at actual temperature
+ long long SENS = 0; // sensitivity at actual temperature
+ int dT = 0; // difference between actual and measured temperature
+ long long OFF2 = 0;
+ long long SENS2 = 0;
+ int P = 0; // compensated pressure value
+
+
+ memset(buffer, 0, 3);
+ if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
+ {
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+ return -1;
+ }
+
+ //D1 conversion
+ sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);
+ msleep(10);
+
+ memset(buffer, 0, 3);
+ buffer[0] = CMD_ADC_READ;
+ result = sensor_rx_data(client, &buffer[0], 3);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+ DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);
+
+ //D2 conversion
+ sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);
+ msleep(10);
+
+ memset(buffer, 0, 3);
+ buffer[0] = CMD_ADC_READ;
+ result = sensor_rx_data(client, &buffer[0], 3);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+ DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);
+
+ dT = D2 - ((unsigned int)C[5] << 8);
+
+ g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));
+
+ OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);
+
+ SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);
+
+ /*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/
+ if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)
+ {
+ printk("%s:temperature is error\n",__func__);
+ return -1;
+ }
+
+ if (g_ms5607_temp < 2000)
+ {
+ int tmp;
+ tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);
+
+ T2 = (int)((long long)(dT * dT) >> 31);
+ OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;
+ SENS2 = (long long)((tmp*tmp) << 1);
+
+ if (g_ms5607_temp < -1500)
+ {
+ tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);
+ OFF2 += 15 * tmp;
+ SENS2 += 8 * tmp;
+ }
+ }
+ else
+ {
+ T2=0;
+ OFF2 = 0;
+ SENS2 = 0;
+ }
+
+ g_ms5607_temp -= T2;
+ OFF -= OFF2;
+ SENS -= SENS2;
+ P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);
+
+ index = pressure_report_value(sensor->input_dev, P);
+
+ DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
+
+ return result;
+}
+
+struct sensor_operate pressure_ms5607_ops = {
+ .name = "pr_ms5607",
+ .type = SENSOR_TYPE_PRESSURE, //sensor type and it should be correct
+ .id_i2c = PRESSURE_ID_MS5607, //i2c id number
+ .read_reg = SENSOR_UNKNOW_DATA, //read data
+ .read_len = 3, //data length
+ .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
+ .id_data = SENSOR_UNKNOW_DATA, //device id
+ .precision = 24, //8 bits
+ .ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable
+ .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
+ .range = {100,65535}, //range
+ .brightness = {10,255}, //brightness
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *pressure_get_ops(void)
+{
+ return &pressure_ms5607_ops;
+}
+
+
+static int __init pressure_ms5607_init(void)
+{
+ struct sensor_operate *ops = pressure_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, pressure_get_ops);
+ return result;
+}
+
+static void __exit pressure_ms5607_exit(void)
+{
+ struct sensor_operate *ops = pressure_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, pressure_get_ops);
+}
+
+
+module_init(pressure_ms5607_init);
+module_exit(pressure_ms5607_exit);
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define CONFIG_REG (0x00)\r
-#define TIM_CTL_REG (0x01)\r
-#define ALS_CTL_REG (0x02)\r
-#define INT_STATUS_REG (0x03)\r
-#define PS_CTL_REG (0x04)\r
-#define PS_ALS_DATA_REG (0x05)\r
-#define ALS_WINDOWS_REG (0x08)\r
-\r
-//enable bit[ 0-1], in register CONFIG_REG\r
-#define ONLY_ALS_EN (0x00)\r
-#define ONLY_PROX_EN (0x01)\r
-#define ALL_PROX_ALS_EN (0x02)\r
-#define ALL_IDLE (0x03)\r
-\r
-#define POWER_MODE_MASK (0x0C)\r
-#define POWER_UP_MODE (0x00)\r
-#define POWER_DOWN_MODE (0x08)\r
-#define POWER_RESET_MODE (0x0C)\r
-\r
-static int sensor_power_updown(struct i2c_client *client, int on)\r
-{\r
- int result = 0;\r
- char value = 0;\r
- int i = 0;\r
- for(i=0; i<3; i++)\r
- {\r
- if(!on)\r
- {\r
- value = sensor_read_reg(client, CONFIG_REG);\r
- value &= ~POWER_MODE_MASK;\r
- value |= POWER_DOWN_MODE;\r
- result = sensor_write_reg(client, CONFIG_REG, value);\r
- if(result)\r
- return result;\r
- }\r
- else\r
- {\r
- value = sensor_read_reg(client, CONFIG_REG);\r
- value &= ~POWER_MODE_MASK;\r
- value |= POWER_UP_MODE;\r
- result = sensor_write_reg(client, CONFIG_REG, value);\r
- if(result)\r
- return result;\r
- }\r
- \r
- if(!result)\r
- break;\r
- }\r
-\r
- if(i>1)\r
- printk("%s:set %d times",__func__,i);\r
- \r
- return result;\r
-}\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
-\r
- if(enable) \r
- sensor_power_updown(client, 1);\r
-\r
- value = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(enable)\r
- { \r
- if( (value & 0x03) == ONLY_ALS_EN )\r
- {\r
- value &= ~0x03;\r
- value |= ALL_PROX_ALS_EN;\r
- }\r
- else if((value & 0x03) == ALL_IDLE )\r
- {\r
- value &= ~0x03;\r
- value |= ONLY_PROX_EN;\r
- }\r
- \r
- }\r
- else\r
- {\r
- if( (value & 0x03) == ONLY_PROX_EN )\r
- {\r
- value &= ~0x03;\r
- value |= ALL_IDLE;\r
- }\r
- else if((value & 0x03) == ALL_PROX_ALS_EN )\r
- {\r
- value &= ~0x03;\r
- value |= ONLY_ALS_EN;\r
- }\r
- }\r
- \r
- sensor->ops->ctrl_data = value;\r
- \r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- \r
- sensor_power_updown(client, 0);\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- value = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define CONFIG_REG (0x00)
+#define TIM_CTL_REG (0x01)
+#define ALS_CTL_REG (0x02)
+#define INT_STATUS_REG (0x03)
+#define PS_CTL_REG (0x04)
+#define PS_ALS_DATA_REG (0x05)
+#define ALS_WINDOWS_REG (0x08)
+
+//enable bit[ 0-1], in register CONFIG_REG
+#define ONLY_ALS_EN (0x00)
+#define ONLY_PROX_EN (0x01)
+#define ALL_PROX_ALS_EN (0x02)
+#define ALL_IDLE (0x03)
+
+#define POWER_MODE_MASK (0x0C)
+#define POWER_UP_MODE (0x00)
+#define POWER_DOWN_MODE (0x08)
+#define POWER_RESET_MODE (0x0C)
+
+static int sensor_power_updown(struct i2c_client *client, int on)
+{
+ int result = 0;
+ char value = 0;
+ int i = 0;
+ for(i=0; i<3; i++)
+ {
+ if(!on)
+ {
+ value = sensor_read_reg(client, CONFIG_REG);
+ value &= ~POWER_MODE_MASK;
+ value |= POWER_DOWN_MODE;
+ result = sensor_write_reg(client, CONFIG_REG, value);
+ if(result)
+ return result;
+ }
+ else
+ {
+ value = sensor_read_reg(client, CONFIG_REG);
+ value &= ~POWER_MODE_MASK;
+ value |= POWER_UP_MODE;
+ result = sensor_write_reg(client, CONFIG_REG, value);
+ if(result)
+ return result;
+ }
+
+ if(!result)
+ break;
+ }
+
+ if(i>1)
+ printk("%s:set %d times",__func__,i);
+
+ return result;
+}
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+
+ if(enable)
+ sensor_power_updown(client, 1);
+
+ value = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ //register setting according to chip datasheet
+ if(enable)
+ {
+ if( (value & 0x03) == ONLY_ALS_EN )
+ {
+ value &= ~0x03;
+ value |= ALL_PROX_ALS_EN;
+ }
+ else if((value & 0x03) == ALL_IDLE )
+ {
+ value &= ~0x03;
+ value |= ONLY_PROX_EN;
+ }
+
+ }
+ else
+ {
+ if( (value & 0x03) == ONLY_PROX_EN )
+ {
+ value &= ~0x03;
+ value |= ALL_IDLE;
+ }
+ else if((value & 0x03) == ALL_PROX_ALS_EN )
+ {
+ value &= ~0x03;
+ value |= ONLY_ALS_EN;
+ }
+ }
+
+ sensor->ops->ctrl_data = value;
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ char value = 0;
+
+ sensor_power_updown(client, 0);
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ value = 0x41;//The ADC effective resolution = 9; Low lux threshold level = 1;
//value = 0x69; //The ADC effective resolution = 17; Low lux threshold level = 9;
- result = sensor_write_reg(client, ALS_CTL_REG, value);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
+ 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% \r
- result = sensor_write_reg(client, ALS_WINDOWS_REG, value);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
-\r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(sensor->ops->int_status_reg)\r
- {\r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- }\r
- \r
- }\r
-\r
- value = sensor_read_reg(client, sensor->ops->read_reg); \r
- input_report_abs(sensor->input_dev, ABS_DISTANCE, (value>>7)?0:1);\r
- input_sync(sensor->input_dev);\r
- DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,(value>>7)?0:1); \r
-\r
- return result;\r
-}\r
-\r
-struct sensor_operate proximity_al3006_ops = {\r
- .name = "ps_al3006",\r
- .type = SENSOR_TYPE_PROXIMITY,//sensor type and it should be correct\r
- .id_i2c = PROXIMITY_ID_AL3006, //i2c id number\r
- .read_reg = PS_ALS_DATA_REG, //read data\r
- .read_len = 1, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = CONFIG_REG, //enable or disable \r
- .int_status_reg = INT_STATUS_REG, //intterupt status register\r
- .range = {0,10}, //range\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *proximity_get_ops(void)\r
-{\r
- return &proximity_al3006_ops;\r
-}\r
-\r
-\r
-static int __init proximity_al3006_init(void)\r
-{\r
- struct sensor_operate *ops = proximity_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit proximity_al3006_exit(void)\r
-{\r
- struct sensor_operate *ops = proximity_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);\r
-}\r
-\r
-\r
-module_init(proximity_al3006_init);\r
-module_exit(proximity_al3006_exit);\r
-\r
-\r
+ 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);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <mach/gpio.h>\r
-#include <mach/board.h> \r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
#define AP3212B_NUM_CACHABLE_REGS 23
-#define AP3216C_NUM_CACHABLE_REGS 26\r
-\r
+#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\r
-\r
+#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
-\r
+
#define AP3212B_OBJ_COMMAND 0x0f
#define AP3212B_OBJ_MASK 0x80
-#define AP3212B_OBJ_SHIFT (7)\r
-\r
-\r
+#define AP3212B_OBJ_SHIFT (7)
+
+
/*
* register access helpers
*/
static int __ap321xx_read_reg(struct i2c_client *client,
u32 reg, u8 mask, u8 shift)
{
- u8 val;\r
+ u8 val;
val = i2c_smbus_read_byte_data(client, reg);
- return (val & mask) >> shift;\r
+ return (val & mask) >> shift;
}
static int __ap321xx_write_reg(struct i2c_client *client,
u32 reg, u8 mask, u8 shift, u8 val)
{
- int ret = 0;\r
+ int ret = 0;
u8 tmp;
tmp = i2c_smbus_read_byte_data(client, reg);
tmp |= val << shift;
ret = i2c_smbus_write_byte_data(client, reg, tmp);
-
+
return ret;
}
-\r
-\r
+
+
/*
* internally used functions
- */\r
+ */
/* range */
-static int ap321xx_set_range(struct i2c_client *client, int range)\r
+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);;
/* mode */
static int ap321xx_get_mode(struct i2c_client *client)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ 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)\r
+static int ap321xx_set_mode(struct i2c_client *client, int mode)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ 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;
-}\r
+}
static int ap321xx_get_intstat(struct i2c_client *client)
{
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int val;\r
- \r
- val = i2c_smbus_read_byte_data(client, sensor->ops->int_status_reg);\r
- val &= AP3212B_INT_MASK;\r
-\r
- return val >> AP3212B_INT_SHIFT;\r
-}\r
-\r
+ 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;
return val >> AP3212B_OBJ_SHIFT;
}
-\r
-\r
-static int ap321xx_product_detect(struct i2c_client *client)\r
+
+
+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);\r
+ //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);\r
+ //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);\r
+ printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
return -EIO;
}
-\r
+
return 0;
-}\r
-\r
+}
+
static int ap321xx_init_client(struct i2c_client *client)
{
/* set defaults */
ap321xx_set_mode(client, 0);
return 0;
-}\r
-\r
+}
+
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;
ret = ap321xx_set_mode(client,mode);
}
return ret;
-}\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- int result = 0;\r
- \r
- //register setting according to chip datasheet \r
- if (enable){\r
- result = ap321xx_psensor_enable(client);\r
- }\r
- else\r
- result = ap321xx_psensor_disable(client);\r
-\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
-\r
- result = ap321xx_product_detect(client);\r
- if (result)\r
+}
+
+/****************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);\r
- return result;\r
- }\r
-\r
+ dev_err(&client->dev, "ret: %d, product version detect failed.\n",result);
+ return result;
+ }
+
/* initialize the AP3212B chip */
- result = ap321xx_init_client(client);\r
- if (result)\r
- return result;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- \r
- return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char value = 0;\r
- u8 int_stat;\r
- \r
- int_stat = ap321xx_get_intstat(client);\r
+ 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)\r
+ if (int_stat & AP3212B_INT_PMASK)
{
- value = ap321xx_get_object(client);\r
- input_report_abs(sensor->input_dev, ABS_DISTANCE, value);\r
- input_sync(sensor->input_dev);\r
+ value = ap321xx_get_object(client);
+ input_report_abs(sensor->input_dev, ABS_DISTANCE, value);
+ input_sync(sensor->input_dev);
}
- \r
- return result;\r
-}\r
-\r
-struct sensor_operate proximity_ap321xx_ops = {\r
- .name = "ps_ap321xx",\r
- .type = SENSOR_TYPE_PROXIMITY, //sensor type and it should be correct\r
- .id_i2c = PROXIMITY_ID_AP321XX, //i2c id number\r
- .read_reg = SENSOR_UNKNOW_DATA, //read data //there are two regs, we fix them in code.\r
- .read_len = 1, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register //there are 3 regs, we fix them in code.\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = AP3212B_MODE_COMMAND, //enable or disable \r
- .int_status_reg = AP3212B_INT_COMMAND, //intterupt status register\r
- .range = {0,10}, //range\r
- .brightness ={10,255}, // brightness\r
- .trig = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *proximity_get_ops(void)\r
-{\r
- return &proximity_ap321xx_ops;\r
-}\r
-\r
-\r
-static int __init proximity_ap321xx_init(void)\r
-{\r
- struct sensor_operate *ops = proximity_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit proximity_ap321xx_exit(void)\r
-{\r
- struct sensor_operate *ops = proximity_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);\r
-}\r
-\r
-\r
-module_init(proximity_ap321xx_init);\r
-module_exit(proximity_ap321xx_exit);\r
-\r
-\r
+
+ 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);
+
+
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define ALS_CMD 0x01\r
-#define ALS_DT1 0x02\r
-#define ALS_DT2 0X03\r
-#define ALS_THDH1 0X04\r
-#define ALS_THDH2 0X05\r
-#define ALS_THDL1 0X06\r
-#define ALS_THDL2 0X07\r
-#define STA_TUS 0X08\r
-#define PS_CMD 0X09\r
-#define PS_DT 0X0A\r
-#define PS_THDH 0X0B\r
-#define PS_THDL 0X0C\r
-#define SW_RESET 0X80\r
-\r
-//ALS_CMD\r
-#define ALS_SD_ENABLE (0<<0)\r
-#define ALS_SD_DISABLE (1<<0)\r
-#define ALS_INT_DISABLE (0<<1)\r
-#define ALS_INT_ENABLE (1<<1)\r
-#define ALS_1T_100MS (0<<2)\r
-#define ALS_2T_200MS (1<<2)\r
-#define ALS_4T_400MS (2<<2)\r
-#define ALS_8T_800MS (3<<2)\r
-#define ALS_RANGE_57671 (0<<6)\r
-#define ALS_RANGE_28836 (1<<6)\r
-\r
-//PS_CMD\r
-#define PS_SD_ENABLE (0<<0)\r
-#define PS_SD_DISABLE (1<<0)\r
-#define PS_INT_DISABLE (0<<1)\r
-#define PS_INT_ENABLE (1<<1)\r
-#define PS_10T_2MS (0<<2)\r
-#define PS_15T_3MS (1<<2)\r
-#define PS_20T_4MS (2<<2)\r
-#define PS_25T_5MS (3<<2)\r
-#define PS_CUR_100MA (0<<4)\r
-#define PS_CUR_200MA (1<<4)\r
-#define PS_SLP_10MS (0<<5)\r
-#define PS_SLP_30MS (1<<5)\r
-#define PS_SLP_90MS (2<<5)\r
-#define PS_SLP_270MS (3<<5)\r
-#define TRIG_PS_OR_LS (0<<7)\r
-#define TRIG_PS_AND_LS (1<<7)\r
-\r
-//STA_TUS\r
-#define STA_PS_INT (1<<5)\r
-#define STA_ALS_INT (1<<4)\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int status = 0;\r
-\r
- sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
- \r
- //register setting according to chip datasheet \r
- if(!enable)\r
- { \r
- status = PS_SD_DISABLE; \r
- sensor->ops->ctrl_data |= status; \r
- }\r
- else\r
- {\r
- status = ~PS_SD_DISABLE;\r
- sensor->ops->ctrl_data &= status;\r
- }\r
- \r
- DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- printk("%s:fail to active sensor\n",__func__);\r
-\r
- if(enable)\r
- sensor->ops->report(sensor->client);\r
-\r
- return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
-\r
- result = sensor_write_reg(client, SW_RESET, 0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
-\r
- sensor->ops->ctrl_data |= PS_15T_3MS| PS_SLP_90MS;\r
- sensor->ops->ctrl_data &= ~TRIG_PS_AND_LS;\r
-\r
- if(sensor->pdata->irq_enable)\r
- sensor->ops->ctrl_data |= PS_INT_ENABLE;\r
- else\r
- sensor->ops->ctrl_data &= ~PS_INT_ENABLE;\r
- \r
- result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int value = 0;\r
- char buffer[1] = {0}; \r
- \r
- if(sensor->ops->read_len < 1) //sensor->ops->read_len = 1\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
- \r
- memset(buffer, 0, 1);\r
-\r
- buffer[0] = sensor->ops->read_reg;\r
- result = sensor_rx_data(client, buffer, sensor->ops->read_len); \r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
-\r
- value = buffer[0];\r
- \r
- input_report_abs(sensor->input_dev, ABS_DISTANCE, (value>>2)?0:1);\r
- input_sync(sensor->input_dev);\r
- DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,(value>>2)?0:1); \r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(sensor->ops->int_status_reg)\r
- { \r
- value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
- }\r
- \r
- if(value & STA_PS_INT)\r
- {\r
- value &= ~STA_PS_INT;\r
- result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- }\r
- }\r
- \r
- return result;\r
-}\r
-\r
-struct sensor_operate proximity_stk3171_ops = {\r
- .name = "ps_stk3171",\r
- .type = SENSOR_TYPE_PROXIMITY, //sensor type and it should be correct\r
- .id_i2c = PROXIMITY_ID_STK3171, //i2c id number\r
- .read_reg = PS_DT, //read data\r
- .read_len = 1, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 8, //8 bits\r
- .ctrl_reg = PS_CMD, //enable or disable \r
- .int_status_reg = STA_TUS, //intterupt status register\r
- .range = {0,1}, //range\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *proximity_get_ops(void)\r
-{\r
- return &proximity_stk3171_ops;\r
-}\r
-\r
-static int __init proximity_stk3171_init(void)\r
-{\r
- struct sensor_operate *ops = proximity_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit proximity_stk3171_exit(void)\r
-{\r
- struct sensor_operate *ops = proximity_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);\r
-}\r
-\r
-\r
-module_init(proximity_stk3171_init);\r
-module_exit(proximity_stk3171_exit);\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define ALS_CMD 0x01
+#define ALS_DT1 0x02
+#define ALS_DT2 0X03
+#define ALS_THDH1 0X04
+#define ALS_THDH2 0X05
+#define ALS_THDL1 0X06
+#define ALS_THDL2 0X07
+#define STA_TUS 0X08
+#define PS_CMD 0X09
+#define PS_DT 0X0A
+#define PS_THDH 0X0B
+#define PS_THDL 0X0C
+#define SW_RESET 0X80
+
+//ALS_CMD
+#define ALS_SD_ENABLE (0<<0)
+#define ALS_SD_DISABLE (1<<0)
+#define ALS_INT_DISABLE (0<<1)
+#define ALS_INT_ENABLE (1<<1)
+#define ALS_1T_100MS (0<<2)
+#define ALS_2T_200MS (1<<2)
+#define ALS_4T_400MS (2<<2)
+#define ALS_8T_800MS (3<<2)
+#define ALS_RANGE_57671 (0<<6)
+#define ALS_RANGE_28836 (1<<6)
+
+//PS_CMD
+#define PS_SD_ENABLE (0<<0)
+#define PS_SD_DISABLE (1<<0)
+#define PS_INT_DISABLE (0<<1)
+#define PS_INT_ENABLE (1<<1)
+#define PS_10T_2MS (0<<2)
+#define PS_15T_3MS (1<<2)
+#define PS_20T_4MS (2<<2)
+#define PS_25T_5MS (3<<2)
+#define PS_CUR_100MA (0<<4)
+#define PS_CUR_200MA (1<<4)
+#define PS_SLP_10MS (0<<5)
+#define PS_SLP_30MS (1<<5)
+#define PS_SLP_90MS (2<<5)
+#define PS_SLP_270MS (3<<5)
+#define TRIG_PS_OR_LS (0<<7)
+#define TRIG_PS_AND_LS (1<<7)
+
+//STA_TUS
+#define STA_PS_INT (1<<5)
+#define STA_ALS_INT (1<<4)
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int status = 0;
+
+ sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+ //register setting according to chip datasheet
+ if(!enable)
+ {
+ status = PS_SD_DISABLE;
+ sensor->ops->ctrl_data |= status;
+ }
+ else
+ {
+ status = ~PS_SD_DISABLE;
+ sensor->ops->ctrl_data &= status;
+ }
+
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ printk("%s:fail to active sensor\n",__func__);
+
+ if(enable)
+ sensor->ops->report(sensor->client);
+
+ return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+
+ result = sensor_write_reg(client, SW_RESET, 0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+
+ sensor->ops->ctrl_data |= PS_15T_3MS| PS_SLP_90MS;
+ sensor->ops->ctrl_data &= ~TRIG_PS_AND_LS;
+
+ if(sensor->pdata->irq_enable)
+ sensor->ops->ctrl_data |= PS_INT_ENABLE;
+ else
+ sensor->ops->ctrl_data &= ~PS_INT_ENABLE;
+
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ return result;
+}
+
+
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+ int value = 0;
+ char buffer[1] = {0};
+
+ if(sensor->ops->read_len < 1) //sensor->ops->read_len = 1
+ {
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+ return -1;
+ }
+
+ memset(buffer, 0, 1);
+
+ buffer[0] = sensor->ops->read_reg;
+ result = sensor_rx_data(client, buffer, sensor->ops->read_len);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+
+ value = buffer[0];
+
+ input_report_abs(sensor->input_dev, ABS_DISTANCE, (value>>2)?0:1);
+ input_sync(sensor->input_dev);
+ DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,(value>>2)?0:1);
+
+ if(sensor->pdata->irq_enable)
+ {
+ if(sensor->ops->int_status_reg)
+ {
+ value = sensor_read_reg(client, sensor->ops->int_status_reg);
+ }
+
+ if(value & STA_PS_INT)
+ {
+ value &= ~STA_PS_INT;
+ result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+ }
+ }
+
+ return result;
+}
+
+struct sensor_operate proximity_stk3171_ops = {
+ .name = "ps_stk3171",
+ .type = SENSOR_TYPE_PROXIMITY, //sensor type and it should be correct
+ .id_i2c = PROXIMITY_ID_STK3171, //i2c id number
+ .read_reg = PS_DT, //read data
+ .read_len = 1, //data length
+ .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
+ .id_data = SENSOR_UNKNOW_DATA, //device id
+ .precision = 8, //8 bits
+ .ctrl_reg = PS_CMD, //enable or disable
+ .int_status_reg = STA_TUS, //intterupt status register
+ .range = {0,1}, //range
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *proximity_get_ops(void)
+{
+ return &proximity_stk3171_ops;
+}
+
+static int __init proximity_stk3171_init(void)
+{
+ struct sensor_operate *ops = proximity_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
+ return result;
+}
+
+static void __exit proximity_stk3171_exit(void)
+{
+ struct sensor_operate *ops = proximity_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, proximity_get_ops);
+}
+
+
+module_init(proximity_stk3171_init);
+module_exit(proximity_stk3171_exit);
+
+
-/* drivers/input/sensors/sensor-dev.c - handle all gsensor in this file\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/proc_fs.h>\r
-#include <linux/gpio.h>\r
-#include <linux/of_gpio.h>\r
-#include <linux/of.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/l3g4200d.h>\r
-#include <linux/sensor-dev.h>\r
-#include <linux/module.h>\r
+/* drivers/input/sensors/sensor-dev.c - handle all gsensor in this file
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/proc_fs.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/l3g4200d.h>
+#include <linux/sensor-dev.h>
+#include <linux/module.h>
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
#endif
-\r
-\r
-/*\r
-sensor-dev.c v1.1 add pressure and temperature support 2013-2-27\r
-sensor-dev.c v1.2 add akm8963 support 2013-3-10\r
-sensor-dev.c v1.3 add sensor debug support 2013-3-15\r
-sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01\r
-*/\r
-\r
-#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01"\r
-\r
-\r
-struct sensor_private_data *g_sensor[SENSOR_NUM_TYPES];\r
-static struct sensor_operate *sensor_ops[SENSOR_NUM_ID]; \r
-static struct class *g_sensor_class[SENSOR_NUM_TYPES];\r
-\r
-static ssize_t sensor_proc_write(struct file *file, const char __user *buffer,\r
- size_t count, loff_t *data)\r
-{\r
- char c;\r
- int rc;\r
- int i = 0, num = 0;\r
- \r
- rc = get_user(c, buffer);\r
- if (rc)\r
- {\r
- for(i=SENSOR_TYPE_NULL+1; i<SENSOR_NUM_TYPES; i++)\r
- atomic_set(&g_sensor[i]->flags.debug_flag, SENSOR_TYPE_NULL);\r
- return rc; \r
- }\r
-\r
- \r
- num = c - '0';\r
-\r
- 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__,\r
- \r
- SENSOR_TYPE_NULL, SENSOR_TYPE_ANGLE, SENSOR_TYPE_ACCEL,SENSOR_TYPE_COMPASS,SENSOR_TYPE_GYROSCOPE,SENSOR_TYPE_LIGHT,SENSOR_TYPE_PROXIMITY,\r
-\r
- SENSOR_TYPE_TEMPERATURE,SENSOR_TYPE_PRESSURE,SENSOR_NUM_TYPES,num);\r
-\r
- if((num > SENSOR_NUM_TYPES) || (num < SENSOR_TYPE_NULL))\r
- {\r
- printk("%s:error! only support %d to %d\n",__func__, SENSOR_TYPE_NULL,SENSOR_NUM_TYPES);\r
- return -1;\r
- }\r
-\r
- for(i=SENSOR_TYPE_NULL+1; i<SENSOR_NUM_TYPES; i++)\r
- {\r
- if(g_sensor[i])\r
- atomic_set(&g_sensor[i]->flags.debug_flag, num);\r
- }\r
- \r
- return count; \r
-}\r
-\r
-static const struct file_operations sensor_proc_fops = {\r
- .owner = THIS_MODULE, \r
- .write = sensor_proc_write,\r
-};\r
-\r
-\r
-\r
-static int sensor_get_id(struct i2c_client *client, int *value)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- char temp = sensor->ops->id_reg;\r
- int i = 0;\r
-\r
- if(sensor->ops->id_reg >= 0)\r
- {\r
- for(i=0; i<3; i++)\r
- {\r
- result = sensor_rx_data(client, &temp, 1);\r
- *value = temp;\r
- if(!result)\r
- break;\r
- }\r
-\r
- if(result)\r
- return result;\r
-\r
- if(*value != sensor->ops->id_data)\r
- {\r
- printk("%s:id=0x%x is not 0x%x\n",__func__,*value, sensor->ops->id_data);\r
- result = -1;\r
- }\r
- \r
- DBG("%s:devid=0x%x\n",__func__,*value);\r
- }\r
- \r
- return result;\r
-}\r
-\r
-static int sensor_initial(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
-\r
- //register setting according to chip datasheet \r
- result = sensor->ops->init(client);\r
- if(result < 0)\r
- {\r
- printk("%s:fail to init sensor\n",__func__);\r
- return result;\r
- }\r
-\r
-\r
- DBG("%s:ctrl_data=0x%x\n",__func__,sensor->ops->ctrl_data);\r
- \r
- return result;\r
-\r
-}\r
-\r
-static int sensor_chip_init(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- struct sensor_operate *ops = sensor_ops[(int)sensor->i2c_id->driver_data];\r
- int result = 0;\r
- \r
- if(ops)\r
- {\r
- sensor->ops = ops;\r
- }\r
- else\r
- {\r
- printk("%s:ops is null,sensor name is %s\n",__func__,sensor->i2c_id->name);\r
- result = -1;\r
- goto error;\r
- }\r
-\r
- if((sensor->type != ops->type) || ((int)sensor->i2c_id->driver_data != ops->id_i2c))\r
- {\r
- 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);\r
- result = -1;\r
- goto error;\r
- }\r
- \r
- if(!ops->init || !ops->active || !ops->report)\r
- {\r
- printk("%s:error:some function is needed\n",__func__); \r
- result = -1;\r
- goto error;\r
- }\r
-\r
- result = sensor_get_id(sensor->client, &sensor->devid);//get id\r
- if(result < 0)\r
- { \r
- printk("%s:fail to read %s devid:0x%x\n",__func__, sensor->i2c_id->name, sensor->devid); \r
- goto error;\r
- }\r
- \r
- printk("%s:%s:devid=0x%x,ops=0x%p\n",__func__, sensor->i2c_id->name, sensor->devid,sensor->ops);\r
-\r
- result = sensor_initial(sensor->client); //init sensor\r
- if(result < 0)\r
- { \r
- printk("%s:fail to init sensor\n",__func__); \r
- goto error;\r
- }\r
-\r
- return 0;\r
-\r
-error:\r
- \r
- return result;\r
-}\r
-\r
-static int sensor_reset_rate(struct i2c_client *client, int rate)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0; \r
- \r
- result = sensor->ops->active(client,SENSOR_OFF,rate);\r
- sensor->ops->init(client);\r
- result = sensor->ops->active(client,SENSOR_ON,rate);\r
-\r
- return result;\r
-}\r
-\r
-static int sensor_get_data(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->report(client);\r
- if(result)\r
- goto error;\r
-\r
- /* set data_ready */\r
- atomic_set(&sensor->data_ready, 1);\r
- /*wake up data_ready work queue*/\r
- wake_up(&sensor->data_ready_wq);\r
- \r
-error: \r
- return result;\r
-}\r
-\r
-#if 0\r
-int sensor_get_cached_data(struct i2c_client* client, char *buffer, int length, struct sensor_axis *axis)\r
-{\r
- struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(client); \r
- wait_event_interruptible_timeout(sensor->data_ready_wq, \r
- atomic_read(&(sensor->data_ready) ),\r
- msecs_to_jiffies(1000) );\r
- if ( 0 == atomic_read(&(sensor->data_ready) ) ) {\r
- printk("waiting 'data_ready_wq' timed out.");\r
- goto error;\r
- }\r
-\r
- \r
- mutex_lock(&sensor->data_mutex);\r
-\r
- switch(sensor->type)\r
- {\r
- case SENSOR_TYPE_ACCEL:\r
- *axis = sensor->axis;\r
- break;\r
-\r
- case SENSOR_TYPE_COMPASS:\r
- memcpy(buffer, sensor->sensor_data, length);\r
- break;\r
- }\r
- \r
- mutex_unlock(&sensor->data_mutex);\r
- \r
- return 0;\r
- \r
-error:\r
- return -1;\r
-}\r
-#endif\r
-\r
-static void sensor_delaywork_func(struct work_struct *work)\r
-{\r
- struct delayed_work *delaywork = container_of(work, struct delayed_work, work);\r
- struct sensor_private_data *sensor = container_of(delaywork, struct sensor_private_data, delaywork);\r
- struct i2c_client *client = sensor->client;\r
-\r
- mutex_lock(&sensor->sensor_mutex); \r
- if (sensor_get_data(client) < 0) \r
- DBG(KERN_ERR "%s: Get data failed\n",__func__);\r
- \r
- if(!sensor->pdata->irq_enable)//restart work while polling\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- //else\r
- //{\r
- //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH))\r
- //enable_irq(sensor->client->irq);\r
- //}\r
- mutex_unlock(&sensor->sensor_mutex);\r
- \r
- DBG("%s:%s\n",__func__,sensor->i2c_id->name);\r
-}\r
-\r
-/*\r
- * This is a threaded IRQ handler so can access I2C/SPI. Since all\r
- * interrupts are clear on read the IRQ line will be reasserted and\r
- * the physical IRQ will be handled again if another interrupt is\r
- * asserted while we run - in the normal course of events this is a\r
- * rare occurrence so we save I2C/SPI reads. We're also assuming that\r
- * it's rare to get lots of interrupts firing simultaneously so try to\r
- * minimise I/O.\r
- */\r
-static irqreturn_t sensor_interrupt(int irq, void *dev_id)\r
-{\r
- struct sensor_private_data *sensor = (struct sensor_private_data *)dev_id;\r
-\r
- //use threaded IRQ\r
- if (sensor_get_data(sensor->client) < 0) \r
- DBG(KERN_ERR "%s: Get data failed\n",__func__);\r
- msleep(sensor->pdata->poll_delay_ms);\r
-\r
- \r
- //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH))\r
- //disable_irq_nosync(irq);\r
- //schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- DBG("%s:irq=%d\n",__func__,irq);\r
- return IRQ_HANDLED;\r
-}\r
-\r
-\r
-static int sensor_irq_init(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- int irq;\r
- if((sensor->pdata->irq_enable)&&(sensor->pdata->irq_flags!= SENSOR_UNKNOW_DATA))\r
- {\r
- //INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
- if(sensor->pdata->poll_delay_ms < 0)\r
- sensor->pdata->poll_delay_ms = 30;\r
- result = gpio_request(client->irq, sensor->i2c_id->name);\r
- if (result)\r
- {\r
- printk("%s:fail to request gpio :%d\n",__func__,client->irq);\r
- }\r
- \r
- //gpio_pull_updown(client->irq, PullEnable);\r
- irq = gpio_to_irq(client->irq);\r
- //result = request_irq(irq, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor);\r
- //result = request_threaded_irq(irq, NULL, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor);\r
- result = devm_request_threaded_irq(&client->dev, irq, NULL, sensor_interrupt, sensor->pdata->irq_flags | IRQF_ONESHOT, sensor->ops->name, sensor);\r
- if (result) {\r
- printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, irq, result); \r
- goto error; \r
- }\r
- client->irq = irq;\r
- if((sensor->pdata->type == SENSOR_TYPE_GYROSCOPE) || (sensor->pdata->type == SENSOR_TYPE_ACCEL) || (sensor->pdata->type == SENSOR_TYPE_ANGLE))\r
- disable_irq_nosync(client->irq);//disable irq\r
- if(((sensor->pdata->type == SENSOR_TYPE_LIGHT) || (sensor->pdata->type == SENSOR_TYPE_PROXIMITY))&& (!(sensor->ops->trig & IRQF_SHARED))) \r
- disable_irq_nosync(client->irq);//disable irq \r
- if(((sensor->pdata->type == SENSOR_TYPE_TEMPERATURE) || (sensor->pdata->type == SENSOR_TYPE_PRESSURE))&& (!(sensor->ops->trig & IRQF_SHARED))) \r
- disable_irq_nosync(client->irq);//disable irq\r
- DBG("%s:use irq=%d\n",__func__,irq);\r
- }\r
- else if(!sensor->pdata->irq_enable)\r
- { \r
- INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
- if(sensor->pdata->poll_delay_ms < 0)\r
- sensor->pdata->poll_delay_ms = 30;\r
- \r
- DBG("%s:use polling,delay=%d ms\n",__func__,sensor->pdata->poll_delay_ms);\r
- }\r
-\r
-error: \r
- return result;\r
-}\r
-\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-static void sensor_suspend(struct early_suspend *h)\r
-{\r
- struct sensor_private_data *sensor = \r
- container_of(h, struct sensor_private_data, early_suspend);\r
- \r
- if(sensor->ops->suspend)\r
- sensor->ops->suspend(sensor->client);\r
-\r
-}\r
-\r
-static void sensor_resume(struct early_suspend *h)\r
-{\r
- struct sensor_private_data *sensor = \r
- container_of(h, struct sensor_private_data, early_suspend);\r
-\r
- if(sensor->ops->resume)\r
- sensor->ops->resume(sensor->client);\r
-}\r
-#endif\r
+
+
+/*
+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; i<SENSOR_NUM_TYPES; i++)
+ atomic_set(&g_sensor[i]->flags.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; i<SENSOR_NUM_TYPES; i++)
+ {
+ if(g_sensor[i])
+ atomic_set(&g_sensor[i]->flags.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)
#define SENSOR_PM_OPS NULL
#endif
-static int angle_dev_open(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; \r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int angle_dev_release(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE]; \r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-/* ioctl - I/O control */\r
-static long angle_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE];\r
- struct i2c_client *client = sensor->client;\r
- void __user *argp = (void __user *)arg;\r
- struct sensor_axis axis = {0};\r
- char rate;\r
- int result = 0;\r
-\r
- switch (cmd) {\r
- case GSENSOR_IOCTL_APP_SET_RATE:\r
- if (copy_from_user(&rate, argp, sizeof(rate)))\r
- {\r
- result = -EFAULT;\r
- goto error;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- switch (cmd) {\r
- case GSENSOR_IOCTL_START: \r
- DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(++sensor->start_count == 1)\r
- {\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- atomic_set(&(sensor->data_ready), 0);\r
- if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- } \r
- if(sensor->pdata->irq_enable)\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s:GSENSOR_IOCTL_START OK\n", __func__);\r
- break;\r
-\r
- case GSENSOR_IOCTL_CLOSE: \r
- DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(--sensor->start_count == 0)\r
- {\r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- atomic_set(&(sensor->data_ready), 0);\r
- if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex); \r
- goto error;\r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- { \r
- DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- disable_irq_nosync(client->irq);//disable irq\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- \r
- DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__);\r
- }\r
- \r
- mutex_unlock(&sensor->operation_mutex); \r
- break;\r
-\r
- case GSENSOR_IOCTL_APP_SET_RATE: \r
- DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__); \r
- mutex_lock(&sensor->operation_mutex); \r
- result = sensor_reset_rate(client, rate);\r
- if (result < 0){\r
- mutex_unlock(&sensor->operation_mutex);\r
- goto error;\r
- }\r
-\r
- sensor->status_cur = SENSOR_ON;\r
- mutex_unlock(&sensor->operation_mutex); \r
- DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__);\r
- break;\r
- \r
- case GSENSOR_IOCTL_GETDATA:\r
- mutex_lock(&sensor->data_mutex);\r
- memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer\r
- mutex_unlock(&sensor->data_mutex); \r
- break;\r
- default:\r
- result = -ENOTTY;\r
- goto error;\r
- }\r
-\r
- switch (cmd) {\r
- case GSENSOR_IOCTL_GETDATA:\r
- if ( copy_to_user(argp, &axis, sizeof(axis) ) ) {\r
- printk("failed to copy sense data to user space.");\r
- result = -EFAULT; \r
- goto error;\r
- } \r
- DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__);\r
- break;\r
- default:\r
- break;\r
- }\r
- \r
-error:\r
- return result;\r
-}\r
-\r
-\r
-static int gsensor_dev_open(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; \r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int gsensor_dev_release(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; \r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-/* ioctl - I/O control */\r
-static long gsensor_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];\r
- struct i2c_client *client = sensor->client;\r
- void __user *argp = (void __user *)arg;\r
- struct sensor_axis axis = {0};\r
- char rate;\r
- int result = 0;\r
-\r
- switch (cmd) {\r
- case GSENSOR_IOCTL_APP_SET_RATE:\r
- if (copy_from_user(&rate, argp, sizeof(rate)))\r
- {\r
- result = -EFAULT;\r
- goto error;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- switch (cmd) {\r
- case GSENSOR_IOCTL_START: \r
- DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(++sensor->start_count == 1)\r
- {\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- atomic_set(&(sensor->data_ready), 0);\r
- if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- } \r
- if(sensor->pdata->irq_enable)\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s:GSENSOR_IOCTL_START OK\n", __func__);\r
- break;\r
-\r
- case GSENSOR_IOCTL_CLOSE: \r
- DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(--sensor->start_count == 0)\r
- {\r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- atomic_set(&(sensor->data_ready), 0);\r
- if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex); \r
- goto error;\r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- { \r
- DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- disable_irq_nosync(client->irq);//disable irq\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- \r
- DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__);\r
- }\r
- \r
- mutex_unlock(&sensor->operation_mutex); \r
- break;\r
-\r
- case GSENSOR_IOCTL_APP_SET_RATE: \r
- DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__); \r
- mutex_lock(&sensor->operation_mutex); \r
- result = sensor_reset_rate(client, rate);\r
- if (result < 0){\r
- mutex_unlock(&sensor->operation_mutex);\r
- goto error;\r
- }\r
-\r
- sensor->status_cur = SENSOR_ON;\r
- mutex_unlock(&sensor->operation_mutex); \r
- DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__);\r
- break;\r
- \r
- case GSENSOR_IOCTL_GETDATA:\r
- mutex_lock(&sensor->data_mutex);\r
- memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer\r
- mutex_unlock(&sensor->data_mutex); \r
- break;\r
- default:\r
- result = -ENOTTY;\r
- goto error;\r
- }\r
-\r
- switch (cmd) {\r
- case GSENSOR_IOCTL_GETDATA:\r
- if ( copy_to_user(argp, &axis, sizeof(axis) ) ) {\r
- printk("failed to copy sense data to user space.");\r
- result = -EFAULT; \r
- goto error;\r
- } \r
- DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__);\r
- break;\r
- default:\r
- break;\r
- }\r
- \r
-error:\r
- return result;\r
-}\r
-\r
-static ssize_t gsensor_set_orientation_online(struct class *class,\r
- struct class_attribute *attr, const char *buf, size_t count)\r
-{\r
- int i=0;\r
- char orientation[20];\r
- char *tmp;\r
- \r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];\r
- struct sensor_platform_data *pdata = sensor->pdata;\r
-\r
- \r
- char *p = strstr(buf,"gsensor_class");\r
- int start = strcspn(p,"{");\r
- int end = strcspn(p,"}");\r
- \r
- strncpy(orientation,p+start,end-start+1);\r
- tmp = orientation;\r
- \r
-\r
- while(strncmp(tmp,"}",1)!=0)\r
- {\r
- if((strncmp(tmp,",",1)==0)||(strncmp(tmp,"{",1)==0))\r
- {\r
- \r
- tmp++; \r
- continue;\r
- } \r
- else if(strncmp(tmp,"-",1)==0)\r
- {\r
- pdata->orientation[i++]=-1;\r
- DBG("i=%d,data=%d\n",i,pdata->orientation[i]);\r
- tmp++;\r
- } \r
- else\r
- {\r
- pdata->orientation[i++]=tmp[0]-48; \r
- DBG("----i=%d,data=%d\n",i,pdata->orientation[i]); \r
- } \r
- tmp++;\r
- \r
- \r
- }\r
-\r
- for(i=0;i<9;i++)\r
- DBG("i=%d gsensor_info=%d\n",i,pdata->orientation[i]);\r
- return 0;\r
-\r
-}\r
-\r
-static CLASS_ATTR(orientation, 0660, NULL, gsensor_set_orientation_online);\r
-\r
-static int gsensor_class_init(void)\r
-{\r
- int ret ;\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; \r
- g_sensor_class[SENSOR_TYPE_ACCEL] = class_create(THIS_MODULE, "gsensor_class");\r
- ret = class_create_file(g_sensor_class[SENSOR_TYPE_ACCEL], &class_attr_orientation);\r
- if (ret)\r
- {\r
- printk("%s:Fail to creat class\n",__func__);\r
- return ret;\r
- }\r
- printk("%s:%s\n",__func__,sensor->i2c_id->name);\r
- return 0;\r
-}\r
-\r
-\r
-\r
-static int compass_dev_open(struct inode *inode, struct file *file)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
- //struct i2c_client *client = sensor->client; \r
-\r
- int result = 0;\r
- int flag = 0;\r
- flag = atomic_read(&sensor->flags.open_flag);\r
- if(!flag)\r
- { \r
- atomic_set(&sensor->flags.open_flag, 1);\r
- wake_up(&sensor->flags.open_wq);\r
- }\r
-\r
- DBG("%s\n", __func__);\r
- return result;\r
-}\r
-\r
-\r
-\r
-static int compass_dev_release(struct inode *inode, struct file *file)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
- //struct i2c_client *client = sensor->client;\r
- //void __user *argp = (void __user *)arg;\r
- int result = 0;\r
- int flag = 0;\r
- flag = atomic_read(&sensor->flags.open_flag);\r
- if(flag)\r
- {\r
- atomic_set(&sensor->flags.open_flag, 0);\r
- wake_up(&sensor->flags.open_wq); \r
- }\r
- \r
- DBG("%s\n", __func__);\r
- return result;\r
-}\r
-\r
-#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
-\r
-/* ioctl - I/O control */\r
-static long compass_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
- //struct i2c_client *client = sensor->client;\r
- void __user *argp = (void __user *)arg;\r
- int result = 0;\r
- short flag;\r
- \r
- switch (cmd) {\r
- case ECS_IOCTL_APP_SET_MFLAG:\r
- case ECS_IOCTL_APP_SET_AFLAG:\r
- case ECS_IOCTL_APP_SET_MVFLAG:\r
- if (copy_from_user(&flag, argp, sizeof(flag))) {\r
- return -EFAULT;\r
- }\r
- if (flag < 0 || flag > 1) {\r
- return -EINVAL;\r
- }\r
- break;\r
- case ECS_IOCTL_APP_SET_DELAY:\r
- if (copy_from_user(&flag, argp, sizeof(flag))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
- \r
- switch (cmd) {\r
- case ECS_IOCTL_APP_SET_MFLAG: \r
- atomic_set(&sensor->flags.m_flag, flag); \r
- DBG("%s:ECS_IOCTL_APP_SET_MFLAG,flag=%d\n", __func__,flag);\r
- break;\r
- case ECS_IOCTL_APP_GET_MFLAG: \r
- flag = atomic_read(&sensor->flags.m_flag);\r
- DBG("%s:ECS_IOCTL_APP_GET_MFLAG,flag=%d\n", __func__,flag);\r
- break;\r
- case ECS_IOCTL_APP_SET_AFLAG: \r
- atomic_set(&sensor->flags.a_flag, flag); \r
- DBG("%s:ECS_IOCTL_APP_SET_AFLAG,flag=%d\n", __func__,flag);\r
- break;\r
- case ECS_IOCTL_APP_GET_AFLAG:\r
- flag = atomic_read(&sensor->flags.a_flag); \r
- DBG("%s:ECS_IOCTL_APP_GET_AFLAG,flag=%d\n", __func__,flag);\r
- break;\r
- case ECS_IOCTL_APP_SET_MVFLAG: \r
- atomic_set(&sensor->flags.mv_flag, flag); \r
- DBG("%s:ECS_IOCTL_APP_SET_MVFLAG,flag=%d\n", __func__,flag);\r
- break;\r
- case ECS_IOCTL_APP_GET_MVFLAG: \r
- flag = atomic_read(&sensor->flags.mv_flag); \r
- DBG("%s:ECS_IOCTL_APP_GET_MVFLAG,flag=%d\n", __func__,flag);\r
- break;\r
- case ECS_IOCTL_APP_SET_DELAY:\r
- sensor->flags.delay = flag;\r
- break;\r
- case ECS_IOCTL_APP_GET_DELAY:\r
- flag = sensor->flags.delay;\r
- break;\r
- default:\r
- return -ENOTTY;\r
- }\r
- \r
- switch (cmd) {\r
- case ECS_IOCTL_APP_GET_MFLAG:\r
- case ECS_IOCTL_APP_GET_AFLAG:\r
- case ECS_IOCTL_APP_GET_MVFLAG:\r
- case ECS_IOCTL_APP_GET_DELAY:\r
- if (copy_to_user(argp, &flag, sizeof(flag))) {\r
- return -EFAULT;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-static int gyro_dev_open(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];\r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int gyro_dev_release(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];\r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long gyro_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE]; \r
- struct i2c_client *client = sensor->client; \r
- void __user *argp = (void __user *)arg;\r
- int result = 0;\r
- char rate;\r
- switch (cmd) {\r
- case L3G4200D_IOCTL_GET_ENABLE: \r
- result = !sensor->status_cur;\r
- if (copy_to_user(argp, &result, sizeof(result)))\r
- {\r
- printk("%s:failed to copy status to user space.\n",__FUNCTION__);\r
- return -EFAULT;\r
- }\r
- \r
- DBG("%s :L3G4200D_IOCTL_GET_ENABLE,status=%d\n",__FUNCTION__,result); \r
- break;\r
- case L3G4200D_IOCTL_SET_ENABLE: \r
- DBG("%s :L3G4200D_IOCTL_SET_ENABLE,flag=%d\n",__FUNCTION__,*(unsigned int *)argp);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(*(unsigned int *)argp)\r
- {\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if ( (result = sensor->ops->active(client, 1, ODR100_BW12_5) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- } \r
- if(sensor->pdata->irq_enable)\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- }\r
- else\r
- {\r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex); \r
- goto error;\r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- { \r
- DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- disable_irq_nosync(client->irq);//disable irq\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- }\r
- \r
- result = sensor->status_cur;\r
- if (copy_to_user(argp, &result, sizeof(result)))\r
- {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:failed to copy sense data to user space.\n",__FUNCTION__);\r
- return -EFAULT;\r
- }\r
-\r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s:L3G4200D_IOCTL_SET_ENABLE OK\n", __func__);\r
- break;\r
- case L3G4200D_IOCTL_SET_DELAY: \r
- if (copy_from_user(&rate, argp, sizeof(rate)))\r
- return -EFAULT;\r
- mutex_lock(&sensor->operation_mutex);\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if ( (result = sensor->ops->active(client, 1, rate) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- \r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s :L3G4200D_IOCTL_SET_DELAY,rate=%d\n",__FUNCTION__,rate);\r
- break;\r
-\r
- default:\r
- printk("%s:error,cmd=0x%x\n",__func__,cmd);\r
- return -ENOTTY;\r
- }\r
- \r
- DBG("%s:line=%d,cmd=0x%x\n",__func__,__LINE__,cmd);\r
-\r
-error:\r
- return result;\r
-}\r
-\r
-static int light_dev_open(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];\r
- //struct i2c_client *client = sensor->client; \r
- int result = 0; \r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-\r
-\r
-static int light_dev_release(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];\r
- //struct i2c_client *client = sensor->client; \r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-#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
-\r
-/* ioctl - I/O control */\r
-static long light_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];\r
- struct i2c_client *client = sensor->client;\r
- unsigned int *argp = (unsigned int *)arg; \r
- int result = 0;\r
-\r
- switch(cmd)\r
- {\r
- case LIGHTSENSOR_IOCTL_GET_ENABLED:\r
- *argp = sensor->status_cur;\r
- break;\r
- case LIGHTSENSOR_IOCTL_ENABLE: \r
- DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(*(unsigned int *)argp)\r
- {\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- } \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- }\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- \r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- }\r
- else\r
- {\r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex); \r
- goto error;\r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- { \r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- disable_irq_nosync(client->irq);//disable irq\r
- }\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__);\r
- break;\r
- \r
- default:\r
- break;\r
- }\r
- \r
-error:\r
- return result;\r
-}\r
-\r
-\r
-static int proximity_dev_open(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];\r
- //struct i2c_client *client = sensor->client; \r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int proximity_dev_release(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];\r
- //struct i2c_client *client = sensor->client; \r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-#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
-\r
-/* ioctl - I/O control */\r
-static long proximity_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];\r
- struct i2c_client *client = sensor->client; \r
- unsigned int *argp = (unsigned int *)arg; \r
- int result = 0;\r
- switch(cmd)\r
- {\r
- case PSENSOR_IOCTL_GET_ENABLED:\r
- *argp = sensor->status_cur;\r
- break;\r
- case PSENSOR_IOCTL_ENABLE: \r
- DBG("%s:PSENSOR_IOCTL_ENABLE start\n", __func__);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(*(unsigned int *)argp)\r
- {\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- }\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- \r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- }\r
- else\r
- {\r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex); \r
- goto error;\r
- }\r
- if(sensor->pdata->irq_enable)\r
- { \r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- disable_irq_nosync(client->irq);//disable irq\r
- }\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s:PSENSOR_IOCTL_ENABLE OK\n", __func__);\r
- break;\r
- \r
- default:\r
- break;\r
- }\r
- \r
-error:\r
- return result;\r
-}\r
-\r
-static int temperature_dev_open(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];\r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int temperature_dev_release(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];\r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long temperature_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];\r
- struct i2c_client *client = sensor->client;\r
- unsigned int *argp = (unsigned int *)arg; \r
- int result = 0;\r
-\r
- switch(cmd)\r
- {\r
- case TEMPERATURE_IOCTL_GET_ENABLED:\r
- *argp = sensor->status_cur;\r
- break;\r
- case TEMPERATURE_IOCTL_ENABLE: \r
- DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(*(unsigned int *)argp)\r
- {\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- } \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- }\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- \r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- }\r
- else\r
- {\r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex); \r
- goto error;\r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- { \r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- disable_irq_nosync(client->irq);//disable irq\r
- }\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__);\r
- break;\r
- \r
- default:\r
- break;\r
- }\r
- \r
-error:\r
- return result;\r
-}\r
-\r
-\r
-static int pressure_dev_open(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE];\r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-static int pressure_dev_release(struct inode *inode, struct file *file)\r
-{\r
- //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE];\r
- //struct i2c_client *client = sensor->client;\r
-\r
- int result = 0;\r
-\r
-\r
- return result;\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long pressure_dev_ioctl(struct file *file,\r
- unsigned int cmd, unsigned long arg)\r
-{\r
- struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE];\r
- struct i2c_client *client = sensor->client;\r
- unsigned int *argp = (unsigned int *)arg; \r
- int result = 0;\r
-\r
- switch(cmd)\r
- {\r
- case PRESSURE_IOCTL_GET_ENABLED:\r
- *argp = sensor->status_cur;\r
- break;\r
- case PRESSURE_IOCTL_ENABLE: \r
- DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);\r
- mutex_lock(&sensor->operation_mutex); \r
- if(*(unsigned int *)argp)\r
- {\r
- if(sensor->status_cur == SENSOR_OFF)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex);\r
- printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
- goto error; \r
- } \r
- if(sensor->pdata->irq_enable)\r
- {\r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- enable_irq(client->irq); //enable irq\r
- }\r
- } \r
- else\r
- {\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- \r
- sensor->status_cur = SENSOR_ON;\r
- } \r
- }\r
- else\r
- {\r
- if(sensor->status_cur == SENSOR_ON)\r
- {\r
- if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {\r
- mutex_unlock(&sensor->operation_mutex); \r
- goto error;\r
- }\r
- \r
- if(sensor->pdata->irq_enable)\r
- { \r
- if(!(sensor->ops->trig & IRQF_SHARED))\r
- {\r
- DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- disable_irq_nosync(client->irq);//disable irq\r
- }\r
- }\r
- else\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- }\r
- }\r
- mutex_unlock(&sensor->operation_mutex);\r
- DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__);\r
- break;\r
- \r
- default:\r
- break;\r
- }\r
- \r
-error:\r
- return result;\r
-}\r
-\r
-\r
-\r
-\r
-static int sensor_misc_device_register(struct sensor_private_data *sensor, int type)\r
-{\r
- int result = 0;\r
- \r
- switch(type)\r
- {\r
- case SENSOR_TYPE_ANGLE:\r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = angle_dev_ioctl;\r
- sensor->fops.open = angle_dev_open;\r
- sensor->fops.release = angle_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "angle";\r
- sensor->miscdev.fops = &sensor->fops;\r
- }\r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
- \r
- break;\r
- \r
- case SENSOR_TYPE_ACCEL:\r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = gsensor_dev_ioctl;\r
- #ifdef CONFIG_COMPAT\r
- sensor->fops.compat_ioctl = gsensor_dev_ioctl;\r
- #endif\r
- sensor->fops.open = gsensor_dev_open;\r
- sensor->fops.release = gsensor_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "mma8452_daemon";\r
- sensor->miscdev.fops = &sensor->fops;\r
- }\r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
- \r
- break;\r
-\r
- case SENSOR_TYPE_COMPASS: \r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = compass_dev_ioctl;\r
-#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;\r
- sensor->fops.release = compass_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "compass";\r
- sensor->miscdev.fops = &sensor->fops;\r
- }\r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
-\r
- break;\r
-\r
- case SENSOR_TYPE_GYROSCOPE: \r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = gyro_dev_ioctl;\r
- sensor->fops.open = gyro_dev_open;\r
- sensor->fops.release = gyro_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "gyrosensor";\r
- sensor->miscdev.fops = &sensor->fops;\r
- }\r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
- \r
- break;\r
-\r
- case SENSOR_TYPE_LIGHT:\r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = light_dev_ioctl;\r
+ 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;\r
- sensor->fops.release = light_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "lightsensor";\r
- sensor->miscdev.fops = &sensor->fops;\r
- } \r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
- break;\r
- \r
- case SENSOR_TYPE_PROXIMITY:\r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = proximity_dev_ioctl;\r
+ 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;\r
- sensor->fops.release = proximity_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "psensor";\r
- sensor->miscdev.fops = &sensor->fops;\r
- } \r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
- break;\r
-\r
- case SENSOR_TYPE_TEMPERATURE:\r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = temperature_dev_ioctl;\r
- sensor->fops.open = temperature_dev_open;\r
- sensor->fops.release = temperature_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "temperature";\r
- sensor->miscdev.fops = &sensor->fops;\r
- } \r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
- \r
- break;\r
-\r
- case SENSOR_TYPE_PRESSURE:\r
- if(!sensor->ops->misc_dev)\r
- {\r
- sensor->fops.owner = THIS_MODULE;\r
- sensor->fops.unlocked_ioctl = pressure_dev_ioctl;\r
- sensor->fops.open = pressure_dev_open;\r
- sensor->fops.release = pressure_dev_release;\r
-\r
- sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
- sensor->miscdev.name = "pressure";\r
- sensor->miscdev.fops = &sensor->fops;\r
- } \r
- else\r
- {\r
- memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
-\r
- }\r
- \r
- break;\r
-\r
- default:\r
- printk("%s:unknow sensor type=%d\n",__func__,type);\r
- result = -1;\r
- goto error;\r
- }\r
- \r
- sensor->miscdev.parent = &sensor->client->dev;\r
- result = misc_register(&sensor->miscdev);\r
- if (result < 0) {\r
- dev_err(&sensor->client->dev,\r
- "fail to register misc device %s\n", sensor->miscdev.name);\r
- goto error;\r
- }\r
- \r
- printk("%s:miscdevice: %s\n",__func__,sensor->miscdev.name);\r
-\r
-error: \r
- \r
- return result;\r
-\r
-}\r
-\r
-int sensor_register_slave(int type,struct i2c_client *client,\r
- struct sensor_platform_data *slave_pdata,\r
- struct sensor_operate *(*get_sensor_ops)(void))\r
-{\r
- int result = 0;\r
- struct sensor_operate *ops = get_sensor_ops();\r
- if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))\r
- { \r
- printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);\r
- return -1; \r
- }\r
- sensor_ops[ops->id_i2c] = ops;\r
- printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);\r
- return result;\r
-}\r
-\r
-\r
-int sensor_unregister_slave(int type,struct i2c_client *client,\r
- struct sensor_platform_data *slave_pdata,\r
- struct sensor_operate *(*get_sensor_ops)(void))\r
-{\r
- int result = 0;\r
- struct sensor_operate *ops = get_sensor_ops();\r
- if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))\r
- { \r
- printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);\r
- return -1; \r
- }\r
- printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);\r
- sensor_ops[ops->id_i2c] = NULL; \r
- return result;\r
-}\r
-\r
-\r
-int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client);\r
- struct sensor_platform_data *pdata;\r
- struct device_node *np = client->dev.of_node;\r
- enum of_gpio_flags rst_flags, pwr_flags;\r
- unsigned long irq_flags;\r
- int result = 0;\r
- int type = 0;\r
- \r
- dev_info(&client->adapter->dev, "%s: %s,%p\n", __func__, devid->name, client);\r
-\r
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {\r
- result = -ENODEV;\r
- goto out_no_free;\r
- }\r
- if (!np) {\r
- dev_err(&client->dev, "no device tree\n");\r
- return -EINVAL;\r
- }\r
- pdata = devm_kzalloc(&client->dev,sizeof(*pdata), GFP_KERNEL);\r
- if (!pdata) {\r
- result = -ENOMEM;\r
- goto out_no_free;\r
- }\r
- sensor = devm_kzalloc(&client->dev,sizeof(*sensor), GFP_KERNEL);\r
- if (!sensor) {\r
- result = -ENOMEM;\r
- goto out_no_free;\r
- }\r
- \r
- of_property_read_u32(np,"type",&(pdata->type));\r
-\r
- pdata->irq_pin = of_get_named_gpio_flags(np, "irq-gpio", 0,(enum of_gpio_flags *)&irq_flags);\r
- pdata->reset_pin = of_get_named_gpio_flags(np, "reset-gpio",0,&rst_flags);\r
- pdata->power_pin = of_get_named_gpio_flags(np, "power-gpio",0,&pwr_flags);\r
- \r
- of_property_read_u32(np,"irq_enable",&(pdata->irq_enable));\r
- of_property_read_u32(np,"poll_delay_ms",&(pdata->poll_delay_ms));\r
-\r
- of_property_read_u32(np,"x_min",&(pdata->x_min));\r
- of_property_read_u32(np,"y_min",&(pdata->y_min));\r
- of_property_read_u32(np,"z_min",&(pdata->z_min));\r
- of_property_read_u32(np,"factory",&(pdata->factory));\r
- of_property_read_u32(np,"layout",&(pdata->layout));\r
-\r
- of_property_read_u8(np,"address",&(pdata->address));\r
- of_get_property(np, "project_name", pdata->project_name);\r
+ 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);
-\r
- switch(pdata->layout)\r
- {\r
- case 1:\r
- pdata->orientation[0] = 1;\r
- pdata->orientation[1] = 0;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = 0;\r
- pdata->orientation[4] = 1;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = 1;\r
- break;\r
-\r
- case 2:\r
- pdata->orientation[0] = 0;\r
- pdata->orientation[1] = -1;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = 1;\r
- pdata->orientation[4] = 0;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = 1;\r
- break;\r
-\r
- case 3:\r
- pdata->orientation[0] = -1;\r
- pdata->orientation[1] = 0;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = 0;\r
- pdata->orientation[4] = -1;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = 1;\r
- break;\r
-\r
- case 4:\r
- pdata->orientation[0] = 0;\r
- pdata->orientation[1] = 1;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = -1;\r
- pdata->orientation[4] = 0;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = 1;\r
- break;\r
-\r
- case 5:\r
- pdata->orientation[0] = 1;\r
- pdata->orientation[1] = 0;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = 0;\r
- pdata->orientation[4] = -1;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = -1;\r
- break;\r
-\r
- case 6:\r
- pdata->orientation[0] = 0;\r
- pdata->orientation[1] = -1;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = -1;\r
- pdata->orientation[4] = 0;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = -1;\r
- break;\r
-\r
- case 7:\r
- pdata->orientation[0] = -1;\r
- pdata->orientation[1] = 0;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = 0;\r
- pdata->orientation[4] = 1;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = -1;\r
- break;\r
-\r
- case 8:\r
- pdata->orientation[0] = 0;\r
- pdata->orientation[1] = 1;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = 1;\r
- pdata->orientation[4] = 0;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = -1;\r
- break;\r
-\r
- default:\r
- pdata->orientation[0] = 1;\r
- pdata->orientation[1] = 0;\r
- pdata->orientation[2] = 0;\r
-\r
- pdata->orientation[3] = 0;\r
- pdata->orientation[4] = 1;\r
- pdata->orientation[5] = 0;\r
-\r
- pdata->orientation[6] = 0;\r
- pdata->orientation[7] = 0;\r
- pdata->orientation[8] = 1;\r
- break;\r
- }\r
-\r
- client->irq = pdata->irq_pin;\r
- type = pdata->type;\r
- pdata->irq_flags = irq_flags;\r
- DBG("irq_flags = %lu padta->irq_flags = %lu\n",irq_flags, pdata->irq_flags);\r
- DBG("type = %d \n",pdata->type);\r
- DBG("irq = %d \n",pdata->irq);\r
- DBG("irq_pin = %d \n",pdata->irq_pin);\r
- DBG("pwer_pin = %d \n",pdata->power_pin); \r
- DBG("reset_pin = %d \n",pdata->reset_pin);\r
- DBG("irq_enable = %d \n",pdata->irq_enable);\r
-\r
- DBG("poll_delay_ms = %d \n",pdata->poll_delay_ms);\r
- DBG("x_min = %d \n",pdata->x_min);\r
- DBG("y_min = %d \n",pdata->y_min);\r
- DBG("z_min = %d \n",pdata->z_min); \r
- DBG("factory = %d \n",pdata->factory);\r
- DBG("layout = %d \n",pdata->layout);\r
- DBG("address = 0x%x \n",pdata->address);\r
- DBG("project_name = [%s] \n",pdata->project_name);\r
- \r
- DBG(" == %d,%d ,%d \t ,%d ,%d ,%d , \t ,%d, %d, %d ,==%d\n",pdata->orientation[0],pdata->orientation[1],pdata->orientation[2]\r
- ,pdata->orientation[3],pdata->orientation[4],pdata->orientation[5]\r
- ,pdata->orientation[6],pdata->orientation[7],pdata->orientation[8],ARRAY_SIZE(pdata->orientation));\r
- \r
- \r
- if((type >= SENSOR_NUM_TYPES) || (type <= SENSOR_TYPE_NULL))\r
- { \r
- dev_err(&client->adapter->dev, "sensor type is error %d\n", type);\r
- result = -EFAULT;\r
- goto out_no_free; \r
- }\r
- if(((int)devid->driver_data >= SENSOR_NUM_ID) || ((int)devid->driver_data <= ID_INVALID))\r
- { \r
- dev_err(&client->adapter->dev, "sensor id is error %d\n", (int)devid->driver_data);\r
- result = -EFAULT;\r
- goto out_no_free; \r
- }\r
- i2c_set_clientdata(client, sensor);\r
- sensor->client = client; \r
- sensor->pdata = pdata; \r
- sensor->type = type;\r
- sensor->i2c_id = (struct i2c_device_id *)devid;\r
-\r
- \r
- memset(&(sensor->axis), 0, sizeof(struct sensor_axis) );\r
- atomic_set(&(sensor->data_ready), 0);\r
- init_waitqueue_head(&(sensor->data_ready_wq));\r
- mutex_init(&sensor->data_mutex); \r
- mutex_init(&sensor->operation_mutex); \r
- mutex_init(&sensor->sensor_mutex);\r
- mutex_init(&sensor->i2c_mutex);\r
-\r
- /* As default, report all information */\r
- atomic_set(&sensor->flags.m_flag, 1);\r
- atomic_set(&sensor->flags.a_flag, 1);\r
- atomic_set(&sensor->flags.mv_flag, 1); \r
- atomic_set(&sensor->flags.open_flag, 0);\r
- atomic_set(&sensor->flags.debug_flag, 1);\r
- init_waitqueue_head(&sensor->flags.open_wq);\r
- sensor->flags.delay = 100;\r
-\r
- sensor->status_cur = SENSOR_OFF;\r
- sensor->axis.x = 0;\r
- sensor->axis.y = 0;\r
- sensor->axis.z = 0;\r
- \r
- result = sensor_chip_init(sensor->client);\r
- if(result < 0)\r
- goto out_free_memory;\r
- \r
- sensor->input_dev = devm_input_allocate_device(&client->dev);\r
- if (!sensor->input_dev) {\r
- result = -ENOMEM;\r
- dev_err(&client->dev,\r
- "Failed to allocate input device\n");\r
- goto out_free_memory;\r
- } \r
-\r
- switch(type)\r
- {\r
- case SENSOR_TYPE_ANGLE: \r
- sensor->input_dev->name = "angle";\r
- set_bit(EV_ABS, sensor->input_dev->evbit);\r
- /* x-axis acceleration */\r
- input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
- /* y-axis acceleration */\r
- input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
- /* z-axis acceleration */\r
- input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
- break; \r
-\r
- case SENSOR_TYPE_ACCEL: \r
- sensor->input_dev->name = "gsensor";\r
- set_bit(EV_ABS, sensor->input_dev->evbit);\r
- /* x-axis acceleration */\r
- input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
- /* y-axis acceleration */\r
- input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
- /* z-axis acceleration */\r
- input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
- break; \r
- case SENSOR_TYPE_COMPASS: \r
- sensor->input_dev->name = "compass"; \r
- /* Setup input device */\r
- set_bit(EV_ABS, sensor->input_dev->evbit);\r
- /* yaw (0, 360) */\r
- input_set_abs_params(sensor->input_dev, ABS_RX, 0, 23040, 0, 0);\r
- /* pitch (-180, 180) */\r
- input_set_abs_params(sensor->input_dev, ABS_RY, -11520, 11520, 0, 0);\r
- /* roll (-90, 90) */\r
- input_set_abs_params(sensor->input_dev, ABS_RZ, -5760, 5760, 0, 0);\r
- /* x-axis acceleration (720 x 8G) */\r
- input_set_abs_params(sensor->input_dev, ABS_X, -5760, 5760, 0, 0);\r
- /* y-axis acceleration (720 x 8G) */\r
- input_set_abs_params(sensor->input_dev, ABS_Y, -5760, 5760, 0, 0);\r
- /* z-axis acceleration (720 x 8G) */\r
- input_set_abs_params(sensor->input_dev, ABS_Z, -5760, 5760, 0, 0);\r
- /* status of magnetic sensor */\r
- input_set_abs_params(sensor->input_dev, ABS_RUDDER, -32768, 3, 0, 0);\r
- /* status of acceleration sensor */\r
- input_set_abs_params(sensor->input_dev, ABS_WHEEL, -32768, 3, 0, 0);\r
- /* x-axis of raw magnetic vector (-4096, 4095) */\r
- input_set_abs_params(sensor->input_dev, ABS_HAT0X, -20480, 20479, 0, 0);\r
- /* y-axis of raw magnetic vector (-4096, 4095) */\r
- input_set_abs_params(sensor->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0);\r
- /* z-axis of raw magnetic vector (-4096, 4095) */\r
- input_set_abs_params(sensor->input_dev, ABS_BRAKE, -20480, 20479, 0, 0);\r
- break; \r
- case SENSOR_TYPE_GYROSCOPE:\r
- sensor->input_dev->name = "gyro";\r
- /* x-axis acceleration */\r
- input_set_capability(sensor->input_dev, EV_REL, REL_RX);\r
- input_set_abs_params(sensor->input_dev, ABS_RX, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
- /* y-axis acceleration */ \r
- input_set_capability(sensor->input_dev, EV_REL, REL_RY);\r
- input_set_abs_params(sensor->input_dev, ABS_RY, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
- /* z-axis acceleration */\r
- input_set_capability(sensor->input_dev, EV_REL, REL_RZ);\r
- input_set_abs_params(sensor->input_dev, ABS_RZ, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
- break;\r
- case SENSOR_TYPE_LIGHT:\r
- sensor->input_dev->name = "lightsensor-level";\r
- set_bit(EV_ABS, sensor->input_dev->evbit);\r
- input_set_abs_params(sensor->input_dev, ABS_MISC, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
- input_set_abs_params(sensor->input_dev, ABS_TOOL_WIDTH , sensor->ops->brightness[0],sensor->ops->brightness[1], 0, 0);\r
- break;\r
- case SENSOR_TYPE_PROXIMITY:\r
- sensor->input_dev->name = "proximity"; \r
- set_bit(EV_ABS, sensor->input_dev->evbit);\r
- input_set_abs_params(sensor->input_dev, ABS_DISTANCE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);\r
- break;\r
- case SENSOR_TYPE_TEMPERATURE: \r
- sensor->input_dev->name = "temperature";\r
- set_bit(EV_ABS, sensor->input_dev->evbit); \r
- input_set_abs_params(sensor->input_dev, ABS_THROTTLE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);\r
- break;\r
- case SENSOR_TYPE_PRESSURE: \r
- sensor->input_dev->name = "pressure";\r
- set_bit(EV_ABS, sensor->input_dev->evbit); \r
- input_set_abs_params(sensor->input_dev, ABS_PRESSURE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);\r
- break;\r
- default:\r
- printk("%s:unknow sensor type=%d\n",__func__,type);\r
- break;\r
-\r
- }\r
- sensor->input_dev->dev.parent = &client->dev;\r
-\r
- result = input_register_device(sensor->input_dev);\r
- if (result) {\r
- dev_err(&client->dev,\r
- "Unable to register input device %s\n", sensor->input_dev->name);\r
- goto out_input_register_device_failed;\r
- }\r
-\r
- result = sensor_irq_init(sensor->client);\r
- if (result) {\r
- dev_err(&client->dev,\r
- "fail to init sensor irq,ret=%d\n",result);\r
- goto out_input_register_device_failed;\r
- }\r
-\r
- \r
- sensor->miscdev.parent = &client->dev;\r
- result = sensor_misc_device_register(sensor, type);\r
- if (result) {\r
- dev_err(&client->dev,\r
- "fail to register misc device %s\n", sensor->miscdev.name);\r
- goto out_misc_device_register_device_failed;\r
- }\r
- \r
- g_sensor[type] = sensor;\r
-\r
- if((type == SENSOR_TYPE_ACCEL) && (sensor->pdata->factory)) //only support setting gsensor orientation online now \r
- {\r
- result = gsensor_class_init();\r
- if (result) {\r
- dev_err(&client->dev,\r
- "fail to register misc device %s\n", sensor->i2c_id->name);\r
- goto out_misc_device_register_device_failed;\r
- }\r
- } \r
- \r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
- if((sensor->ops->suspend) && (sensor->ops->resume))\r
- {\r
- sensor->early_suspend.suspend = sensor_suspend;\r
- sensor->early_suspend.resume = sensor_resume;\r
- sensor->early_suspend.level = 0x02;\r
- register_early_suspend(&sensor->early_suspend);\r
- }\r
-#endif\r
-\r
- printk("%s:initialized ok,sensor name:%s,type:%d,id=%d\n\n",__func__,sensor->ops->name,type,(int)sensor->i2c_id->driver_data);\r
-\r
- return result;\r
- \r
-out_misc_device_register_device_failed:\r
-out_input_register_device_failed:\r
-out_free_memory:\r
-out_no_free:\r
- dev_err(&client->adapter->dev, "%s failed %d\n\n", __func__, result);\r
- return result;\r
-\r
-}\r
-\r
-static void sensor_shut_down(struct i2c_client *client)\r
-{\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client);\r
- if((sensor->ops->suspend) && (sensor->ops->resume)) \r
- unregister_early_suspend(&sensor->early_suspend);\r
- DBG("%s:%s\n",__func__,sensor->i2c_id->name);\r
-#endif\r
-}\r
-\r
-static int sensor_remove(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client);\r
- int result = 0;\r
- \r
- cancel_delayed_work_sync(&sensor->delaywork);\r
- misc_deregister(&sensor->miscdev);\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
- if((sensor->ops->suspend) && (sensor->ops->resume))\r
- unregister_early_suspend(&sensor->early_suspend);\r
-#endif \r
- return result;\r
-}\r
-\r
-static const struct i2c_device_id sensor_id[] = {\r
- /*angle*/ \r
- {"angle_kxtik", ANGLE_ID_KXTIK},\r
- {"angle_lis3dh", ANGLE_ID_LIS3DH}, \r
- /*gsensor*/\r
- {"gsensor", ACCEL_ID_ALL},\r
- {"gs_mma8452", ACCEL_ID_MMA845X}, \r
- {"gs_kxtik", ACCEL_ID_KXTIK}, \r
- {"gs_kxtj9", ACCEL_ID_KXTJ9},\r
- {"gs_lis3dh", ACCEL_ID_LIS3DH},\r
- {"gs_mma7660", ACCEL_ID_MMA7660},\r
- {"gs_mxc6225", ACCEL_ID_MXC6225}, \r
- {"gs_dmard10", ACCEL_ID_DMARD10},\r
- {"gs_lsm303d", ACCEL_ID_LSM303D},\r
- {"gs_mc3230",ACCEL_ID_MC3230},\r
- {"mpu6880_acc",ACCEL_ID_MPU6880},\r
- {"mpu6500_acc",ACCEL_ID_MPU6500},\r
+
+ 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*/\r
- {"compass", COMPASS_ID_ALL},\r
- {"ak8975", COMPASS_ID_AK8975}, \r
- {"ak8963", COMPASS_ID_AK8963},\r
- {"ak09911", COMPASS_ID_AK09911},\r
- {"mmc314x", COMPASS_ID_MMC314X},\r
- /*gyroscope*/\r
- {"gyro", GYRO_ID_ALL}, \r
- {"l3g4200d_gyro", GYRO_ID_L3G4200D},\r
- {"l3g20d_gyro", GYRO_ID_L3G20D},\r
- {"ewtsa_gyro", GYRO_ID_EWTSA},\r
- {"k3g", GYRO_ID_K3G},\r
- {"mpu6880_gyro",GYRO_ID_MPU6880},\r
+ /*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*/\r
- {"lightsensor", LIGHT_ID_ALL}, \r
- {"light_cm3217", LIGHT_ID_CM3217},\r
- {"light_cm3218", LIGHT_ID_CM3218},\r
- {"light_cm3232", LIGHT_ID_CM3232},\r
- {"light_al3006", LIGHT_ID_AL3006},\r
- {"ls_stk3171", LIGHT_ID_STK3171},\r
- {"ls_isl29023", LIGHT_ID_ISL29023},\r
- {"ls_ap321xx", LIGHT_ID_AP321XX},\r
- {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR},\r
- {"ls_us5152", LIGHT_ID_US5152},\r
- /*proximity sensor*/\r
- {"psensor", PROXIMITY_ID_ALL},\r
- {"proximity_al3006", PROXIMITY_ID_AL3006}, \r
- {"ps_stk3171", PROXIMITY_ID_STK3171},\r
- {"ps_ap321xx", PROXIMITY_ID_AP321XX},\r
- \r
- /*temperature*/\r
- {"temperature", TEMPERATURE_ID_ALL}, \r
- {"tmp_ms5607", TEMPERATURE_ID_MS5607},\r
-\r
- /*pressure*/\r
- {"pressure", PRESSURE_ID_ALL},\r
- {"pr_ms5607", PRESSURE_ID_MS5607},\r
- \r
- {},\r
-};\r
-\r
-static struct of_device_id sensor_dt_ids[] = {\r
- /*gsensor*/\r
- { .compatible = "gs_mma8452" },\r
- { .compatible = "gs_lis3dh" },\r
- { .compatible = "gs_lsm303d" },\r
- { .compatible = "gs_mma7660" },\r
- { .compatible = "gs_mxc6225" },\r
- { .compatible = "gs_mc3230" },\r
+ /*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*/\r
- { .compatible = "ak8975" },\r
- { .compatible = "ak8963" },\r
- { .compatible = "ak09911" },\r
- { .compatible = "mmc314x" },\r
-\r
- /* gyroscop*/\r
- { .compatible = "l3g4200d_gyro" },\r
- { .compatible = "l3g20d_gyro" },\r
- { .compatible = "ewtsa_gyro" },\r
- { .compatible = "k3g" },\r
+ /*compass*/
+ { .compatible = "ak8975" },
+ { .compatible = "ak8963" },
+ { .compatible = "ak09911" },
+ { .compatible = "mmc314x" },
+
+ /* gyroscop*/
+ { .compatible = "l3g4200d_gyro" },
+ { .compatible = "l3g20d_gyro" },
+ { .compatible = "ewtsa_gyro" },
+ { .compatible = "k3g" },
{ .compatible = "lsm330_gyro" },
- \r
- /*light sensor*/\r
- { .compatible = "light_cm3217" },\r
- { .compatible = "light_cm3232" },\r
- { .compatible = "light_al3006" },\r
- { .compatible = "ls_stk3171" },\r
- { .compatible = "ls_ap321xx" },\r
-\r
- { .compatible = "ls_photoresistor" },\r
- { .compatible = "ls_us5152" },\r
-\r
- /*temperature sensor*/\r
- { .compatible = "tmp_ms5607" },\r
- \r
- /*pressure sensor*/\r
- { .compatible = "pr_ms5607" },\r
-\r
- /*hall sensor*/\r
- { .compatible = "hall_och165t" },\r
- { }\r
-};\r
-\r
-\r
-static struct i2c_driver sensor_driver = {\r
- .probe = sensor_probe,\r
- .remove = sensor_remove,\r
- .shutdown = sensor_shut_down,\r
- .id_table = sensor_id,\r
+
+ /*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,
- },\r
-};\r
-\r
-static int __init sensor_init(void)\r
-{\r
- int res = i2c_add_driver(&sensor_driver); \r
- struct proc_dir_entry *sensor_proc_entry; \r
- pr_info("%s: Probe name %s\n", __func__, sensor_driver.driver.name);\r
- if (res)\r
- pr_err("%s failed\n", __func__);\r
- \r
- sensor_proc_entry = proc_create("driver/sensor_dbg", 0660, NULL, &sensor_proc_fops); \r
- printk("%s\n", SENSOR_VERSION_AND_TIME);\r
- return res;\r
-}\r
-\r
-static void __exit sensor_exit(void)\r
-{\r
- pr_info("%s\n", __func__);\r
- i2c_del_driver(&sensor_driver);\r
-}\r
-\r
-late_initcall(sensor_init);\r
-module_exit(sensor_exit);\r
-\r
-MODULE_AUTHOR("ROCKCHIP Corporation:lw@rock-chips.com");\r
-MODULE_DESCRIPTION("User space character device interface for sensors");\r
-MODULE_LICENSE("GPL");\r
-\r
+ },
+};
+
+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");
+
-/* drivers/input/sensors/sensor-i2c.c - sensor i2c handle\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-#define SENSOR_I2C_RATE 200*1000\r
-\r
-\r
-static int sensor_i2c_write(struct i2c_adapter *i2c_adap,\r
- unsigned char address,\r
- unsigned int len, unsigned char const *data)\r
-{\r
- struct i2c_msg msgs[1];\r
- int res;\r
-\r
- if (!data || !i2c_adap) {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return -EINVAL;\r
- }\r
-\r
- msgs[0].addr = address;\r
- msgs[0].flags = 0; /* write */\r
- msgs[0].buf = (unsigned char *)data;\r
- msgs[0].len = len;\r
-\r
- res = i2c_transfer(i2c_adap, msgs, 1);\r
- if (res == 1)\r
- return 0;\r
- else if(res == 0)\r
- return -EBUSY;\r
- else\r
- return res;\r
-\r
-}\r
-\r
-static int senosr_i2c_read(struct i2c_adapter *i2c_adap,\r
- unsigned char address, unsigned char reg,\r
- unsigned int len, unsigned char *data)\r
-{\r
- struct i2c_msg msgs[2];\r
- int res;\r
-\r
- if (!data || !i2c_adap) {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return -EINVAL;\r
- }\r
-\r
- msgs[0].addr = address;\r
- msgs[0].flags = 0; /* write */\r
- msgs[0].buf = ®\r
- msgs[0].len = 1;\r
- \r
- msgs[1].addr = address;\r
- msgs[1].flags = I2C_M_RD;\r
- msgs[1].buf = data;\r
- msgs[1].len = len;\r
-\r
- res = i2c_transfer(i2c_adap, msgs, 2);\r
- if (res == 2)\r
- return 0;\r
- else if(res == 0)\r
- return -EBUSY;\r
- else\r
- return res;\r
-\r
-}\r
-\r
-\r
-int sensor_rx_data(struct i2c_client *client, char *rxData, int length)\r
-{\r
- //struct sensor_private_data* sensor = \r
- // (struct sensor_private_data *)i2c_get_clientdata(client);\r
- int i = 0;\r
- int ret = 0;\r
- char reg = rxData[0];\r
- ret = senosr_i2c_read(client->adapter, client->addr, reg, length, rxData);\r
- \r
- DBG("addr=0x%x,len=%d,rxdata:",reg,length);\r
- for(i=0; i<length; i++)\r
- DBG("0x%x,",rxData[i]);\r
- DBG("\n");\r
- return ret;\r
-}\r
-EXPORT_SYMBOL(sensor_rx_data);\r
-\r
-int sensor_tx_data(struct i2c_client *client, char *txData, int length)\r
-{\r
- //struct sensor_private_data* sensor = \r
- //(struct sensor_private_data *)i2c_get_clientdata(client);\r
- int i = 0;\r
- int ret = 0;\r
-\r
- DBG("addr=0x%x,len=%d,txdata:",txData[0],length);\r
- for(i=1; i<length; i++)\r
- DBG("0x%x,",txData[i]);\r
- DBG("\n");\r
- ret = sensor_i2c_write(client->adapter, client->addr, length, txData);\r
- return ret;\r
-\r
-}\r
-EXPORT_SYMBOL(sensor_tx_data);\r
-\r
-int sensor_write_reg(struct i2c_client *client, int addr, int value)\r
-{\r
- char buffer[2];\r
- int ret = 0;\r
- struct sensor_private_data* sensor = \r
- (struct sensor_private_data *)i2c_get_clientdata(client);\r
- \r
- mutex_lock(&sensor->i2c_mutex); \r
- buffer[0] = addr;\r
- buffer[1] = value;\r
- ret = sensor_tx_data(client, &buffer[0], 2); \r
- mutex_unlock(&sensor->i2c_mutex); \r
- return ret;\r
-}\r
-EXPORT_SYMBOL(sensor_write_reg);\r
-\r
-int sensor_read_reg(struct i2c_client *client, int addr)\r
-{\r
- char tmp[1] = {0};\r
- int ret = 0; \r
- struct sensor_private_data* sensor = \r
- (struct sensor_private_data *)i2c_get_clientdata(client);\r
- \r
- mutex_lock(&sensor->i2c_mutex); \r
- tmp[0] = addr;\r
- ret = sensor_rx_data(client, tmp, 1);\r
- mutex_unlock(&sensor->i2c_mutex);\r
- \r
- return tmp[0];\r
-}\r
-\r
-EXPORT_SYMBOL(sensor_read_reg);\r
-\r
-static int i2c_master_normal_recv(const struct i2c_client *client, char *buf, int count, int scl_rate)\r
- {\r
- struct i2c_adapter *adap=client->adapter;\r
- struct i2c_msg msg;\r
- int ret;\r
- \r
- msg.addr = client->addr;\r
- msg.flags = client->flags | I2C_M_RD;\r
- msg.len = count;\r
- msg.buf = (char *)buf;\r
- ret = i2c_transfer(adap, &msg, 1);\r
-\r
- return (ret == 1) ? count : ret;\r
-}\r
-\r
-static int i2c_master_normal_send(const struct i2c_client *client, const char *buf, int count, int scl_rate)\r
-{\r
- int ret;\r
- struct i2c_adapter *adap=client->adapter;\r
- struct i2c_msg msg; \r
-\r
- msg.addr = client->addr;\r
- msg.flags = client->flags;\r
- msg.len = count;\r
- msg.buf = (char *)buf;\r
-\r
- ret = i2c_transfer(adap, &msg, 1);\r
- return (ret == 1) ? count : ret;\r
-}\r
-\r
-int sensor_tx_data_normal(struct i2c_client *client, char *buf, int num)\r
-{\r
- int ret = 0;\r
- ret = i2c_master_normal_send(client, buf, num, SENSOR_I2C_RATE);\r
- \r
- return (ret == num) ? 0 : ret;\r
-}\r
-EXPORT_SYMBOL(sensor_tx_data_normal);\r
-\r
-\r
-int sensor_rx_data_normal(struct i2c_client *client, char *buf, int num)\r
-{\r
- int ret = 0;\r
- ret = i2c_master_normal_recv(client, buf, num, SENSOR_I2C_RATE);\r
- \r
- return (ret == num) ? 0 : ret;\r
-}\r
-\r
-EXPORT_SYMBOL(sensor_rx_data_normal);\r
-\r
-\r
-int sensor_write_reg_normal(struct i2c_client *client, char value)\r
-{\r
- char buffer[2];\r
- int ret = 0;\r
- struct sensor_private_data* sensor = \r
- (struct sensor_private_data *)i2c_get_clientdata(client);\r
- \r
- mutex_lock(&sensor->i2c_mutex); \r
- buffer[0] = value;\r
- ret = sensor_tx_data_normal(client, &buffer[0], 1); \r
- mutex_unlock(&sensor->i2c_mutex); \r
- return ret;\r
-}\r
-EXPORT_SYMBOL(sensor_write_reg_normal);\r
-\r
-int sensor_read_reg_normal(struct i2c_client *client)\r
-{\r
- char tmp[1] = {0};\r
- int ret = 0; \r
- struct sensor_private_data* sensor = \r
- (struct sensor_private_data *)i2c_get_clientdata(client);\r
- \r
- mutex_lock(&sensor->i2c_mutex); \r
- ret = sensor_rx_data_normal(client, tmp, 1);\r
- mutex_unlock(&sensor->i2c_mutex);\r
- \r
- return tmp[0];\r
-}\r
-\r
-EXPORT_SYMBOL(sensor_read_reg_normal);\r
-\r
+/* drivers/input/sensors/sensor-i2c.c - sensor i2c handle
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+#define SENSOR_I2C_RATE 200*1000
+
+
+static int sensor_i2c_write(struct i2c_adapter *i2c_adap,
+ unsigned char address,
+ unsigned int len, unsigned char const *data)
+{
+ struct i2c_msg msgs[1];
+ int res;
+
+ if (!data || !i2c_adap) {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return -EINVAL;
+ }
+
+ msgs[0].addr = address;
+ msgs[0].flags = 0; /* write */
+ msgs[0].buf = (unsigned char *)data;
+ msgs[0].len = len;
+
+ res = i2c_transfer(i2c_adap, msgs, 1);
+ if (res == 1)
+ return 0;
+ else if(res == 0)
+ return -EBUSY;
+ else
+ return res;
+
+}
+
+static int senosr_i2c_read(struct i2c_adapter *i2c_adap,
+ unsigned char address, unsigned char reg,
+ unsigned int len, unsigned char *data)
+{
+ struct i2c_msg msgs[2];
+ int res;
+
+ if (!data || !i2c_adap) {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return -EINVAL;
+ }
+
+ msgs[0].addr = address;
+ msgs[0].flags = 0; /* write */
+ msgs[0].buf = ®
+ msgs[0].len = 1;
+
+ msgs[1].addr = address;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].buf = data;
+ msgs[1].len = len;
+
+ res = i2c_transfer(i2c_adap, msgs, 2);
+ if (res == 2)
+ return 0;
+ else if(res == 0)
+ return -EBUSY;
+ else
+ return res;
+
+}
+
+
+int sensor_rx_data(struct i2c_client *client, char *rxData, int length)
+{
+ //struct sensor_private_data* sensor =
+ // (struct sensor_private_data *)i2c_get_clientdata(client);
+ int i = 0;
+ int ret = 0;
+ char reg = rxData[0];
+ ret = senosr_i2c_read(client->adapter, client->addr, reg, length, rxData);
+
+ DBG("addr=0x%x,len=%d,rxdata:",reg,length);
+ for(i=0; i<length; i++)
+ DBG("0x%x,",rxData[i]);
+ DBG("\n");
+ return ret;
+}
+EXPORT_SYMBOL(sensor_rx_data);
+
+int sensor_tx_data(struct i2c_client *client, char *txData, int length)
+{
+ //struct sensor_private_data* sensor =
+ //(struct sensor_private_data *)i2c_get_clientdata(client);
+ int i = 0;
+ int ret = 0;
+
+ DBG("addr=0x%x,len=%d,txdata:",txData[0],length);
+ for(i=1; i<length; i++)
+ DBG("0x%x,",txData[i]);
+ DBG("\n");
+ ret = sensor_i2c_write(client->adapter, client->addr, length, txData);
+ return ret;
+
+}
+EXPORT_SYMBOL(sensor_tx_data);
+
+int sensor_write_reg(struct i2c_client *client, int addr, int value)
+{
+ char buffer[2];
+ int ret = 0;
+ struct sensor_private_data* sensor =
+ (struct sensor_private_data *)i2c_get_clientdata(client);
+
+ mutex_lock(&sensor->i2c_mutex);
+ buffer[0] = addr;
+ buffer[1] = value;
+ ret = sensor_tx_data(client, &buffer[0], 2);
+ mutex_unlock(&sensor->i2c_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(sensor_write_reg);
+
+int sensor_read_reg(struct i2c_client *client, int addr)
+{
+ char tmp[1] = {0};
+ int ret = 0;
+ struct sensor_private_data* sensor =
+ (struct sensor_private_data *)i2c_get_clientdata(client);
+
+ mutex_lock(&sensor->i2c_mutex);
+ tmp[0] = addr;
+ ret = sensor_rx_data(client, tmp, 1);
+ mutex_unlock(&sensor->i2c_mutex);
+
+ return tmp[0];
+}
+
+EXPORT_SYMBOL(sensor_read_reg);
+
+static int i2c_master_normal_recv(const struct i2c_client *client, char *buf, int count, int scl_rate)
+ {
+ struct i2c_adapter *adap=client->adapter;
+ struct i2c_msg msg;
+ int ret;
+
+ msg.addr = client->addr;
+ msg.flags = client->flags | I2C_M_RD;
+ msg.len = count;
+ msg.buf = (char *)buf;
+ ret = i2c_transfer(adap, &msg, 1);
+
+ return (ret == 1) ? count : ret;
+}
+
+static int i2c_master_normal_send(const struct i2c_client *client, const char *buf, int count, int scl_rate)
+{
+ int ret;
+ struct i2c_adapter *adap=client->adapter;
+ struct i2c_msg msg;
+
+ msg.addr = client->addr;
+ msg.flags = client->flags;
+ msg.len = count;
+ msg.buf = (char *)buf;
+
+ ret = i2c_transfer(adap, &msg, 1);
+ return (ret == 1) ? count : ret;
+}
+
+int sensor_tx_data_normal(struct i2c_client *client, char *buf, int num)
+{
+ int ret = 0;
+ ret = i2c_master_normal_send(client, buf, num, SENSOR_I2C_RATE);
+
+ return (ret == num) ? 0 : ret;
+}
+EXPORT_SYMBOL(sensor_tx_data_normal);
+
+
+int sensor_rx_data_normal(struct i2c_client *client, char *buf, int num)
+{
+ int ret = 0;
+ ret = i2c_master_normal_recv(client, buf, num, SENSOR_I2C_RATE);
+
+ return (ret == num) ? 0 : ret;
+}
+
+EXPORT_SYMBOL(sensor_rx_data_normal);
+
+
+int sensor_write_reg_normal(struct i2c_client *client, char value)
+{
+ char buffer[2];
+ int ret = 0;
+ struct sensor_private_data* sensor =
+ (struct sensor_private_data *)i2c_get_clientdata(client);
+
+ mutex_lock(&sensor->i2c_mutex);
+ buffer[0] = value;
+ ret = sensor_tx_data_normal(client, &buffer[0], 1);
+ mutex_unlock(&sensor->i2c_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(sensor_write_reg_normal);
+
+int sensor_read_reg_normal(struct i2c_client *client)
+{
+ char tmp[1] = {0};
+ int ret = 0;
+ struct sensor_private_data* sensor =
+ (struct sensor_private_data *)i2c_get_clientdata(client);
+
+ mutex_lock(&sensor->i2c_mutex);
+ ret = sensor_rx_data_normal(client, tmp, 1);
+ mutex_unlock(&sensor->i2c_mutex);
+
+ return tmp[0];
+}
+
+EXPORT_SYMBOL(sensor_read_reg_normal);
+
-/* drivers/input/sensors/temperature/tmp_ms5607.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define CMD_RESET 0x1E // ADC reset command \r
-#define CMD_ADC_READ 0x00 // ADC read command \r
-#define CMD_ADC_CONV 0x40 // ADC conversion command \r
-#define CMD_ADC_D1 0x00 // ADC D1 conversion \r
-#define CMD_ADC_D2 0x10 // ADC D2 conversion \r
-#define CMD_ADC_256 0x00 // ADC OSR=256 \r
-#define CMD_ADC_512 0x02 // ADC OSR=512 \r
-#define CMD_ADC_1024 0x04 // ADC OSR=1024 \r
-#define CMD_ADC_2048 0x06 // ADC OSR=2048 \r
-#define CMD_ADC_4096 0x08 // ADC OSR=4096 \r
-#define CMD_PROM_RD 0xA0 // Prom read command \r
-\r
-#if defined(CONFIG_PR_MS5607)\r
-extern int g_ms5607_temp;\r
-extern int g_ms5607_pr_status;\r
-#else\r
-static int g_ms5607_temp = 0;\r
-static int g_ms5607_pr_status = SENSOR_OFF;\r
-#endif\r
-\r
-int g_ms5607_temp_status;\r
-static int C[8] = {0};\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
- int result = 0;\r
- int i = 0;\r
- char prom[16];\r
- \r
- if((enable)&&(g_ms5607_pr_status == SENSOR_OFF))\r
- {\r
- result = sensor_write_reg_normal(client, CMD_RESET);\r
- if(result) \r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
-\r
- //Read PROM (128 bit of calibration words) \r
- memset(prom, 0, 16);\r
- prom[0]= CMD_PROM_RD;//CMD_PROM_RD; \r
- for(i=0; i<8; i++)\r
- {\r
- prom[i*2]= CMD_PROM_RD + i*2;\r
- result = sensor_rx_data(client, &prom[i*2], 2);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- }\r
-\r
- for (i=0;i<8;i++) \r
- {\r
- C[i] = prom[2*i] << 8 | prom[2*i + 1];\r
- //printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);\r
- //printk("\nC[%d]=%d,",i+1,C[i]);\r
- } \r
-\r
- }\r
-\r
- g_ms5607_temp_status = enable;\r
- \r
- return result;\r
-}\r
-\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{ \r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- int result = 0;\r
- \r
- result = sensor->ops->active(client,0,0);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
- \r
- sensor->status_cur = SENSOR_OFF;\r
- g_ms5607_temp_status = sensor->status_cur;\r
- //Reset\r
- //result = sensor_write_reg_normal(client, CMD_RESET);\r
- //if(result) \r
- //printk("%s:line=%d,error\n",__func__,__LINE__); \r
- \r
- return result;\r
-}\r
-\r
-\r
-\r
-static int temperature_report_value(struct input_dev *input, int data)\r
-{\r
- //get temperature, high and temperature from register data\r
-\r
- input_report_abs(input, ABS_THROTTLE, data);\r
- input_sync(input);\r
- \r
- return 0;\r
-}\r
-\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
- struct sensor_private_data *sensor =\r
- (struct sensor_private_data *) i2c_get_clientdata(client); \r
- \r
- int result = 0;\r
- char buffer[3]; \r
- char index = 0;\r
- unsigned int D1=0, D2=0;\r
-\r
- int T2 = 0;\r
- long long OFF = 0; // offset at actual temperature \r
- long long SENS = 0; // sensitivity at actual temperature \r
- int dT = 0; // difference between actual and measured temperature\r
- long long OFF2 = 0;\r
- long long SENS2 = 0;\r
- int P = 0; // compensated pressure value \r
-\r
-\r
- memset(buffer, 0, 3);\r
- if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3\r
- {\r
- printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
- return -1;\r
- }\r
-\r
- if(g_ms5607_pr_status == SENSOR_OFF)\r
- {\r
-\r
- //D1 conversion\r
- sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);\r
- msleep(10);\r
-\r
- memset(buffer, 0, 3);\r
- buffer[0] = CMD_ADC_READ;\r
- result = sensor_rx_data(client, &buffer[0], 3);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];\r
- DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);\r
-\r
- //D2 conversion\r
- sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);\r
- msleep(10);\r
-\r
- memset(buffer, 0, 3);\r
- buffer[0] = CMD_ADC_READ;\r
- result = sensor_rx_data(client, &buffer[0], 3);\r
- if(result)\r
- {\r
- printk("%s:line=%d,error\n",__func__,__LINE__);\r
- return result;\r
- }\r
-\r
- D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];\r
- DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);\r
-\r
- dT = D2 - ((unsigned int)C[5] << 8);\r
-\r
- g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));\r
-\r
- OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);\r
-\r
- SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);\r
-\r
- /*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/\r
- if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)\r
- {\r
- printk("%s:temperature is error\n",__func__);\r
- return -1;\r
- }\r
-\r
- if (g_ms5607_temp < 2000)\r
- {\r
- int tmp;\r
- tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);\r
-\r
- T2 = (int)((long long)(dT * dT) >> 31);\r
- OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;\r
- SENS2 = (long long)((tmp*tmp) << 1);\r
-\r
- if (g_ms5607_temp < -1500)\r
- {\r
- tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);\r
- OFF2 += 15 * tmp;\r
- SENS2 += 8 * tmp;\r
- }\r
- }\r
- else\r
- {\r
- T2=0;\r
- OFF2 = 0;\r
- SENS2 = 0;\r
- }\r
-\r
- g_ms5607_temp -= T2;\r
- OFF -= OFF2;\r
- SENS -= SENS2; \r
- P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);\r
-\r
- index = temperature_report_value(sensor->input_dev, g_ms5607_temp);\r
- \r
- DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);\r
- \r
- }\r
- else\r
- { \r
- index = temperature_report_value(sensor->input_dev, g_ms5607_temp);\r
- \r
- #if defined(CONFIG_PR_MS5607)\r
- DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);\r
- #else \r
- printk("%s:errror,need pr_ms5607\n",__func__);\r
- #endif\r
- }\r
- \r
- \r
- return result;\r
-}\r
-\r
-\r
-struct sensor_operate temperature_ms5607_ops = {\r
- .name = "tmp_ms5607",\r
- .type = SENSOR_TYPE_TEMPERATURE, //sensor type and it should be correct\r
- .id_i2c = TEMPERATURE_ID_MS5607, //i2c id number\r
- .read_reg = SENSOR_UNKNOW_DATA, //read data\r
- .read_len = 3, //data length\r
- .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register\r
- .id_data = SENSOR_UNKNOW_DATA, //device id\r
- .precision = 24, //8 bits\r
- .ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable \r
- .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
- .range = {100,65535}, //range\r
- .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, \r
- .active = sensor_active, \r
- .init = sensor_init,\r
- .report = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *temperature_get_ops(void)\r
-{\r
- return &temperature_ms5607_ops;\r
-}\r
-\r
-\r
-static int __init temperature_ms5607_init(void)\r
-{\r
- struct sensor_operate *ops = temperature_get_ops();\r
- int result = 0;\r
- int type = ops->type;\r
- result = sensor_register_slave(type, NULL, NULL, temperature_get_ops);\r
- return result;\r
-}\r
-\r
-static void __exit temperature_ms5607_exit(void)\r
-{\r
- struct sensor_operate *ops = temperature_get_ops();\r
- int type = ops->type;\r
- sensor_unregister_slave(type, NULL, NULL, temperature_get_ops);\r
-}\r
-\r
-\r
-module_init(temperature_ms5607_init);\r
-module_exit(temperature_ms5607_exit);\r
-\r
+/* drivers/input/sensors/temperature/tmp_ms5607.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define CMD_RESET 0x1E // ADC reset command
+#define CMD_ADC_READ 0x00 // ADC read command
+#define CMD_ADC_CONV 0x40 // ADC conversion command
+#define CMD_ADC_D1 0x00 // ADC D1 conversion
+#define CMD_ADC_D2 0x10 // ADC D2 conversion
+#define CMD_ADC_256 0x00 // ADC OSR=256
+#define CMD_ADC_512 0x02 // ADC OSR=512
+#define CMD_ADC_1024 0x04 // ADC OSR=1024
+#define CMD_ADC_2048 0x06 // ADC OSR=2048
+#define CMD_ADC_4096 0x08 // ADC OSR=4096
+#define CMD_PROM_RD 0xA0 // Prom read command
+
+#if defined(CONFIG_PR_MS5607)
+extern int g_ms5607_temp;
+extern int g_ms5607_pr_status;
+#else
+static int g_ms5607_temp = 0;
+static int g_ms5607_pr_status = SENSOR_OFF;
+#endif
+
+int g_ms5607_temp_status;
+static int C[8] = {0};
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+ int result = 0;
+ int i = 0;
+ char prom[16];
+
+ if((enable)&&(g_ms5607_pr_status == SENSOR_OFF))
+ {
+ result = sensor_write_reg_normal(client, CMD_RESET);
+ if(result)
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+
+ //Read PROM (128 bit of calibration words)
+ memset(prom, 0, 16);
+ prom[0]= CMD_PROM_RD;//CMD_PROM_RD;
+ for(i=0; i<8; i++)
+ {
+ prom[i*2]= CMD_PROM_RD + i*2;
+ result = sensor_rx_data(client, &prom[i*2], 2);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+ }
+
+ for (i=0;i<8;i++)
+ {
+ C[i] = prom[2*i] << 8 | prom[2*i + 1];
+ //printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
+ //printk("\nC[%d]=%d,",i+1,C[i]);
+ }
+
+ }
+
+ g_ms5607_temp_status = enable;
+
+ return result;
+}
+
+
+
+static int sensor_init(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+ int result = 0;
+
+ result = sensor->ops->active(client,0,0);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ sensor->status_cur = SENSOR_OFF;
+ g_ms5607_temp_status = sensor->status_cur;
+ //Reset
+ //result = sensor_write_reg_normal(client, CMD_RESET);
+ //if(result)
+ //printk("%s:line=%d,error\n",__func__,__LINE__);
+
+ return result;
+}
+
+
+
+static int temperature_report_value(struct input_dev *input, int data)
+{
+ //get temperature, high and temperature from register data
+
+ input_report_abs(input, ABS_THROTTLE, data);
+ input_sync(input);
+
+ return 0;
+}
+
+
+static int sensor_report_value(struct i2c_client *client)
+{
+ struct sensor_private_data *sensor =
+ (struct sensor_private_data *) i2c_get_clientdata(client);
+
+ int result = 0;
+ char buffer[3];
+ char index = 0;
+ unsigned int D1=0, D2=0;
+
+ int T2 = 0;
+ long long OFF = 0; // offset at actual temperature
+ long long SENS = 0; // sensitivity at actual temperature
+ int dT = 0; // difference between actual and measured temperature
+ long long OFF2 = 0;
+ long long SENS2 = 0;
+ int P = 0; // compensated pressure value
+
+
+ memset(buffer, 0, 3);
+ if(sensor->ops->read_len < 3) //sensor->ops->read_len = 3
+ {
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+ return -1;
+ }
+
+ if(g_ms5607_pr_status == SENSOR_OFF)
+ {
+
+ //D1 conversion
+ sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);
+ msleep(10);
+
+ memset(buffer, 0, 3);
+ buffer[0] = CMD_ADC_READ;
+ result = sensor_rx_data(client, &buffer[0], 3);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+ DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);
+
+ //D2 conversion
+ sensor_write_reg_normal(client, CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);
+ msleep(10);
+
+ memset(buffer, 0, 3);
+ buffer[0] = CMD_ADC_READ;
+ result = sensor_rx_data(client, &buffer[0], 3);
+ if(result)
+ {
+ printk("%s:line=%d,error\n",__func__,__LINE__);
+ return result;
+ }
+
+ D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+ DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);
+
+ dT = D2 - ((unsigned int)C[5] << 8);
+
+ g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));
+
+ OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);
+
+ SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);
+
+ /*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/
+ if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)
+ {
+ printk("%s:temperature is error\n",__func__);
+ return -1;
+ }
+
+ if (g_ms5607_temp < 2000)
+ {
+ int tmp;
+ tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);
+
+ T2 = (int)((long long)(dT * dT) >> 31);
+ OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;
+ SENS2 = (long long)((tmp*tmp) << 1);
+
+ if (g_ms5607_temp < -1500)
+ {
+ tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);
+ OFF2 += 15 * tmp;
+ SENS2 += 8 * tmp;
+ }
+ }
+ else
+ {
+ T2=0;
+ OFF2 = 0;
+ SENS2 = 0;
+ }
+
+ g_ms5607_temp -= T2;
+ OFF -= OFF2;
+ SENS -= SENS2;
+ P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);
+
+ index = temperature_report_value(sensor->input_dev, g_ms5607_temp);
+
+ DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
+
+ }
+ else
+ {
+ index = temperature_report_value(sensor->input_dev, g_ms5607_temp);
+
+ #if defined(CONFIG_PR_MS5607)
+ DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);
+ #else
+ printk("%s:errror,need pr_ms5607\n",__func__);
+ #endif
+ }
+
+
+ return result;
+}
+
+
+struct sensor_operate temperature_ms5607_ops = {
+ .name = "tmp_ms5607",
+ .type = SENSOR_TYPE_TEMPERATURE, //sensor type and it should be correct
+ .id_i2c = TEMPERATURE_ID_MS5607, //i2c id number
+ .read_reg = SENSOR_UNKNOW_DATA, //read data
+ .read_len = 3, //data length
+ .id_reg = SENSOR_UNKNOW_DATA, //read device id from this register
+ .id_data = SENSOR_UNKNOW_DATA, //device id
+ .precision = 24, //8 bits
+ .ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable
+ .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
+ .range = {100,65535}, //range
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
+ .active = sensor_active,
+ .init = sensor_init,
+ .report = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *temperature_get_ops(void)
+{
+ return &temperature_ms5607_ops;
+}
+
+
+static int __init temperature_ms5607_init(void)
+{
+ struct sensor_operate *ops = temperature_get_ops();
+ int result = 0;
+ int type = ops->type;
+ result = sensor_register_slave(type, NULL, NULL, temperature_get_ops);
+ return result;
+}
+
+static void __exit temperature_ms5607_exit(void)
+{
+ struct sensor_operate *ops = temperature_get_ops();
+ int type = ops->type;
+ sensor_unregister_slave(type, NULL, NULL, temperature_get_ops);
+}
+
+
+module_init(temperature_ms5607_init);
+module_exit(temperature_ms5607_exit);
+
ANGLE_ID_ALL,
ANGLE_ID_KXTIK,
ANGLE_ID_LIS3DH,
-
+
ACCEL_ID_ALL,
ACCEL_ID_LIS331,
ACCEL_ID_LSM303DLX,
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,
HALL_ID_ALL,
HALL_ID_OCH165T,
-
+
SENSOR_NUM_ID,
};
};
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;
};
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;
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);
/* 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;
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
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;
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];
#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