sensors:add sensor debug support
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Executable
+335
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
+795
@@ -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);
|
||||
|
||||
|
||||
@@ -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__);
|
||||
|
||||
|
||||
@@ -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__);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,5 +35,8 @@ config LS_PHOTORESISTOR
|
||||
bool "light sensor photoresistor"
|
||||
default n
|
||||
|
||||
config LS_US5152
|
||||
bool "light sensor us5152"
|
||||
default n
|
||||
endif
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user