sensors:add sensor debug support

This commit is contained in:
luowei
2013-04-01 16:15:12 +08:00
parent 8ee4d5753d
commit 44f4717e0d
35 changed files with 1953 additions and 244 deletions
+1
View File
@@ -210,6 +210,7 @@ struct sensor_platform_data {
int y_min;
int z_min;
int factory;
int layout;
unsigned char address;
signed char orientation[9];
short m_layout[4][3][3];
+6
View File
@@ -21,6 +21,12 @@ config GS_KXTIK
To have support for your specific gsesnor you will have to
select the proper drivers which depend on this option.
config GS_KXTJ9
bool "gsensor kxtj9"
help
To have support for your specific gsesnor you will have to
select the proper drivers which depend on this option.
config GS_LIS3DH
bool "gsensor lis3dh"
help
+1
View File
@@ -1,4 +1,5 @@
obj-$(CONFIG_GS_KXTIK) += kxtik.o
obj-$(CONFIG_GS_KXTJ9) += kxtj9.o
obj-$(CONFIG_GS_MMA8452) += mma8452.o
obj-$(CONFIG_GS_LIS3DH) += lis3dh.o
obj-$(CONFIG_GS_MMA7660) += mma7660.o
+1 -7
View File
@@ -33,12 +33,7 @@
#include <linux/kxtik.h>
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
/****************operate according to sensor chip:start************/
@@ -247,7 +242,6 @@ static int __init gsensor_kxtik_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
DBG("%s\n",__func__);
return result;
}
+335
View File
@@ -0,0 +1,335 @@
/* drivers/input/sensors/access/kxtj9.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 KXTJ9_DEVID 0x09 //chip id
#define KXTJ9_RANGE 2000000
#define KXTJ9_XOUT_HPF_L (0x00) /* 0000 0000 */
#define KXTJ9_XOUT_HPF_H (0x01) /* 0000 0001 */
#define KXTJ9_YOUT_HPF_L (0x02) /* 0000 0010 */
#define KXTJ9_YOUT_HPF_H (0x03) /* 0000 0011 */
#define KXTJ9_ZOUT_HPF_L (0x04) /* 0001 0100 */
#define KXTJ9_ZOUT_HPF_H (0x05) /* 0001 0101 */
#define KXTJ9_XOUT_L (0x06) /* 0000 0110 */
#define KXTJ9_XOUT_H (0x07) /* 0000 0111 */
#define KXTJ9_YOUT_L (0x08) /* 0000 1000 */
#define KXTJ9_YOUT_H (0x09) /* 0000 1001 */
#define KXTJ9_ZOUT_L (0x0A) /* 0001 1010 */
#define KXTJ9_ZOUT_H (0x0B) /* 0001 1011 */
#define KXTJ9_ST_RESP (0x0C) /* 0000 1100 */
#define KXTJ9_WHO_AM_I (0x0F) /* 0000 1111 */
#define KXTJ9_TILT_POS_CUR (0x10) /* 0001 0000 */
#define KXTJ9_TILT_POS_PRE (0x11) /* 0001 0001 */
#define KXTJ9_INT_SRC_REG1 (0x15) /* 0001 0101 */
#define KXTJ9_INT_SRC_REG2 (0x16) /* 0001 0110 */
#define KXTJ9_STATUS_REG (0x18) /* 0001 1000 */
#define KXTJ9_INT_REL (0x1A) /* 0001 1010 */
#define KXTJ9_CTRL_REG1 (0x1B) /* 0001 1011 */
#define KXTJ9_CTRL_REG2 (0x1C) /* 0001 1100 */
#define KXTJ9_CTRL_REG3 (0x1D) /* 0001 1101 */
#define KXTJ9_INT_CTRL_REG1 (0x1E) /* 0001 1110 */
#define KXTJ9_INT_CTRL_REG2 (0x1F) /* 0001 1111 */
#define KXTJ9_INT_CTRL_REG3 (0x20) /* 0010 0000 */
#define KXTJ9_DATA_CTRL_REG (0x21) /* 0010 0001 */
#define KXTJ9_TILT_TIMER (0x28) /* 0010 1000 */
#define KXTJ9_WUF_TIMER (0x29) /* 0010 1001 */
#define KXTJ9_TDT_TIMER (0x2B) /* 0010 1011 */
#define KXTJ9_TDT_H_THRESH (0x2C) /* 0010 1100 */
#define KXTJ9_TDT_L_THRESH (0x2D) /* 0010 1101 */
#define KXTJ9_TDT_TAP_TIMER (0x2E) /* 0010 1110 */
#define KXTJ9_TDT_TOTAL_TIMER (0x2F) /* 0010 1111 */
#define KXTJ9_TDT_LATENCY_TIMER (0x30) /* 0011 0000 */
#define KXTJ9_TDT_WINDOW_TIMER (0x31) /* 0011 0001 */
#define KXTJ9_WUF_THRESH (0x5A) /* 0101 1010 */
#define KXTJ9_TILT_ANGLE (0x5C) /* 0101 1100 */
#define KXTJ9_HYST_SET (0x5F) /* 0101 1111 */
/* CONTROL REGISTER 1 BITS */
#define KXTJ9_DISABLE 0x7F
#define KXTJ9_ENABLE (1 << 7)
/* INPUT_ABS CONSTANTS */
#define FUZZ 3
#define FLAT 3
/* RESUME STATE INDICES */
#define RES_DATA_CTRL 0
#define RES_CTRL_REG1 1
#define RES_INT_CTRL1 2
#define RESUME_ENTRIES 3
/* CTRL_REG1: set resolution, g-range, data ready enable */
/* Output resolution: 8-bit valid or 12-bit valid */
#define KXTJ9_RES_8BIT 0
#define KXTJ9_RES_12BIT (1 << 6)
/* Output g-range: +/-2g, 4g, or 8g */
#define KXTJ9_G_2G 0
#define KXTJ9_G_4G (1 << 3)
#define KXTJ9_G_8G (1 << 4)
/* DATA_CTRL_REG: controls the output data rate of the part */
#define KXTJ9_ODR12_5F 0
#define KXTJ9_ODR25F 1
#define KXTJ9_ODR50F 2
#define KXTJ9_ODR100F 3
#define KXTJ9_ODR200F 4
#define KXTJ9_ODR400F 5
#define KXTJ9_ODR800F 6
/* kxtj9 */
#define KXTJ9_PRECISION 12
#define KXTJ9_BOUNDARY (0x1 << (KXTJ9_PRECISION - 1))
#define KXTJ9_GRAVITY_STEP KXTJ9_RANGE / KXTJ9_BOUNDARY
/****************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 = KXTJ9_ENABLE; //kxtj9
sensor->ops->ctrl_data |= status;
}
else
{
status = ~KXTJ9_ENABLE; //kxtj9
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;
result = sensor_write_reg(client, KXTJ9_DATA_CTRL_REG, KXTJ9_ODR400F);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
if(sensor->pdata->irq_enable) //open interrupt
{
result = sensor_write_reg(client, KXTJ9_INT_CTRL_REG1, 0x34);//enable int,active high,need read INT_REL
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
}
sensor->ops->ctrl_data = (KXTJ9_RES_12BIT | KXTJ9_G_2G);
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_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);
//int precision = sensor->ops->precision;
switch (sensor->devid) {
case KXTJ9_DEVID:
result = (((int)high_byte << 8) | ((int)low_byte ))>>4;
if (result < KXTJ9_BOUNDARY)
result = result* KXTJ9_GRAVITY_STEP;
else
result = ~( ((~result & (0x7fff>>(16-KXTJ9_PRECISION)) ) + 1)
* KXTJ9_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);
/* 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);
//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_kxtj9_ops = {
.name = "kxtj9",
.type = SENSOR_TYPE_ACCEL, //sensor type and it should be correct
.id_i2c = ACCEL_ID_KXTJ9, //i2c id number
.read_reg = KXTJ9_XOUT_L, //read data
.read_len = 6, //data length
.id_reg = KXTJ9_WHO_AM_I, //read device id from this register
.id_data = KXTJ9_DEVID, //device id
.precision = KXTJ9_PRECISION, //12 bits
.ctrl_reg = KXTJ9_CTRL_REG1, //enable or disable
.int_status_reg = KXTJ9_INT_REL, //intterupt status register
.range = {-KXTJ9_RANGE,KXTJ9_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_kxtj9_ops;
}
static int __init gsensor_kxtj9_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_kxtj9_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_kxtj9_init);
module_exit(gsensor_kxtj9_exit);
-7
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define LIS3DH_INT_COUNT (0x0E)
#define LIS3DH_WHO_AM_I (0x0F)
@@ -325,7 +319,6 @@ static int __init gsensor_lis3dh_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
DBG("%s\n",__func__);
return result;
}
+2 -9
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define MMA7660_ENABLE 1
@@ -156,8 +150,8 @@ static int sensor_init(struct i2c_client *client)
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);
//struct sensor_private_data *sensor =
// (struct sensor_private_data *) i2c_get_clientdata(client);
//int precision = sensor->ops->precision;
result = (int)low_byte;
@@ -295,7 +289,6 @@ static int __init gsensor_mma7660_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
DBG("%s\n",__func__);
return result;
}
-7
View File
@@ -33,12 +33,6 @@
#include <linux/mma8452.h>
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define MMA8451_DEVID 0x1a
@@ -286,7 +280,6 @@ static int __init gsensor_mma8452_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
DBG("%s\n",__func__);
return result;
}
+3 -10
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define MXC6225_ENABLE 1
@@ -154,8 +148,8 @@ static int sensor_init(struct i2c_client *client)
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);
//struct sensor_private_data *sensor =
// (struct sensor_private_data *) i2c_get_clientdata(client);
//int precision = sensor->ops->precision;
result = (int)low_byte;
@@ -174,7 +168,7 @@ static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *a
/* Report acceleration sensor information */
input_report_abs(sensor->input_dev, ABS_X, axis->x);
input_report_abs(sensor->input_dev, ABS_X, axis->y);
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);
@@ -293,7 +287,6 @@ static int __init gsensor_mxc6225_init(void)
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
DBG("%s\n",__func__);
return result;
}
+9
View File
@@ -33,6 +33,15 @@ config COMPASS_AK8963
will be called ak8963.
config COMPASS_AK09911
tristate "Asahi Kasei AK09911 3-Axis Magnetometer"
depends on I2C
help
Say yes here to build support for Asahi Kasei AK09911 3-Axis Magnetometer.
To compile this driver as a module, choose M here: the module
will be called AK09911.
config COMPASS_MMC328X
tristate "Mmc328x 3-Axis Magnetometer"
depends on I2C
+2 -1
View File
@@ -3,4 +3,5 @@
#
obj-$(CONFIG_COMPASS_AK8975) += ak8975.o
obj-$(CONFIG_COMPASS_AK8963) += ak8963.o
obj-$(CONFIG_COMPASS_MMC328X) += mmc328x.o
obj-$(CONFIG_COMPASS_AK09911) += ak09911.o
obj-$(CONFIG_COMPASS_MMC328X) += mmc328x.o
+795
View File
@@ -0,0 +1,795 @@
/* 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 <mach/gpio.h>
#include <mach/board.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.
*/
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;
* data read would not be correct.
* Valid in continuous measurement mode only.
* In single measurement mode this error should not occour but we
* stil account for it and return an error, since the data would be
* corrupted.
* DERR bit is self-clearing when ST2 register is read.
*/
if (*stat2 & 0x04)
{
DBG(KERN_ERR "%s:compass data error\n",__func__);
return -2;
}
/*
* ST2 : overflow -
* the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
* This is likely to happen in presence of an external magnetic
* disturbance; it indicates, the sensor data is incorrect and should
* be ignored.
* An error is returned.
* HOFL bit clears when a new measurement starts.
*/
if (*stat2 & 0x08)
{
DBG(KERN_ERR "%s:compass data overflow\n",__func__);
return -3;
}
#endif
/* »¥³âµØ»º´æÊý¾Ý. */
mutex_lock(&sensor->data_mutex);
memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
mutex_unlock(&sensor->data_mutex);
DBG("%s:",__func__);
for(i=0; 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;
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);
+1 -14
View File
@@ -34,12 +34,6 @@
#define SENSOR_DATA_SIZE 8
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_COMPASS
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define SENSOR_DATA_SIZE 8
#define YPR_DATA_SIZE 12
@@ -205,9 +199,8 @@ static int sensor_report_value(struct i2c_client *client)
unsigned char *stat2;
int ret = 0;
char value = 0;
#ifdef SENSOR_DEBUG_TYPE
int i;
#endif
if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
@@ -271,12 +264,10 @@ static int sensor_report_value(struct i2c_client *client)
mutex_lock(&sensor->data_mutex);
memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
mutex_unlock(&sensor->data_mutex);
#ifdef SENSOR_DEBUG_TYPE
DBG("%s:",__func__);
for(i=0; i<sensor->ops->read_len; i++)
DBG("0x%x,",buffer[i]);
DBG("\n");
#endif
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
@@ -348,10 +339,8 @@ static void compass_set_YPR(int *rbuf)
static int compass_dev_open(struct inode *inode, struct file *file)
{
#ifdef SENSOR_DEBUG_TYPE
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(this_client);
#endif
int result = 0;
DBG("%s\n",__func__);
@@ -361,10 +350,8 @@ static int compass_dev_open(struct inode *inode, struct file *file)
static int compass_dev_release(struct inode *inode, struct file *file)
{
#ifdef SENSOR_DEBUG_TYPE
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(this_client);
#endif
int result = 0;
DBG("%s\n",__func__);
+1 -14
View File
@@ -35,12 +35,6 @@
#define SENSOR_DATA_SIZE 8
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_COMPASS
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
/*! \name AK8975 operation mode
\anchor AK8975_Mode
@@ -191,9 +185,8 @@ static int sensor_report_value(struct i2c_client *client)
unsigned char *stat2;
int ret = 0;
char value = 0;
#ifdef SENSOR_DEBUG_TYPE
int i;
#endif
if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8
{
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
@@ -257,12 +250,10 @@ static int sensor_report_value(struct i2c_client *client)
mutex_lock(&sensor->data_mutex);
memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
mutex_unlock(&sensor->data_mutex);
#ifdef SENSOR_DEBUG_TYPE
DBG("%s:",__func__);
for(i=0; i<sensor->ops->read_len; i++)
DBG("0x%x,",buffer[i]);
DBG("\n");
#endif
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
{
@@ -322,10 +313,8 @@ static void compass_set_YPR(short *rbuf)
static int compass_dev_open(struct inode *inode, struct file *file)
{
#ifdef SENSOR_DEBUG_TYPE
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(this_client);
#endif
int result = 0;
DBG("%s\n",__func__);
@@ -335,10 +324,8 @@ static int compass_dev_open(struct inode *inode, struct file *file)
static int compass_dev_release(struct inode *inode, struct file *file)
{
#ifdef SENSOR_DEBUG_TYPE
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(this_client);
#endif
int result = 0;
DBG("%s\n",__func__);
-7
View File
@@ -33,12 +33,6 @@
#include <linux/l3g4200d.h>
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_GYROSCOPE
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define L3G4200D_ENABLE 0x08
@@ -246,7 +240,6 @@ static int __init gyro_l3g20d_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
DBG("%s\n",__func__);
return result;
}
-7
View File
@@ -33,12 +33,6 @@
#include <linux/l3g4200d.h>
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_GYROSCOPE
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define L3G4200D_ENABLE 0x08
@@ -246,7 +240,6 @@ static int __init gyro_l3g4200d_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);
DBG("%s\n",__func__);
return result;
}
+3
View File
@@ -35,5 +35,8 @@ config LS_PHOTORESISTOR
bool "light sensor photoresistor"
default n
config LS_US5152
bool "light sensor us5152"
default n
endif
+2 -1
View File
@@ -6,4 +6,5 @@ obj-$(CONFIG_LS_AL3006) += ls_al3006.o
obj-$(CONFIG_LS_STK3171) += ls_stk3171.o
obj-$(CONFIG_LS_ISL29023) += isl29023.o
obj-$(CONFIG_LS_AP321XX) += ls_ap321xx.o
obj-$(CONFIG_LS_PHOTORESISTOR) += ls_photoresistor.o
obj-$(CONFIG_LS_PHOTORESISTOR) += ls_photoresistor.o
obj-$(CONFIG_LS_US5152) += ls_us5152.o
+8 -12
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define CM3217_ADDR_COM1 0x10
#define CM3217_ADDR_COM2 0x11
@@ -121,9 +115,10 @@ static int sensor_init(struct i2c_client *client)
}
static void light_report_value(struct input_dev *input, int data)
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 10){
index = 0;goto report;
}
@@ -150,9 +145,10 @@ static void light_report_value(struct input_dev *input, int data)
}
report:
DBG("cm3217 report data=%d,index = %d\n",data,index);
input_report_abs(input, ABS_MISC, index);
input_sync(input);
return index;
}
@@ -162,6 +158,7 @@ static int sensor_report_value(struct i2c_client *client)
(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);
@@ -169,9 +166,9 @@ static int sensor_report_value(struct i2c_client *client)
sensor_rx_data_normal(sensor->client, &msb, 1);
result = ((msb << 8) | lsb) & 0xffff;
DBG("%s:result=%d\n",__func__,result);
light_report_value(sensor->input_dev, result);
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
{
@@ -220,7 +217,6 @@ static int __init light_cm3217_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
printk("%s\n",__func__);
return result;
}
+9 -13
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define CM3232_CLOSE 0x01
@@ -72,7 +66,7 @@ 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;
//int status = 0;
//sensor->client->addr = sensor->ops->ctrl_reg;
//sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
@@ -125,9 +119,10 @@ static int sensor_init(struct i2c_client *client)
}
static void light_report_value(struct input_dev *input, int data)
static int light_report_value(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 10){
index = 0;goto report;
}
@@ -154,10 +149,10 @@ static void light_report_value(struct input_dev *input, int data)
}
report:
DBG("cm3232 report data=%d,index = %d\n",data,index);
printk("cm3232 report data=%d,index = %d\n",data,index);
input_report_abs(input, ABS_MISC, index);
input_sync(input);
return index;
}
@@ -166,9 +161,10 @@ 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 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;
@@ -177,7 +173,8 @@ static int sensor_report_value(struct i2c_client *client)
DBG("%s:result=%d\n",__func__,value);
//printk("%s:result=%d\n",__func__,value);
light_report_value(sensor->input_dev, 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
{
@@ -227,7 +224,6 @@ static int __init light_cm3232_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
//printk("%s: >>>>>>>>>>>>>>>>>>>\n\n\n",__func__);
return result;
}
+7 -14
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define ISL29023_REG_ADD_COMMAND1 0x00
#define COMMMAND1_OPMODE_SHIFT 5
@@ -87,7 +81,7 @@ 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;
//int status = 0;
sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
@@ -224,7 +218,7 @@ static int sensor_report_value(struct i2c_client *client)
return result;
}
struct sensor_operate light_stk3171_ops = {
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
@@ -248,21 +242,20 @@ struct sensor_operate light_stk3171_ops = {
//function name should not be changed
static struct sensor_operate *light_get_ops(void)
{
return &light_stk3171_ops;
return &light_isl29023_ops;
}
static int __init light_stk3171_init(void)
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);
//printk("%s\n",__func__);
return result;
}
static void __exit light_stk3171_exit(void)
static void __exit light_isl29023_exit(void)
{
struct sensor_operate *ops = light_get_ops();
int type = ops->type;
@@ -270,7 +263,7 @@ static void __exit light_stk3171_exit(void)
}
module_init(light_stk3171_init);
module_exit(light_stk3171_exit);
module_init(light_isl29023_init);
module_exit(light_isl29023_exit);
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define CONFIG_REG (0x00)
#define TIM_CTL_REG (0x01)
@@ -285,7 +279,6 @@ static int __init light_al3006_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
DBG("%s\n",__func__);
return result;
}
+3 -10
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define AP3212B_NUM_CACHABLE_REGS 23
#define AP3216C_NUM_CACHABLE_REGS 26
@@ -219,16 +213,16 @@ static int ap321xx_product_detect(struct i2c_client *client)
if ( mid == 0x01 && pid == 0x01 &&
(rid == 0x03 || rid == 0x04) )
{
DBG("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
//printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
}
else if ( (mid == 0x01 && pid == 0x02 && rid == 0x00) ||
(mid == 0x02 && pid == 0x02 && rid == 0x01))
{
DBG("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
//printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
}
else
{
DBG("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
//printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
return -EIO;
}
@@ -398,7 +392,6 @@ static int __init light_ap321xx_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
DBG("%s\n",__func__);
return result;
}
@@ -33,20 +33,6 @@
#endif
#include <linux/sensor-dev.h>
static int ls_photoresistor_dbg_level = 0;
module_param_named(dbg_level, ls_photoresistor_dbg_level, int, 0644);
#if 1
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT
#define DBG( args...) \
do { \
if (ls_photoresistor_dbg_level) { \
pr_info(args); \
} \
} while (0)
#else
#define DBG(x...) printk(x)
#endif
struct lsp_base_data {
int adcvalue ;
@@ -63,9 +49,9 @@ static int LighSensorLevel_TAB[8]={0,1,2,3,4,5,6,7};
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
int ret = 0;
//int ret = 0;
DBG("light_photoresisto: sensor active is %s \n",( (enable)?"on":"off" ) );
//printk("light_photoresisto: sensor active is %s \n",( (enable)?"on":"off" ) );
if( enable ){//ture on
@@ -79,7 +65,7 @@ static int sensor_active(struct i2c_client *client, int enable, int rate)
static void lsp_adc_callback(struct adc_client *client, void *callback_param, int result)
{
glspdata.adcvalue = result;
DBG("light_photoresisto: adc callback value is %d \n",glspdata.adcvalue);
//printk("light_photoresisto: adc callback value is %d \n",glspdata.adcvalue);
}
static int valuetoindex( int data)
@@ -105,7 +91,7 @@ static int sensor_report_value(struct i2c_client *client)
adc_async_read(glspdata.adc_client);
if(glspdata.adcvalue==0||glspdata.adcvalue==1){//
DBG("light_photoresisto: adc value is (%d) invalid \n",glspdata.adcvalue);
printk("light_photoresisto: adc value is (%d) invalid \n",glspdata.adcvalue);
return ret ;
}
@@ -124,9 +110,9 @@ static int sensor_report_value(struct i2c_client *client)
static int sensor_init(struct i2c_client *client)
{
DBG("enter %s\n",__func__);
int error = 0 ;
struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client);
DBG("enter %s\n",__func__);
//adc register
if( (sensor->pdata->address >= 0) && (sensor->pdata->address <=3) ){
@@ -148,11 +134,11 @@ static int sensor_init(struct i2c_client *client)
struct sensor_operate light_photoresistor_ops = {
.name = "light_photoresistor",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_PHOTORESISTOR, //i2c id number
.range = {0,10}, //range
.brightness ={1,255}, // brightness
.range = {0,10}, //range
.brightness ={1,255}, // brightness
.active = sensor_active,
.init = sensor_init,
.report = sensor_report_value,
@@ -165,7 +151,7 @@ struct sensor_operate light_photoresistor_ops = {
.precision = SENSOR_UNKNOW_DATA, //8 bits INVALID
.ctrl_reg = SENSOR_UNKNOW_DATA, //enable or disable INVALID
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register INVALID
.trig = SENSOR_UNKNOW_DATA,
.trig = SENSOR_UNKNOW_DATA,
/*--------- INVALID end-------*/
};
/****************operate according to sensor chip:end************/
@@ -183,7 +169,6 @@ static int __init lsp_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
DBG("%s\n",__func__);
return result;
}
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define ALS_CMD 0x01
#define ALS_DT1 0x02
@@ -304,7 +298,6 @@ static int __init light_stk3171_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
DBG("%s\n",__func__);
return result;
}
+438
View File
@@ -0,0 +1,438 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>
#include <linux/types.h>
#define DRIVER_VERSION "1.0"
#define PWR_MODE_DOWN_MASK 0x80
#define PWR_MODE_OPERATE_MASK 0x7F
/*us5152 Slave Addr*/
#define LIGHT_ADDR 0x72
/*Interrupt PIN for S3C6410*/
#define IRQ_LIGHT_INT IRQ_EINT(6)
/*Register Set*/
#define REGS_CR0 0x00
#define REGS_CR1 0x01
#define REGS_CR2 0x02
#define REGS_CR3 0x03
//ALS
#define REGS_INT_LSB_TH_LO 0x04
#define REGS_INT_MSB_TH_LO 0x05
#define REGS_INT_LSB_TH_HI 0x06
#define REGS_INT_MSB_TH_HI 0x07
//ALS data
#define REGS_LBS_SENSOR 0x0C
#define REGS_MBS_SENSOR 0x0D
#define REGS_CR10 0x10
#define REGS_CR11 0x11
#define REGS_VERSION_ID 0x1F
#define REGS_CHIP_ID 0xB2
/*ShutDown_EN*/
#define CR0_OPERATION 0x0
#define CR0_SHUTDOWN_EN 0x1
#define CR0_SHUTDOWN_SHIFT (7)
#define CR0_SHUTDOWN_MASK (0x1 << CR0_SHUTDOWN_SHIFT)
/*OneShot_EN*/
#define CR0_ONESHOT_EN 0x01
#define CR0_ONESHOT_SHIFT (6)
#define CR0_ONESHOT_MASK (0x1 << CR0_ONESHOT_SHIFT)
/*Operation Mode*/
#define CR0_OPMODE_ALSANDPS 0x0
#define CR0_OPMODE_ALSONLY 0x1
#define CR0_OPMODE_IRONLY 0x2
#define CR0_OPMODE_SHIFT (4)
#define CR0_OPMODE_MASK (0x3 << CR0_OPMODE_SHIFT)
/*all int flag (PROX, INT_A, INT_P)*/
#define CR0_ALL_INT_CLEAR 0x0
#define CR0_ALL_INT_SHIFT (1)
#define CR0_ALL_INT_MASK (0x7 << CR0_ALL_INT_SHIFT)
/*indicator of object proximity detection*/
#define CR0_PROX_CLEAR 0x0
#define CR0_PROX_SHIFT (3)
#define CR0_PROX_MASK (0x1 << CR0_PROX_SHIFT)
/*interrupt status of proximity sensor*/
#define CR0_INTP_CLEAR 0x0
#define CR0_INTP_SHIFT (2)
#define CR0_INTP_MASK (0x1 << CR0_INTP_SHIFT)
/*interrupt status of ambient sensor*/
#define CR0_INTA_CLEAR 0x0
#define CR0_INTA_SHIFT (1)
#define CR0_INTA_MASK (0x1 << CR0_INTA_SHIFT)
/*Word mode enable*/
#define CR0_WORD_EN 0x1
#define CR0_WORD_SHIFT (0)
#define CR0_WORD_MASK (0x1 << CR0_WORD_SHIFT)
/*ALS fault queue depth for interrupt enent output*/
#define CR1_ALS_FQ_1 0x0
#define CR1_ALS_FQ_4 0x1
#define CR1_ALS_FQ_8 0x2
#define CR1_ALS_FQ_16 0x3
#define CR1_ALS_FQ_24 0x4
#define CR1_ALS_FQ_32 0x5
#define CR1_ALS_FQ_48 0x6
#define CR1_ALS_FQ_63 0x7
#define CR1_ALS_FQ_SHIFT (5)
#define CR1_ALS_FQ_MASK (0x7 << CR1_ALS_FQ_SHIFT)
/*resolution for ALS*/
#define CR1_ALS_RES_12BIT 0x0
#define CR1_ALS_RES_14BIT 0x1
#define CR1_ALS_RES_16BIT 0x2
#define CR1_ALS_RES_16BIT_2 0x3
#define CR1_ALS_RES_SHIFT (3)
#define CR1_ALS_RES_MASK (0x3 << CR1_ALS_RES_SHIFT)
/*sensing amplifier selection for ALS*/
#define CR1_ALS_GAIN_X1 0x0
#define CR1_ALS_GAIN_X2 0x1
#define CR1_ALS_GAIN_X4 0x2
#define CR1_ALS_GAIN_X8 0x3
#define CR1_ALS_GAIN_X16 0x4
#define CR1_ALS_GAIN_X32 0x5
#define CR1_ALS_GAIN_X64 0x6
#define CR1_ALS_GAIN_X128 0x7
#define CR1_ALS_GAIN_SHIFT (0)
#define CR1_ALS_GAIN_MASK (0x7 << CR1_ALS_GAIN_SHIFT)
/*PS fault queue depth for interrupt event output*/
#define CR2_PS_FQ_1 0x0
#define CR2_PS_FQ_4 0x1
#define CR2_PS_FQ_8 0x2
#define CR2_PS_FQ_15 0x3
#define CR2_PS_FQ_SHIFT (6)
#define CR2_PS_FQ_MASK (0x3 << CR2_PS_FQ_SHIFT)
/*interrupt type setting */
/*low active*/
#define CR2_INT_LEVEL 0x0
/*low pulse*/
#define CR2_INT_PULSE 0x1
#define CR2_INT_SHIFT (5)
#define CR2_INT_MASK (0x1 << CR2_INT_SHIFT)
/*resolution for PS*/
#define CR2_PS_RES_12 0x0
#define CR2_PS_RES_14 0x1
#define CR2_PS_RES_16 0x2
#define CR2_PS_RES_16_2 0x3
#define CR2_PS_RES_SHIFT (3)
#define CR2_PS_RES_MASK (0x3 << CR2_PS_RES_SHIFT)
/*sensing amplifier selection for PS*/
#define CR2_PS_GAIN_1 0x0
#define CR2_PS_GAIN_2 0x1
#define CR2_PS_GAIN_4 0x2
#define CR2_PS_GAIN_8 0x3
#define CR2_PS_GAIN_16 0x4
#define CR2_PS_GAIN_32 0x5
#define CR2_PS_GAIN_64 0x6
#define CR2_PS_GAIN_128 0x7
#define CR2_PS_GAIN_SHIFT (0)
#define CR2_PS_GAIN_MASK (0x7 << CR2_PS_GAIN_SHIFT)
/*wait-time slot selection*/
#define CR3_WAIT_SEL_0 0x0
#define CR3_WAIT_SEL_4 0x1
#define CR3_WAIT_SEL_8 0x2
#define CR3_WAIT_SEL_16 0x3
#define CR3_WAIT_SEL_SHIFT (6)
#define CR3_WAIT_SEL_MASK (0x3 << CR3_WAIT_SEL_SHIFT)
/*IR-LED drive peak current setting*/
#define CR3_LEDDR_12_5 0x0
#define CR3_LEDDR_25 0x1
#define CR3_LEDDR_50 0x2
#define CR3_LEDDR_100 0x3
#define CR3_LEDDR_SHIFT (4)
#define CR3_LEDDR_MASK (0x3 << CR3_LEDDR_SHIFT)
/*INT pin source selection*/
#define CR3_INT_SEL_BATH 0x0
#define CR3_INT_SEL_ALS 0x1
#define CR3_INT_SEL_PS 0x2
#define CR3_INT_SEL_PSAPP 0x3
#define CR3_INT_SEL_SHIFT (2)
#define CR3_INT_SEL_MASK (0x3 << CR3_INT_SEL_SHIFT)
/*software reset for register and core*/
#define CR3_SOFTRST_EN 0x1
#define CR3_SOFTRST_SHIFT (0)
#define CR3_SOFTRST_MASK (0x1 << CR3_SOFTRST_SHIFT)
/*modulation frequency of LED driver*/
#define CR10_FREQ_DIV2 0x0
#define CR10_FREQ_DIV4 0x1
#define CR10_FREQ_DIV8 0x2
#define CR10_FREQ_DIV16 0x3
#define CR10_FREQ_SHIFT (1)
#define CR10_FREQ_MASK (0x3 << CR10_FREQ_SHIFT)
/*50/60 Rejection enable*/
#define CR10_REJ_5060_DIS 0x00
#define CR10_REJ_5060_EN 0x01
#define CR10_REJ_5060_SHIFT (0)
#define CR10_REJ_5060_MASK (0x1 << CR10_REJ_5060_SHIFT)
#define us5152_NUM_CACHABLE_REGS 0x12
static int sensor_active(struct i2c_client *client, int enable, int rate)
{
//struct sensor_private_data *sensor =
// (struct sensor_private_data *) i2c_get_clientdata(client);
int result = 0;
char value = 0;
int i = 0;
for(i=0; i<3; i++)
{
if(!enable)
{
value = sensor_read_reg(client, REGS_CR0);
value |= PWR_MODE_DOWN_MASK; //ShutDown_EN=1
result = sensor_write_reg(client, REGS_CR0, value);
if(result)
return result;
}
else
{
value = sensor_read_reg(client, REGS_CR0);
value &= PWR_MODE_OPERATE_MASK ; //Operation_EN=0
result = sensor_write_reg(client, REGS_CR0, value);
if(result)
return result;
}
if(!result)
break;
}
if(i>1)
printk("%s:set %d times",__func__,i);
//TODO:? function to be added here
return result;
}
static int sensor_init(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int result = 0;
char value = 0;
result = sensor->ops->active(client,0,0);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
sensor->status_cur = SENSOR_OFF;
value = sensor_read_reg(client, REGS_CHIP_ID); //read chip ids
printk("us5152 chip id is %x!\n", value);
value = 0x01;//word accessing
result = sensor_write_reg(client, REGS_CR0, value);
if(result)
{
printk("%s:line=%d,error\n",__func__,__LINE__);
return result;
}
return result;
}
static int us5152_value_report(struct input_dev *input, int data)
{
unsigned char index = 0;
if(data <= 10){
index = 0;goto report;
}
else if(data <= 160){
index = 1;goto report;
}
else if(data <= 225){
index = 2;goto report;
}
else if(data <= 320){
index = 3;goto report;
}
else if(data <= 640){
index = 4;goto report;
}
else if(data <= 1280){
index = 5;goto report;
}
else if(data <= 2600){
index = 6;goto report;
}
else{
index = 7;goto report;
}
report:
input_report_abs(input, ABS_MISC, index);
input_sync(input);
return index;
}
static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *) i2c_get_clientdata(client);
int result = 0;
int value = 0;
char index = 0;
char buffer[2]= { 0 } ;
int ret=0;
if(sensor->pdata->irq_enable)
{
if(sensor->ops->int_status_reg >= 0)
{
value = sensor_read_reg(client, sensor->ops->int_status_reg);
}
}
//value = sensor_read_reg(client, sensor->ops->read_reg); //TODO:? to be changed
if(sensor->ops->read_len< 2) //12bit
{
printk("us5152 data read para num error ; len = %d\n ",sensor->ops->read_len);
return -1;
}
memset(buffer , 0 , 2);
do
{
*buffer = sensor->ops->read_reg;
ret=sensor_rx_data(client,buffer,sensor->ops->read_len);
if(ret<0)
return ret;
}
while(0);
value=buffer[1];
value =((value << 8) | buffer[0]) & 0xffff;
index = us5152_value_report(sensor->input_dev, value); //now is 12bit
//printk("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
DBG("%s:%s result=%d,index=%d buffer[1]=0x%x , buffer[0]=0x%x \n",__func__,sensor->ops->name, value,index,buffer[1],buffer[0]);
return result;
}
struct sensor_operate light_us5152_ops = {
.name = "ls_us5152",
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct
.id_i2c = LIGHT_ID_US5152, //i2c id number
.read_reg = REGS_LBS_SENSOR, //read data
.read_len = 2, //data length
.id_reg = REGS_CHIP_ID, //read device id from this register
.id_data = 0x26, //device id
.precision = 12, //12 bits
.ctrl_reg = REGS_CR0, //enable or disable
.int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register
.range = {0,10}, //range
.brightness = {10,4095}, // brightness
.trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT ,
.active = sensor_active,
.init = sensor_init,
.report = sensor_report_value,
};
/****************operate according to sensor chip:end************/
//function name should not be changed
static struct sensor_operate *light_get_ops(void)
{
return &light_us5152_ops;
}
static int __init us5152_init(void)
{
struct sensor_operate *ops = light_get_ops();
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
return result;
}
static void __exit us5152_exit(void)
{
struct sensor_operate *ops = light_get_ops();
int type = ops->type;
sensor_unregister_slave(type, NULL, NULL, light_get_ops);
}
MODULE_AUTHOR("Finley Huang finley_huang@upi-semi.com");
MODULE_DESCRIPTION("us5152 ambient light sensor driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRIVER_VERSION);
module_init(us5152_init);
module_exit(us5152_exit);
+235
View File
@@ -0,0 +1,235 @@
/*
* Copyright (C) 2012 UPI semi <Finley_huang@upi-semi.com>. All Rights Reserved.
* 5152 Light Sensor Driver for Linux 2.6
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* 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.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __us5152_H__
#define __us5152_H__
#include <linux/types.h>
#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
#endif
+2 -9
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PRESSURE
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
@@ -94,8 +88,8 @@ static int sensor_active(struct i2c_client *client, int enable, int rate)
for (i=0;i<8;i++)
{
C[i] = prom[2*i] << 8 | prom[2*i + 1];
DBG("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
DBG("\nC[%d]=%d,",i+1,C[i]);
//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]);
}
}
@@ -283,7 +277,6 @@ static int __init pressure_ms5607_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, pressure_get_ops);
printk("%s\n",__func__);
return result;
}
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PROXIMITY
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define CONFIG_REG (0x00)
#define TIM_CTL_REG (0x01)
@@ -246,7 +240,6 @@ static int __init proximity_al3006_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
DBG("%s\n",__func__);
return result;
}
+3 -10
View File
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PROXIMITY
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define AP3212B_NUM_CACHABLE_REGS 23
#define AP3216C_NUM_CACHABLE_REGS 26
@@ -154,16 +148,16 @@ static int ap321xx_product_detect(struct i2c_client *client)
if ( mid == 0x01 && pid == 0x01 &&
(rid == 0x03 || rid == 0x04) )
{
DBG("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
//printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);
}
else if ( (mid == 0x01 && pid == 0x02 && rid == 0x00) ||
(mid == 0x02 && pid == 0x02 && rid == 0x01))
{
DBG("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
//printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);
}
else
{
DBG("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);
return -EIO;
}
@@ -311,7 +305,6 @@ static int __init proximity_ap321xx_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
DBG("%s\n",__func__);
return result;
}
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PROXIMITY
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define ALS_CMD 0x01
#define ALS_DT1 0x02
@@ -252,7 +246,6 @@ static int __init proximity_stk3171_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);
DBG("%s\n",__func__);
return result;
}
+64 -16
View File
@@ -26,6 +26,7 @@
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/proc_fs.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
@@ -35,24 +36,64 @@
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#if 0
/*
sensor-dev.c v1.1 add pressure and temperature support 2013-2-27
sensor-dev.c v1.2 add akm8963 support 2013-3-10
#endif
#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.2 add akm8963 support 2013-3-10"
sensor-dev.c v1.3 add sensor debug support 2013-3-15
*/
#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.3 add sensor debug support 2013-3-15"
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, 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_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)
{
@@ -608,7 +649,7 @@ 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;
//struct i2c_client *client = sensor->client;
void __user *argp = (void __user *)arg;
int result = 0;
short flag;
@@ -1439,6 +1480,7 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
struct sensor_platform_data *pdata;
int result = 0;
int type = 0;
dev_info(&client->adapter->dev, "%s: %s,0x%x\n", __func__, devid->name,(unsigned int)client);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
@@ -1506,7 +1548,8 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
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.open_flag, 0);
atomic_set(&sensor->flags.debug_flag, 0);
init_waitqueue_head(&sensor->flags.open_wq);
sensor->flags.delay = 100;
@@ -1639,7 +1682,7 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
"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))
@@ -1700,7 +1743,8 @@ static const struct i2c_device_id sensor_id[] = {
/*gsensor*/
{"gsensor", ACCEL_ID_ALL},
{"gs_mma8452", ACCEL_ID_MMA845X},
{"gs_kxtik", ACCEL_ID_KXTIK},
{"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},
@@ -1708,11 +1752,12 @@ static const struct i2c_device_id sensor_id[] = {
{"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_gryo", GYRO_ID_L3G4200D},
{"l3g20d_gryo", GYRO_ID_L3G20D},
{"l3g20d_gryo", GYRO_ID_L3G20D},
{"k3g", GYRO_ID_K3G},
/*light sensor*/
{"lightsensor", LIGHT_ID_ALL},
@@ -1723,6 +1768,7 @@ static const struct i2c_device_id sensor_id[] = {
{"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},
@@ -1754,11 +1800,13 @@ static struct i2c_driver sensor_driver = {
static int __init sensor_init(void)
{
int res = i2c_add_driver(&sensor_driver);
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;
}
+1 -14
View File
@@ -34,12 +34,6 @@
#define SENSOR_I2C_RATE 200*1000
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_COMPASS
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
static int sensor_i2c_write(struct i2c_adapter *i2c_adap,
unsigned char address,
@@ -106,39 +100,32 @@ static int senosr_i2c_read(struct i2c_adapter *i2c_adap,
int sensor_rx_data(struct i2c_client *client, char *rxData, int length)
{
#ifdef SENSOR_DEBUG_TYPE
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
int i = 0;
#endif
int ret = 0;
char reg = rxData[0];
ret = senosr_i2c_read(client->adapter, client->addr, reg, length, rxData);
#ifdef SENSOR_DEBUG_TYPE
DBG("addr=0x%x,len=%d,rxdata:",reg,length);
for(i=0; i<length; i++)
DBG("0x%x,",rxData[i]);
DBG("\n");
#endif
return ret;
}
EXPORT_SYMBOL(sensor_rx_data);
int sensor_tx_data(struct i2c_client *client, char *txData, int length)
{
#ifdef SENSOR_DEBUG_TYPE
struct sensor_private_data* sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
int i = 0;
#endif
int ret = 0;
#ifdef SENSOR_DEBUG_TYPE
DBG("addr=0x%x,len=%d,txdata:",txData[0],length);
for(i=1; i<length; i++)
DBG("0x%x,",txData[i]);
DBG("\n");
#endif
ret = sensor_i2c_write(client->adapter, client->addr, length, txData);
return ret;
@@ -32,12 +32,6 @@
#endif
#include <linux/sensor-dev.h>
#if 0
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_TEMPERATURE
#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)
#else
#define DBG(x...)
#endif
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
@@ -93,8 +87,8 @@ static int sensor_active(struct i2c_client *client, int enable, int rate)
for (i=0;i<8;i++)
{
C[i] = prom[2*i] << 8 | prom[2*i + 1];
DBG("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);
DBG("\nC[%d]=%d,",i+1,C[i]);
//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]);
}
}
@@ -300,7 +294,6 @@ static int __init temperature_ms5607_init(void)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, temperature_get_ops);
DBG("%s\n",__func__);
return result;
}
+10 -1
View File
@@ -46,6 +46,7 @@ enum sensor_id {
ACCEL_ID_KXSD9,
ACCEL_ID_KXTF9,
ACCEL_ID_KXTIK,
ACCEL_ID_KXTJ9,
ACCEL_ID_BMA150,
ACCEL_ID_BMA222,
ACCEL_ID_BMA250,
@@ -59,6 +60,7 @@ enum sensor_id {
COMPASS_ID_ALL,
COMPASS_ID_AK8975,
COMPASS_ID_AK8963,
COMPASS_ID_AK09911,
COMPASS_ID_AK8972,
COMPASS_ID_AMI30X,
COMPASS_ID_AMI306,
@@ -73,7 +75,7 @@ enum sensor_id {
GYRO_ID_ALL,
GYRO_ID_L3G4200D,
GYRO_ID_L3G20D,
GYRO_ID_L3G20D,
GYRO_ID_K3G,
LIGHT_ID_ALL,
@@ -84,6 +86,7 @@ enum sensor_id {
LIGHT_ID_ISL29023,
LIGHT_ID_AP321XX,
LIGHT_ID_PHOTORESISTOR,
LIGHT_ID_US5152,
PROXIMITY_ID_ALL,
PROXIMITY_ID_AL3006,
@@ -111,6 +114,7 @@ struct sensor_flag {
atomic_t m_flag;
atomic_t mv_flag;
atomic_t open_flag;
atomic_t debug_flag;
long long delay;
wait_queue_head_t open_wq;
};
@@ -181,6 +185,11 @@ extern int sensor_unregister_slave(int type,struct i2c_client *client,
struct sensor_platform_data *slave_pdata,
struct sensor_operate *(*get_sensor_ops)(void));
#if 1
#define DBG(x...) if((atomic_read(&sensor->flags.debug_flag) == sensor->pdata->type) || (atomic_read(&sensor->flags.debug_flag) == SENSOR_NUM_TYPES))printk(x)
#else
#define DBG(x...)
#endif
#define GSENSOR_IOCTL_MAGIC 'a'
#define GBUFF_SIZE 12 /* Rx buffer size */