int y_min;
int z_min;
int factory;
+ int layout;
unsigned char address;
signed char orientation[9];
short m_layout[4][3][3];
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
obj-$(CONFIG_GS_KXTIK) += kxtik.o\r
+obj-$(CONFIG_GS_KXTJ9) += kxtj9.o\r
obj-$(CONFIG_GS_MMA8452) += mma8452.o\r
obj-$(CONFIG_GS_LIS3DH) += lis3dh.o\r
obj-$(CONFIG_GS_MMA7660) += mma7660.o
#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************/
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
- DBG("%s\n",__func__);
return result;
}
--- /dev/null
+/* 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);
+
#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)
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
- DBG("%s\n",__func__);
return result;
}
#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
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;
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
- DBG("%s\n",__func__);
return result;
}
#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
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
- DBG("%s\n",__func__);
return result;
}
#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
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;
/* 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);
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
- DBG("%s\n",__func__);
return result;
}
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
#
obj-$(CONFIG_COMPASS_AK8975) += ak8975.o
obj-$(CONFIG_COMPASS_AK8963) += ak8963.o
-obj-$(CONFIG_COMPASS_MMC328X) += mmc328x.o
\ No newline at end of file
+obj-$(CONFIG_COMPASS_AK09911) += ak09911.o
+obj-$(CONFIG_COMPASS_MMC328X) += mmc328x.o
--- /dev/null
+/* drivers/input/sensors/access/akm09911.c\r
+ *\r
+ * Copyright (C) 2012-2015 ROCKCHIP.\r
+ * Author: luowei <lw@rock-chips.com>\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ */\r
+#include <linux/interrupt.h>\r
+#include <linux/i2c.h>\r
+#include <linux/slab.h>\r
+#include <linux/irq.h>\r
+#include <linux/miscdevice.h>\r
+#include <linux/gpio.h>\r
+#include <asm/uaccess.h>\r
+#include <asm/atomic.h>\r
+#include <linux/delay.h>\r
+#include <linux/input.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/freezer.h>\r
+#include <mach/gpio.h>\r
+#include <mach/board.h> \r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+#include <linux/earlysuspend.h>\r
+#endif\r
+#include <linux/sensor-dev.h>\r
+\r
+\r
+\r
+#define SENSOR_DATA_SIZE 9\r
+#define YPR_DATA_SIZE 16\r
+#define RWBUF_SIZE 16\r
+\r
+#define ACC_DATA_FLAG 0\r
+#define MAG_DATA_FLAG 1\r
+#define ORI_DATA_FLAG 2\r
+#define AKM_NUM_SENSORS 3\r
+\r
+#define ACC_DATA_READY (1<<(ACC_DATA_FLAG))\r
+#define MAG_DATA_READY (1<<(MAG_DATA_FLAG))\r
+#define ORI_DATA_READY (1<<(ORI_DATA_FLAG))\r
+\r
+/*Constant definitions of the AK09911.*/\r
+#define AK09911_MEASUREMENT_TIME_US 10000\r
+\r
+#define AK09911_MODE_SNG_MEASURE 0x01\r
+#define AK09911_MODE_SELF_TEST 0x10\r
+#define AK09911_MODE_FUSE_ACCESS 0x1F\r
+#define AK09911_MODE_POWERDOWN 0x00\r
+#define AK09911_RESET_DATA 0x01\r
+\r
+\r
+/* Device specific constant values */\r
+#define AK09911_REG_WIA1 0x00\r
+#define AK09911_REG_WIA2 0x01\r
+#define AK09911_REG_INFO1 0x02\r
+#define AK09911_REG_INFO2 0x03\r
+#define AK09911_REG_ST1 0x10\r
+#define AK09911_REG_HXL 0x11\r
+#define AK09911_REG_HXH 0x12\r
+#define AK09911_REG_HYL 0x13\r
+#define AK09911_REG_HYH 0x14\r
+#define AK09911_REG_HZL 0x15\r
+#define AK09911_REG_HZH 0x16\r
+#define AK09911_REG_TMPS 0x17\r
+#define AK09911_REG_ST2 0x18\r
+#define AK09911_REG_CNTL1 0x30\r
+#define AK09911_REG_CNTL2 0x31\r
+#define AK09911_REG_CNTL3 0x32\r
+\r
+\r
+#define AK09911_FUSE_ASAX 0x60\r
+#define AK09911_FUSE_ASAY 0x61\r
+#define AK09911_FUSE_ASAZ 0x62\r
+\r
+#define AK09911_INFO_SIZE 2\r
+#define AK09911_CONF_SIZE 3\r
+\r
+\r
+\r
+#define COMPASS_IOCTL_MAGIC 'c'\r
+\r
+/* IOCTLs for AKM library */\r
+#define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)\r
+#define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)\r
+#define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */\r
+#define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)\r
+#define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8])\r
+#define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])\r
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)\r
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)\r
+#define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)\r
+#define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])\r
+#define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)\r
+#define ECS_IOCTL_GET_INFO _IOR(COMPASS_IOCTL_MAGIC, 0x0C, short)\r
+#define ECS_IOCTL_GET_CONF _IOR(COMPASS_IOCTL_MAGIC, 0x0D, short)\r
+#define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)\r
+#define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)\r
+\r
+\r
+\r
+#define AK09911_DEVICE_ID 0x05\r
+static struct i2c_client *this_client;\r
+static struct miscdevice compass_dev_device;\r
+\r
+static short g_akm_rbuf[12];\r
+static char g_sensor_info[AK09911_INFO_SIZE];\r
+static char g_sensor_conf[AK09911_CONF_SIZE];\r
+\r
+\r
+/****************operate according to sensor chip:start************/\r
+\r
+static int sensor_active(struct i2c_client *client, int enable, int rate)\r
+{\r
+ struct sensor_private_data *sensor =\r
+ (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ int result = 0;\r
+ \r
+ //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
+ \r
+ //register setting according to chip datasheet \r
+ if(enable)\r
+ { \r
+ sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE; \r
+ }\r
+ else\r
+ {\r
+ sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN;\r
+ }\r
+\r
+ DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
+ if(result)\r
+ printk("%s:fail to active sensor\n",__func__);\r
+ \r
+ return result;\r
+\r
+}\r
+\r
+static int sensor_init(struct i2c_client *client)\r
+{ \r
+ struct sensor_private_data *sensor =\r
+ (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ int result = 0;\r
+\r
+ this_client = client; \r
+\r
+ result = sensor->ops->active(client,0,0);\r
+ if(result)\r
+ {\r
+ printk("%s:line=%d,error\n",__func__,__LINE__);\r
+ return result;\r
+ }\r
+ \r
+ sensor->status_cur = SENSOR_OFF;\r
+\r
+ result = misc_register(&compass_dev_device);\r
+ if (result < 0) {\r
+ printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
+ result = -1;\r
+ }\r
+\r
+ g_sensor_info[0] = AK09911_REG_WIA1;\r
+ result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE);\r
+ if(result)\r
+ {\r
+ printk("%s:line=%d,error\n",__func__,__LINE__);\r
+ return result;\r
+ }\r
+\r
+ \r
+ g_sensor_conf[0] = AK09911_FUSE_ASAX;\r
+ result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE);\r
+ if(result)\r
+ {\r
+ printk("%s:line=%d,error\n",__func__,__LINE__);\r
+ return result;\r
+ }\r
+ \r
+ DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
+ return result;\r
+}\r
+\r
+static int sensor_report_value(struct i2c_client *client)\r
+{\r
+ struct sensor_private_data *sensor =\r
+ (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ char buffer[SENSOR_DATA_SIZE] = {0}; \r
+ unsigned char *stat;\r
+ unsigned char *stat2; \r
+ int ret = 0; \r
+ char value = 0;\r
+ int i;\r
+\r
+ if(sensor->ops->read_len < SENSOR_DATA_SIZE) //sensor->ops->read_len = 8\r
+ {\r
+ printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
+ return -1;\r
+ }\r
+ \r
+ memset(buffer, 0, SENSOR_DATA_SIZE);\r
+ \r
+ /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ \r
+ do {\r
+ *buffer = sensor->ops->read_reg;\r
+ ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
+ if (ret < 0)\r
+ return ret;\r
+ } while (0);\r
+\r
+ stat = &buffer[0];\r
+ stat2 = &buffer[7];\r
+ \r
+ /*\r
+ * ST : data ready -
+ * Measurement has been completed and data is ready to be read.
+ */\r
+ if ((*stat & 0x01) != 0x01) {\r
+ DBG(KERN_ERR "%s:ST is not set\n",__func__);\r
+ return -1;\r
+ }\r
+#if 0\r
+ /*
+ * 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)\r
+ {\r
+ DBG(KERN_ERR "%s:compass data error\n",__func__);\r
+ return -2;\r
+ }\r
+ \r
+ /*
+ * 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)\r
+ { \r
+ DBG(KERN_ERR "%s:compass data overflow\n",__func__);\r
+ return -3;\r
+ }\r
+#endif\r
+ /* »¥³âµØ»º´æÊý¾Ý. */\r
+ mutex_lock(&sensor->data_mutex); \r
+ memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
+ mutex_unlock(&sensor->data_mutex);\r
+ DBG("%s:",__func__);\r
+ for(i=0; i<sensor->ops->read_len; i++)\r
+ DBG("0x%x,",buffer[i]);\r
+ DBG("\n");\r
+\r
+ if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
+ {\r
+ \r
+ value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
+ DBG("%s:sensor int status :0x%x\n",__func__,value);\r
+ }\r
+\r
+ \r
+ //trigger next measurement \r
+ ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
+ if(ret)\r
+ {\r
+ printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);\r
+ return ret;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+static void compass_set_YPR(int *rbuf)\r
+{\r
+ struct sensor_private_data *sensor =\r
+ (struct sensor_private_data *) i2c_get_clientdata(this_client); \r
+\r
+ /* No events are reported */\r
+ if (!rbuf[0]) {\r
+ printk("%s:Don't waste a time.",__func__);\r
+ return;\r
+ }\r
+\r
+ DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);\r
+ \r
+ /* Report magnetic sensor information */\r
+ if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) {\r
+ input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]);\r
+ input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]);\r
+ input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]);\r
+ input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);\r
+ DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11], rbuf[4]);\r
+ }\r
+ \r
+ /* Report acceleration sensor information */\r
+ if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {\r
+ input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);\r
+ input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);\r
+ input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);\r
+ input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);\r
+ \r
+ DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);\r
+ }\r
+ \r
+ /* Report magnetic vector information */\r
+ if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) {\r
+ input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]);\r
+ input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]);\r
+ input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]); \r
+ input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]);\r
+ \r
+ DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]);\r
+ }\r
+ \r
+ input_sync(sensor->input_dev);\r
+\r
+ memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL\r
+}\r
+\r
+\r
+\r
+static int compass_dev_open(struct inode *inode, struct file *file)\r
+{\r
+ struct sensor_private_data* sensor = \r
+ (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+ int result = 0;\r
+ DBG("%s\n",__func__);\r
+\r
+ return result;\r
+}\r
+\r
+\r
+static int compass_dev_release(struct inode *inode, struct file *file)\r
+{\r
+ struct sensor_private_data* sensor = \r
+ (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+ int result = 0; \r
+ DBG("%s\n",__func__);\r
+\r
+ return result;\r
+}\r
+\r
+static int compass_akm_set_mode(struct i2c_client *client, char mode)\r
+{\r
+ struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+ int result = 0; \r
+\r
+ switch(mode & 0x1f)\r
+ {\r
+ case AK09911_MODE_SNG_MEASURE:\r
+ case AK09911_MODE_SELF_TEST: \r
+ case AK09911_MODE_FUSE_ACCESS: \r
+ if(sensor->status_cur == SENSOR_OFF)\r
+ {\r
+ if(sensor->pdata->irq_enable)\r
+ {\r
+ //DBG("%s:enable irq=%d\n",__func__,client->irq);\r
+ //enable_irq(client->irq);\r
+ } \r
+ else\r
+ {\r
+ schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
+ }\r
+ \r
+ sensor->status_cur = SENSOR_ON;\r
+ }\r
+\r
+ break;\r
+\r
+ case AK09911_MODE_POWERDOWN: \r
+ if(sensor->status_cur == SENSOR_ON)\r
+ {\r
+ if(sensor->pdata->irq_enable)\r
+ { \r
+ //DBG("%s:disable irq=%d\n",__func__,client->irq);\r
+ //disable_irq_nosync(client->irq);//disable irq\r
+ }\r
+ else\r
+ cancel_delayed_work_sync(&sensor->delaywork); \r
+\r
+ sensor->status_cur = SENSOR_OFF;\r
+ }\r
+ break;\r
+\r
+ }\r
+ \r
+ switch(mode & 0x1f)\r
+ {\r
+ case AK09911_MODE_SNG_MEASURE: \r
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);\r
+ if(result)\r
+ printk("%s:i2c error,mode=%d\n",__func__,mode); \r
+ break;\r
+ case AK09911_MODE_SELF_TEST: \r
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST);\r
+ if(result)\r
+ printk("%s:i2c error,mode=%d\n",__func__,mode);\r
+ break;\r
+ case AK09911_MODE_FUSE_ACCESS:\r
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS);\r
+ if(result)\r
+ printk("%s:i2c error,mode=%d\n",__func__,mode);\r
+ break;\r
+ case AK09911_MODE_POWERDOWN:\r
+ /* Set powerdown mode */\r
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN);\r
+ if(result)\r
+ printk("%s:i2c error,mode=%d\n",__func__,mode);\r
+ udelay(100);\r
+ break;\r
+ default:\r
+ printk("%s: Unknown mode(%d)", __func__, mode);\r
+ result = -EINVAL;\r
+ break;\r
+ }\r
+ DBG("%s:mode=0x%x\n",__func__,mode);\r
+ return result;\r
+\r
+}\r
+\r
+static int compass_akm_reset(struct i2c_client *client)\r
+{\r
+ struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+ int result = 0; \r
+ \r
+ if(sensor->pdata->reset_pin > 0)\r
+ {\r
+ gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);\r
+ udelay(10);\r
+ gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);\r
+ }\r
+ else \r
+ {\r
+ /* Set measure mode */\r
+ result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);\r
+ if(result)\r
+ printk("%s:fail to Set measure mode\n",__func__);\r
+ }\r
+ \r
+ udelay(100);\r
+ \r
+ return result;\r
+\r
+}\r
+\r
+\r
+\r
+static int compass_akm_get_openstatus(void)\r
+{ \r
+ struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+ wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));\r
+ return atomic_read(&sensor->flags.open_flag);\r
+}\r
+\r
+static int compass_akm_get_closestatus(void)\r
+{ \r
+ struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+ wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));\r
+ return atomic_read(&sensor->flags.open_flag);\r
+}\r
+\r
+\r
+/* ioctl - I/O control */\r
+static long compass_dev_ioctl(struct file *file,\r
+ unsigned int cmd, unsigned long arg)\r
+{\r
+ struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
+ struct i2c_client *client = this_client;\r
+ void __user *argp = (void __user *)arg;\r
+ int result = 0;\r
+ struct akm_platform_data compass;\r
+ \r
+ /* NOTE: In this function the size of "char" should be 1-byte. */\r
+ char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */\r
+ char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */\r
+ char mode; /* for SET_MODE*/\r
+ int value[YPR_DATA_SIZE]; /* for SET_YPR */\r
+ int status; /* for OPEN/CLOSE_STATUS */\r
+ int ret = -1; /* Return value. */\r
+ \r
+ //int8_t sensor_buf[SENSOR_DATA_SIZE]; /* for GETDATA */\r
+ //int32_t ypr_buf[YPR_DATA_SIZE]; /* for SET_YPR */\r
+ int16_t acc_buf[3]; /* for GET_ACCEL */\r
+ int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */\r
+ char layout; /* for GET_LAYOUT */\r
+ char outbit; /* for GET_OUTBIT */\r
+\r
+ switch (cmd) {\r
+ case ECS_IOCTL_WRITE:\r
+ case ECS_IOCTL_READ:\r
+ if (argp == NULL) {\r
+ return -EINVAL;\r
+ }\r
+ if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_SET_MODE:\r
+ if (argp == NULL) {\r
+ return -EINVAL;\r
+ }\r
+ if (copy_from_user(&mode, argp, sizeof(mode))) {\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_SET_YPR:\r
+ if (argp == NULL) {\r
+ return -EINVAL;\r
+ }\r
+ if (copy_from_user(&value, argp, sizeof(value))) {\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GETDATA:\r
+ case ECS_IOCTL_GET_OPEN_STATUS:\r
+ case ECS_IOCTL_GET_CLOSE_STATUS:\r
+ case ECS_IOCTL_GET_DELAY:\r
+ case ECS_IOCTL_GET_LAYOUT:\r
+ case ECS_IOCTL_GET_OUTBIT:\r
+ case ECS_IOCTL_GET_ACCEL:\r
+ case ECS_IOCTL_GET_INFO:\r
+ case ECS_IOCTL_GET_CONF:\r
+ /* Just check buffer pointer */\r
+ if (argp == NULL) {\r
+ printk("%s:invalid argument\n",__func__);\r
+ return -EINVAL;\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ switch (cmd) {\r
+ case ECS_IOCTL_WRITE:\r
+ DBG("%s:ECS_IOCTL_WRITE start\n",__func__);\r
+ mutex_lock(&sensor->operation_mutex);\r
+ if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
+ mutex_unlock(&sensor->operation_mutex);\r
+ return -EINVAL;\r
+ }\r
+ ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);\r
+ if (ret < 0) { \r
+ mutex_unlock(&sensor->operation_mutex); \r
+ printk("%s:fait to tx data\n",__func__);\r
+ return ret;\r
+ } \r
+ mutex_unlock(&sensor->operation_mutex);\r
+ break;\r
+ case ECS_IOCTL_READ: \r
+ DBG("%s:ECS_IOCTL_READ start\n",__func__);\r
+ mutex_lock(&sensor->operation_mutex);\r
+ if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) { \r
+ mutex_unlock(&sensor->operation_mutex); \r
+ printk("%s:data is error\n",__func__);\r
+ return -EINVAL;\r
+ }\r
+ ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);\r
+ if (ret < 0) { \r
+ mutex_unlock(&sensor->operation_mutex); \r
+ printk("%s:fait to rx data\n",__func__);\r
+ return ret;\r
+ } \r
+ mutex_unlock(&sensor->operation_mutex);\r
+ break;\r
+ case ECS_IOCTL_SET_MODE:\r
+ DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__); \r
+ mutex_lock(&sensor->operation_mutex);\r
+ if(sensor->ops->ctrl_data != mode)\r
+ {\r
+ ret = compass_akm_set_mode(client, mode);\r
+ if (ret < 0) {\r
+ printk("%s:fait to set mode\n",__func__); \r
+ mutex_unlock(&sensor->operation_mutex);\r
+ return ret;\r
+ }\r
+ \r
+ sensor->ops->ctrl_data = mode;\r
+ }\r
+ mutex_unlock(&sensor->operation_mutex);\r
+ break;\r
+ case ECS_IOCTL_GETDATA:\r
+ DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);\r
+ mutex_lock(&sensor->data_mutex); \r
+ memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE); //get data from buffer\r
+ mutex_unlock(&sensor->data_mutex);\r
+ break;\r
+ case ECS_IOCTL_SET_YPR: \r
+ DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);\r
+ mutex_lock(&sensor->data_mutex);\r
+ compass_set_YPR(value); \r
+ mutex_unlock(&sensor->data_mutex);\r
+ break;\r
+ case ECS_IOCTL_GET_OPEN_STATUS:\r
+ status = compass_akm_get_openstatus(); \r
+ DBG("%s:openstatus=%d\n",__func__,status);\r
+ break;\r
+ case ECS_IOCTL_GET_CLOSE_STATUS:\r
+ status = compass_akm_get_closestatus(); \r
+ DBG("%s:closestatus=%d\n",__func__,status);\r
+ break;\r
+ case ECS_IOCTL_GET_DELAY:\r
+ DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);\r
+ mutex_lock(&sensor->operation_mutex);\r
+ delay[0] = sensor->flags.delay;\r
+ delay[1] = sensor->flags.delay;\r
+ delay[2] = sensor->flags.delay;\r
+ mutex_unlock(&sensor->operation_mutex);\r
+ break;\r
+ \r
+ case ECS_IOCTL_GET_PLATFORM_DATA: \r
+ DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);\r
+ memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));\r
+ memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));\r
+ ret = copy_to_user(argp, &compass, sizeof(compass));\r
+ if(ret < 0)\r
+ {\r
+ printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
+ return ret;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GET_LAYOUT:\r
+ DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);\r
+ if((sensor->pdata->layout >= 1) && (sensor->pdata->layout <=8 ))
+ layout = sensor->pdata->layout;
+ else
+ layout = 1;
+ break;\r
+ case ECS_IOCTL_GET_OUTBIT:\r
+ DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);\r
+ outbit = 1; //sensor->pdata->outbit;\r
+ break;\r
+ case ECS_IOCTL_RESET:\r
+ DBG("%s:ECS_IOCTL_RESET start\n",__func__);\r
+ ret = compass_akm_reset(client);\r
+ if (ret < 0)\r
+ return ret;\r
+ break;\r
+ case ECS_IOCTL_GET_ACCEL:\r
+ DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);\r
+ mutex_lock(&sensor->operation_mutex);\r
+ acc_buf[0] = g_akm_rbuf[6];\r
+ acc_buf[1] = g_akm_rbuf[7];\r
+ acc_buf[2] = g_akm_rbuf[8];\r
+ mutex_unlock(&sensor->operation_mutex);\r
+ break;\r
+ case ECS_IOCTL_GET_INFO:\r
+ ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info));\r
+ if(ret < 0)\r
+ {\r
+ printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
+ return ret;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GET_CONF:\r
+ ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf));\r
+ if(ret < 0)\r
+ {\r
+ printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
+ return ret;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ return -ENOTTY;\r
+ }\r
+\r
+ switch (cmd) {\r
+ case ECS_IOCTL_READ:\r
+ if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GETDATA:\r
+ if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GET_OPEN_STATUS:\r
+ case ECS_IOCTL_GET_CLOSE_STATUS:\r
+ if (copy_to_user(argp, &status, sizeof(status))) {\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GET_DELAY:\r
+ if (copy_to_user(argp, &delay, sizeof(delay))) {\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GET_LAYOUT:\r
+ if (copy_to_user(argp, &layout, sizeof(layout))) {\r
+ printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GET_OUTBIT:\r
+ if (copy_to_user(argp, &outbit, sizeof(outbit))) {\r
+ printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ case ECS_IOCTL_GET_ACCEL:\r
+ if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {\r
+ printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
+ return -EFAULT;\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+static struct file_operations compass_dev_fops =\r
+{\r
+ .owner = THIS_MODULE,\r
+ .open = compass_dev_open,\r
+ .release = compass_dev_release, \r
+ .unlocked_ioctl = compass_dev_ioctl,\r
+};\r
+\r
+\r
+static struct miscdevice compass_dev_device =\r
+{ \r
+ .minor = MISC_DYNAMIC_MINOR,\r
+ .name = "akm_dev",\r
+ .fops = &compass_dev_fops,\r
+};\r
+\r
+struct sensor_operate compass_akm09911_ops = {\r
+ .name = "akm09911",\r
+ .type = SENSOR_TYPE_COMPASS, //it is important\r
+ .id_i2c = COMPASS_ID_AK09911,\r
+ .read_reg = AK09911_REG_ST1, //read data\r
+ .read_len = SENSOR_DATA_SIZE, //data length\r
+ .id_reg = AK09911_REG_WIA2, //read id\r
+ .id_data = AK09911_DEVICE_ID,\r
+ .precision = 8, //12 bits\r
+ .ctrl_reg = AK09911_REG_CNTL2, //enable or disable \r
+ .int_status_reg = SENSOR_UNKNOW_DATA, //not exist\r
+ .range = {-0xffff,0xffff},\r
+ .trig = IRQF_TRIGGER_RISING, //if LEVEL interrupt then IRQF_ONESHOT\r
+ .active = sensor_active, \r
+ .init = sensor_init,\r
+ .report = sensor_report_value, \r
+ .misc_dev = NULL, //private misc support\r
+};\r
+\r
+/****************operate according to sensor chip:end************/\r
+\r
+//function name should not be changed\r
+static struct sensor_operate *compass_get_ops(void)\r
+{\r
+ return &compass_akm09911_ops; \r
+}\r
+\r
+\r
+static int __init compass_akm09911_init(void)\r
+{\r
+ struct sensor_operate *ops = compass_get_ops();\r
+ int result = 0;\r
+ int type = ops->type;\r
+ result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
+ \r
+ return result;\r
+}\r
+\r
+static void __exit compass_akm09911_exit(void)\r
+{\r
+ struct sensor_operate *ops = compass_get_ops();\r
+ int type = ops->type;\r
+ sensor_unregister_slave(type, NULL, NULL, compass_get_ops);\r
+}\r
+\r
+\r
+module_init(compass_akm09911_init);\r
+module_exit(compass_akm09911_exit);\r
+\r
+\r
\r
#define SENSOR_DATA_SIZE 8\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_COMPASS\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define SENSOR_DATA_SIZE 8\r
#define YPR_DATA_SIZE 12\r
unsigned char *stat2; \r
int ret = 0; \r
char value = 0;\r
-#ifdef SENSOR_DEBUG_TYPE \r
int i;\r
-#endif \r
+\r
if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8\r
{\r
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
mutex_lock(&sensor->data_mutex); \r
memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
mutex_unlock(&sensor->data_mutex);\r
-#ifdef SENSOR_DEBUG_TYPE \r
DBG("%s:",__func__);\r
for(i=0; i<sensor->ops->read_len; i++)\r
DBG("0x%x,",buffer[i]);\r
DBG("\n");\r
-#endif \r
\r
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
{\r
\r
static int compass_dev_open(struct inode *inode, struct file *file)\r
{\r
-#ifdef SENSOR_DEBUG_TYPE\r
struct sensor_private_data* sensor = \r
(struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-#endif\r
int result = 0;\r
DBG("%s\n",__func__);\r
\r
\r
static int compass_dev_release(struct inode *inode, struct file *file)\r
{\r
-#ifdef SENSOR_DEBUG_TYPE\r
struct sensor_private_data* sensor = \r
(struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-#endif\r
int result = 0; \r
DBG("%s\n",__func__);\r
\r
\r
#define SENSOR_DATA_SIZE 8\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_COMPASS\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
/*! \name AK8975 operation mode\r
\anchor AK8975_Mode\r
unsigned char *stat2; \r
int ret = 0; \r
char value = 0;\r
-#ifdef SENSOR_DEBUG_TYPE \r
int i;\r
-#endif \r
+\r
if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8\r
{\r
printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
mutex_lock(&sensor->data_mutex); \r
memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
mutex_unlock(&sensor->data_mutex);\r
-#ifdef SENSOR_DEBUG_TYPE \r
DBG("%s:",__func__);\r
for(i=0; i<sensor->ops->read_len; i++)\r
DBG("0x%x,",buffer[i]);\r
DBG("\n");\r
-#endif \r
\r
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
{\r
\r
static int compass_dev_open(struct inode *inode, struct file *file)\r
{\r
-#ifdef SENSOR_DEBUG_TYPE\r
struct sensor_private_data* sensor = \r
(struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-#endif\r
int result = 0;\r
DBG("%s\n",__func__);\r
\r
\r
static int compass_dev_release(struct inode *inode, struct file *file)\r
{\r
-#ifdef SENSOR_DEBUG_TYPE\r
struct sensor_private_data* sensor = \r
(struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-#endif\r
int result = 0; \r
DBG("%s\n",__func__);\r
\r
#include <linux/l3g4200d.h>\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_GYROSCOPE\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define L3G4200D_ENABLE 0x08\r
\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
#include <linux/l3g4200d.h>\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_GYROSCOPE\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define L3G4200D_ENABLE 0x08\r
\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, gyro_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
bool "light sensor photoresistor"
default n
+config LS_US5152
+ bool "light sensor us5152"
+ default n
endif
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
\ No newline at end of file
+obj-$(CONFIG_LS_PHOTORESISTOR) += ls_photoresistor.o
+obj-$(CONFIG_LS_US5152) += ls_us5152.o
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define CM3217_ADDR_COM1 0x10\r
#define CM3217_ADDR_COM2 0x11\r
}\r
\r
\r
-static void light_report_value(struct input_dev *input, int data)\r
+static int light_report_value(struct input_dev *input, int data)\r
{\r
unsigned char index = 0;\r
+ \r
if(data <= 10){\r
index = 0;goto report;\r
}\r
}\r
\r
report:\r
- DBG("cm3217 report data=%d,index = %d\n",data,index);\r
input_report_abs(input, ABS_MISC, index);\r
input_sync(input);\r
+\r
+ return index;\r
}\r
\r
\r
(struct sensor_private_data *) i2c_get_clientdata(client); \r
int result = 0;\r
char msb = 0, lsb = 0;\r
+ int index = 0;\r
\r
sensor->client->addr = CM3217_ADDR_DATA_LSB;\r
sensor_rx_data_normal(sensor->client, &lsb, 1);\r
sensor_rx_data_normal(sensor->client, &msb, 1);\r
result = ((msb << 8) | lsb) & 0xffff;\r
\r
- DBG("%s:result=%d\n",__func__,result);\r
- light_report_value(sensor->input_dev, result);\r
-\r
+ index = light_report_value(sensor->input_dev, result);\r
+ DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, result,index);\r
+ \r
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
{\r
\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- printk("%s\n",__func__);\r
return result;\r
}\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define CM3232_CLOSE 0x01\r
\r
struct sensor_private_data *sensor =\r
(struct sensor_private_data *) i2c_get_clientdata(client); \r
int result = 0;\r
- int status = 0;\r
+ //int status = 0;\r
\r
//sensor->client->addr = sensor->ops->ctrl_reg; \r
//sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
}\r
\r
\r
-static void light_report_value(struct input_dev *input, int data)\r
+static int light_report_value(struct input_dev *input, int data)\r
{\r
unsigned char index = 0;\r
+ \r
if(data <= 10){\r
index = 0;goto report;\r
}\r
}\r
\r
report:\r
- DBG("cm3232 report data=%d,index = %d\n",data,index);\r
- printk("cm3232 report data=%d,index = %d\n",data,index);\r
input_report_abs(input, ABS_MISC, index);\r
input_sync(input);\r
+ \r
+ return index;\r
}\r
\r
\r
struct sensor_private_data *sensor =\r
(struct sensor_private_data *) i2c_get_clientdata(client); \r
int result = 0;\r
- char msb = 0, lsb = 0;\r
+ //char msb = 0, lsb = 0;\r
char data[2] = {0};\r
unsigned short value = 0;\r
+ int index = 0;\r
\r
//sensor->client->addr = CM3232_ADDR_DATA;\r
data[0] = CM3232_ADDR_DATA;\r
\r
DBG("%s:result=%d\n",__func__,value);\r
//printk("%s:result=%d\n",__func__,value);\r
- light_report_value(sensor->input_dev, value);\r
+ index = light_report_value(sensor->input_dev, value); \r
+ DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
\r
if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register\r
{\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- //printk("%s: >>>>>>>>>>>>>>>>>>>\n\n\n",__func__);\r
return result;\r
}\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define ISL29023_REG_ADD_COMMAND1 0x00\r
#define COMMMAND1_OPMODE_SHIFT 5\r
struct sensor_private_data *sensor =\r
(struct sensor_private_data *) i2c_get_clientdata(client); \r
int result = 0;\r
- int status = 0;\r
+ //int status = 0;\r
\r
sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
\r
return result;\r
}\r
\r
-struct sensor_operate light_stk3171_ops = {\r
+struct sensor_operate light_isl29023_ops = {\r
.name = "ls_isl29023",\r
.type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
.id_i2c = LIGHT_ID_ISL29023, //i2c id number\r
//function name should not be changed\r
static struct sensor_operate *light_get_ops(void)\r
{\r
- return &light_stk3171_ops;\r
+ return &light_isl29023_ops;\r
}\r
\r
\r
-static int __init light_stk3171_init(void)\r
+static int __init light_isl29023_init(void)\r
{\r
struct sensor_operate *ops = light_get_ops();\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- //printk("%s\n",__func__);\r
return result;\r
}\r
\r
-static void __exit light_stk3171_exit(void)\r
+static void __exit light_isl29023_exit(void)\r
{\r
struct sensor_operate *ops = light_get_ops();\r
int type = ops->type;\r
}\r
\r
\r
-module_init(light_stk3171_init);\r
-module_exit(light_stk3171_exit);\r
+module_init(light_isl29023_init);\r
+module_exit(light_isl29023_exit);\r
\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define CONFIG_REG (0x00)\r
#define TIM_CTL_REG (0x01)\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define AP3212B_NUM_CACHABLE_REGS 23
#define AP3216C_NUM_CACHABLE_REGS 26\r
if ( mid == 0x01 && pid == 0x01 &&
(rid == 0x03 || rid == 0x04) )
{
- DBG("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);\r
+ //printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);\r
}\r
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);\r
+ //printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);\r
}\r
else
{
- DBG("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);\r
+ //printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);\r
return -EIO;
}
\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
#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 ;
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
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)
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 ;
}
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) ){
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,
.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************/
int result = 0;
int type = ops->type;
result = sensor_register_slave(type, NULL, NULL, light_get_ops);
- DBG("%s\n",__func__);
return result;
}
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_LIGHT\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define ALS_CMD 0x01\r
#define ALS_DT1 0x02\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
--- /dev/null
+#include <linux/interrupt.h>\r
+#include <linux/i2c.h>\r
+#include <linux/slab.h>\r
+#include <linux/irq.h>\r
+#include <linux/miscdevice.h>\r
+#include <linux/gpio.h>\r
+#include <asm/uaccess.h>\r
+#include <asm/atomic.h>\r
+#include <linux/delay.h>\r
+#include <linux/input.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/freezer.h>\r
+#include <mach/gpio.h>\r
+#include <mach/board.h> \r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+#include <linux/earlysuspend.h>\r
+#endif\r
+#include <linux/sensor-dev.h>\r
+#include <linux/types.h>\r
+\r
+\r
+#define DRIVER_VERSION "1.0"\r
+\r
+#define PWR_MODE_DOWN_MASK 0x80\r
+#define PWR_MODE_OPERATE_MASK 0x7F\r
+\r
+\r
+/*us5152 Slave Addr*/\r
+#define LIGHT_ADDR 0x72 \r
+\r
+/*Interrupt PIN for S3C6410*/\r
+#define IRQ_LIGHT_INT IRQ_EINT(6)\r
+\r
+/*Register Set*/\r
+#define REGS_CR0 0x00\r
+#define REGS_CR1 0x01\r
+#define REGS_CR2 0x02\r
+#define REGS_CR3 0x03\r
+//ALS\r
+#define REGS_INT_LSB_TH_LO 0x04\r
+#define REGS_INT_MSB_TH_LO 0x05\r
+#define REGS_INT_LSB_TH_HI 0x06\r
+#define REGS_INT_MSB_TH_HI 0x07\r
+//ALS data\r
+#define REGS_LBS_SENSOR 0x0C\r
+#define REGS_MBS_SENSOR 0x0D\r
+\r
+#define REGS_CR10 0x10\r
+#define REGS_CR11 0x11\r
+#define REGS_VERSION_ID 0x1F\r
+#define REGS_CHIP_ID 0xB2\r
+\r
+/*ShutDown_EN*/\r
+#define CR0_OPERATION 0x0\r
+#define CR0_SHUTDOWN_EN 0x1\r
+\r
+#define CR0_SHUTDOWN_SHIFT (7)\r
+#define CR0_SHUTDOWN_MASK (0x1 << CR0_SHUTDOWN_SHIFT)\r
+\r
+/*OneShot_EN*/\r
+#define CR0_ONESHOT_EN 0x01\r
+\r
+#define CR0_ONESHOT_SHIFT (6)\r
+#define CR0_ONESHOT_MASK (0x1 << CR0_ONESHOT_SHIFT)\r
+\r
+/*Operation Mode*/\r
+#define CR0_OPMODE_ALSANDPS 0x0 \r
+#define CR0_OPMODE_ALSONLY 0x1 \r
+#define CR0_OPMODE_IRONLY 0x2 \r
+\r
+#define CR0_OPMODE_SHIFT (4)\r
+#define CR0_OPMODE_MASK (0x3 << CR0_OPMODE_SHIFT)\r
+\r
+/*all int flag (PROX, INT_A, INT_P)*/\r
+#define CR0_ALL_INT_CLEAR 0x0\r
+\r
+#define CR0_ALL_INT_SHIFT (1)\r
+#define CR0_ALL_INT_MASK (0x7 << CR0_ALL_INT_SHIFT)\r
+\r
+\r
+/*indicator of object proximity detection*/\r
+#define CR0_PROX_CLEAR 0x0\r
+\r
+#define CR0_PROX_SHIFT (3)\r
+#define CR0_PROX_MASK (0x1 << CR0_PROX_SHIFT)\r
+\r
+/*interrupt status of proximity sensor*/\r
+#define CR0_INTP_CLEAR 0x0\r
+\r
+#define CR0_INTP_SHIFT (2)\r
+#define CR0_INTP_MASK (0x1 << CR0_INTP_SHIFT)\r
+\r
+/*interrupt status of ambient sensor*/\r
+#define CR0_INTA_CLEAR 0x0\r
+\r
+#define CR0_INTA_SHIFT (1)\r
+#define CR0_INTA_MASK (0x1 << CR0_INTA_SHIFT)\r
+\r
+/*Word mode enable*/\r
+#define CR0_WORD_EN 0x1\r
+\r
+#define CR0_WORD_SHIFT (0)\r
+#define CR0_WORD_MASK (0x1 << CR0_WORD_SHIFT)\r
+\r
+\r
+/*ALS fault queue depth for interrupt enent output*/\r
+#define CR1_ALS_FQ_1 0x0 \r
+#define CR1_ALS_FQ_4 0x1 \r
+#define CR1_ALS_FQ_8 0x2\r
+#define CR1_ALS_FQ_16 0x3\r
+#define CR1_ALS_FQ_24 0x4\r
+#define CR1_ALS_FQ_32 0x5\r
+#define CR1_ALS_FQ_48 0x6\r
+#define CR1_ALS_FQ_63 0x7\r
+\r
+#define CR1_ALS_FQ_SHIFT (5)\r
+#define CR1_ALS_FQ_MASK (0x7 << CR1_ALS_FQ_SHIFT)\r
+\r
+/*resolution for ALS*/\r
+#define CR1_ALS_RES_12BIT 0x0 \r
+#define CR1_ALS_RES_14BIT 0x1 \r
+#define CR1_ALS_RES_16BIT 0x2\r
+#define CR1_ALS_RES_16BIT_2 0x3\r
+\r
+#define CR1_ALS_RES_SHIFT (3)\r
+#define CR1_ALS_RES_MASK (0x3 << CR1_ALS_RES_SHIFT)\r
+\r
+/*sensing amplifier selection for ALS*/\r
+#define CR1_ALS_GAIN_X1 0x0 \r
+#define CR1_ALS_GAIN_X2 0x1 \r
+#define CR1_ALS_GAIN_X4 0x2\r
+#define CR1_ALS_GAIN_X8 0x3\r
+#define CR1_ALS_GAIN_X16 0x4\r
+#define CR1_ALS_GAIN_X32 0x5\r
+#define CR1_ALS_GAIN_X64 0x6\r
+#define CR1_ALS_GAIN_X128 0x7\r
+\r
+#define CR1_ALS_GAIN_SHIFT (0)\r
+#define CR1_ALS_GAIN_MASK (0x7 << CR1_ALS_GAIN_SHIFT)\r
+\r
+\r
+/*PS fault queue depth for interrupt event output*/\r
+#define CR2_PS_FQ_1 0x0 \r
+#define CR2_PS_FQ_4 0x1 \r
+#define CR2_PS_FQ_8 0x2\r
+#define CR2_PS_FQ_15 0x3\r
+\r
+#define CR2_PS_FQ_SHIFT (6)\r
+#define CR2_PS_FQ_MASK (0x3 << CR2_PS_FQ_SHIFT)\r
+\r
+/*interrupt type setting */\r
+/*low active*/\r
+#define CR2_INT_LEVEL 0x0 \r
+/*low pulse*/\r
+#define CR2_INT_PULSE 0x1 \r
+\r
+#define CR2_INT_SHIFT (5)\r
+#define CR2_INT_MASK (0x1 << CR2_INT_SHIFT)\r
+\r
+/*resolution for PS*/\r
+#define CR2_PS_RES_12 0x0 \r
+#define CR2_PS_RES_14 0x1 \r
+#define CR2_PS_RES_16 0x2\r
+#define CR2_PS_RES_16_2 0x3\r
+\r
+#define CR2_PS_RES_SHIFT (3)\r
+#define CR2_PS_RES_MASK (0x3 << CR2_PS_RES_SHIFT)\r
+\r
+/*sensing amplifier selection for PS*/\r
+#define CR2_PS_GAIN_1 0x0 \r
+#define CR2_PS_GAIN_2 0x1 \r
+#define CR2_PS_GAIN_4 0x2\r
+#define CR2_PS_GAIN_8 0x3\r
+#define CR2_PS_GAIN_16 0x4\r
+#define CR2_PS_GAIN_32 0x5\r
+#define CR2_PS_GAIN_64 0x6\r
+#define CR2_PS_GAIN_128 0x7\r
+\r
+#define CR2_PS_GAIN_SHIFT (0)\r
+#define CR2_PS_GAIN_MASK (0x7 << CR2_PS_GAIN_SHIFT)\r
+\r
+/*wait-time slot selection*/\r
+#define CR3_WAIT_SEL_0 0x0 \r
+#define CR3_WAIT_SEL_4 0x1 \r
+#define CR3_WAIT_SEL_8 0x2\r
+#define CR3_WAIT_SEL_16 0x3\r
+\r
+#define CR3_WAIT_SEL_SHIFT (6)\r
+#define CR3_WAIT_SEL_MASK (0x3 << CR3_WAIT_SEL_SHIFT)\r
+\r
+/*IR-LED drive peak current setting*/\r
+#define CR3_LEDDR_12_5 0x0 \r
+#define CR3_LEDDR_25 0x1 \r
+#define CR3_LEDDR_50 0x2\r
+#define CR3_LEDDR_100 0x3\r
+\r
+#define CR3_LEDDR_SHIFT (4)\r
+#define CR3_LEDDR_MASK (0x3 << CR3_LEDDR_SHIFT)\r
+\r
+/*INT pin source selection*/\r
+#define CR3_INT_SEL_BATH 0x0 \r
+#define CR3_INT_SEL_ALS 0x1 \r
+#define CR3_INT_SEL_PS 0x2\r
+#define CR3_INT_SEL_PSAPP 0x3\r
+\r
+#define CR3_INT_SEL_SHIFT (2)\r
+#define CR3_INT_SEL_MASK (0x3 << CR3_INT_SEL_SHIFT)\r
+\r
+/*software reset for register and core*/\r
+#define CR3_SOFTRST_EN 0x1\r
+\r
+#define CR3_SOFTRST_SHIFT (0)\r
+#define CR3_SOFTRST_MASK (0x1 << CR3_SOFTRST_SHIFT)\r
+\r
+/*modulation frequency of LED driver*/\r
+#define CR10_FREQ_DIV2 0x0 \r
+#define CR10_FREQ_DIV4 0x1 \r
+#define CR10_FREQ_DIV8 0x2\r
+#define CR10_FREQ_DIV16 0x3\r
+\r
+#define CR10_FREQ_SHIFT (1)\r
+#define CR10_FREQ_MASK (0x3 << CR10_FREQ_SHIFT)\r
+\r
+/*50/60 Rejection enable*/\r
+#define CR10_REJ_5060_DIS 0x00\r
+#define CR10_REJ_5060_EN 0x01\r
+\r
+#define CR10_REJ_5060_SHIFT (0)\r
+#define CR10_REJ_5060_MASK (0x1 << CR10_REJ_5060_SHIFT)\r
+\r
+#define us5152_NUM_CACHABLE_REGS 0x12\r
+\r
+\r
+static int sensor_active(struct i2c_client *client, int enable, int rate)\r
+{\r
+ //struct sensor_private_data *sensor =\r
+ // (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ int result = 0;\r
+ char value = 0;\r
+ int i = 0;\r
+ \r
+ for(i=0; i<3; i++)\r
+ {\r
+ if(!enable)\r
+ { \r
+ value = sensor_read_reg(client, REGS_CR0);\r
+ value |= PWR_MODE_DOWN_MASK; //ShutDown_EN=1\r
+ result = sensor_write_reg(client, REGS_CR0, value);\r
+ if(result)\r
+ return result;\r
+ }\r
+ else\r
+ { \r
+ value = sensor_read_reg(client, REGS_CR0);\r
+ value &= PWR_MODE_OPERATE_MASK ; //Operation_EN=0\r
+ result = sensor_write_reg(client, REGS_CR0, value);\r
+ if(result)\r
+ return result;\r
+ }\r
+ \r
+ if(!result)\r
+ break;\r
+ }\r
+ \r
+ if(i>1)\r
+ printk("%s:set %d times",__func__,i);\r
+\r
+ \r
+ //TODO:? function to be added here\r
+\r
+ return result;\r
+\r
+}\r
+\r
+\r
+static int sensor_init(struct i2c_client *client)\r
+{ \r
+ struct sensor_private_data *sensor =\r
+ (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ int result = 0;\r
+ char value = 0;\r
+ \r
+ result = sensor->ops->active(client,0,0);\r
+ if(result)\r
+ {\r
+ printk("%s:line=%d,error\n",__func__,__LINE__);\r
+ return result;\r
+ }\r
+ \r
+ sensor->status_cur = SENSOR_OFF;\r
+\r
+ value = sensor_read_reg(client, REGS_CHIP_ID); //read chip ids\r
+ printk("us5152 chip id is %x!\n", value);\r
+\r
+ value = 0x01;//word accessing\r
+ \r
+ result = sensor_write_reg(client, REGS_CR0, value);\r
+ if(result)\r
+ {\r
+ printk("%s:line=%d,error\n",__func__,__LINE__);\r
+ return result;\r
+ }\r
+ \r
+ return result;\r
+}\r
+\r
+\r
+static int us5152_value_report(struct input_dev *input, int data)\r
+{\r
+ unsigned char index = 0;\r
+ if(data <= 10){\r
+ index = 0;goto report;\r
+ }\r
+ else if(data <= 160){\r
+ index = 1;goto report;\r
+ }\r
+ else if(data <= 225){\r
+ index = 2;goto report;\r
+ }\r
+ else if(data <= 320){\r
+ index = 3;goto report;\r
+ }\r
+ else if(data <= 640){\r
+ index = 4;goto report;\r
+ }\r
+ else if(data <= 1280){\r
+ index = 5;goto report;\r
+ }\r
+ else if(data <= 2600){\r
+ index = 6;goto report;\r
+ }\r
+ else{\r
+ index = 7;goto report;\r
+ }\r
+\r
+report:\r
+ input_report_abs(input, ABS_MISC, index);\r
+ input_sync(input);\r
+ return index;\r
+}\r
+\r
+static int sensor_report_value(struct i2c_client *client)\r
+{\r
+ struct sensor_private_data *sensor =\r
+ (struct sensor_private_data *) i2c_get_clientdata(client); \r
+ int result = 0;\r
+ int value = 0;\r
+ char index = 0;\r
+ char buffer[2]= { 0 } ;\r
+ int ret=0;\r
+ \r
+ if(sensor->pdata->irq_enable)\r
+ {\r
+ if(sensor->ops->int_status_reg >= 0)\r
+ {\r
+ value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
+ }\r
+ \r
+ }\r
+ \r
+ //value = sensor_read_reg(client, sensor->ops->read_reg); //TODO:? to be changed\r
+ if(sensor->ops->read_len< 2) //12bit\r
+ {\r
+ printk("us5152 data read para num error ; len = %d\n ",sensor->ops->read_len);\r
+ return -1;\r
+ }\r
+ memset(buffer , 0 , 2);\r
+ do\r
+ {\r
+ *buffer = sensor->ops->read_reg;\r
+ ret=sensor_rx_data(client,buffer,sensor->ops->read_len);\r
+ if(ret<0)\r
+ return ret;\r
+ }\r
+ while(0);\r
+ value=buffer[1];\r
+ value =((value << 8) | buffer[0]) & 0xffff;\r
+ index = us5152_value_report(sensor->input_dev, value); //now is 12bit \r
+ \r
+ //printk("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);\r
+ DBG("%s:%s result=%d,index=%d buffer[1]=0x%x , buffer[0]=0x%x \n",__func__,sensor->ops->name, value,index,buffer[1],buffer[0]);\r
+ \r
+ return result;\r
+}\r
+\r
+\r
+struct sensor_operate light_us5152_ops = {\r
+ .name = "ls_us5152",\r
+ .type = SENSOR_TYPE_LIGHT, //sensor type and it should be correct\r
+ .id_i2c = LIGHT_ID_US5152, //i2c id number\r
+ .read_reg = REGS_LBS_SENSOR, //read data\r
+ .read_len = 2, //data length\r
+ .id_reg = REGS_CHIP_ID, //read device id from this register\r
+ .id_data = 0x26, //device id\r
+ .precision = 12, //12 bits\r
+ .ctrl_reg = REGS_CR0, //enable or disable \r
+ .int_status_reg = SENSOR_UNKNOW_DATA, //intterupt status register\r
+ .range = {0,10}, //range\r
+ .brightness = {10,4095}, // brightness\r
+ .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT , \r
+ .active = sensor_active, \r
+ .init = sensor_init,\r
+ .report = sensor_report_value,\r
+};\r
+/****************operate according to sensor chip:end************/\r
+\r
+//function name should not be changed\r
+static struct sensor_operate *light_get_ops(void)\r
+{\r
+ return &light_us5152_ops;\r
+}\r
+\r
+\r
+static int __init us5152_init(void)\r
+{\r
+ struct sensor_operate *ops = light_get_ops();\r
+ int result = 0;\r
+ int type = ops->type;\r
+ result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
+\r
+ return result;\r
+}\r
+\r
+static void __exit us5152_exit(void)\r
+{\r
+ struct sensor_operate *ops = light_get_ops();\r
+ int type = ops->type;\r
+ sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
+}\r
+\r
+MODULE_AUTHOR("Finley Huang finley_huang@upi-semi.com");\r
+MODULE_DESCRIPTION("us5152 ambient light sensor driver");\r
+MODULE_LICENSE("GPL");\r
+MODULE_VERSION(DRIVER_VERSION);\r
+\r
+module_init(us5152_init);\r
+module_exit(us5152_exit);\r
+\r
--- /dev/null
+/*
+ * 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
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PRESSURE\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define CMD_RESET 0x1E // ADC reset command \r
#define CMD_ADC_READ 0x00 // ADC read command \r
for (i=0;i<8;i++) \r
{\r
C[i] = prom[2*i] << 8 | prom[2*i + 1];\r
- DBG("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);\r
- DBG("\nC[%d]=%d,",i+1,C[i]);\r
+ //printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);\r
+ //printk("\nC[%d]=%d,",i+1,C[i]);\r
} \r
\r
}\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, pressure_get_ops);\r
- printk("%s\n",__func__);\r
return result;\r
}\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PROXIMITY\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define CONFIG_REG (0x00)\r
#define TIM_CTL_REG (0x01)\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PROXIMITY\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define AP3212B_NUM_CACHABLE_REGS 23
#define AP3216C_NUM_CACHABLE_REGS 26\r
if ( mid == 0x01 && pid == 0x01 &&
(rid == 0x03 || rid == 0x04) )
{
- DBG("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);\r
+ //printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);\r
}
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);\r
+ //printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);\r
}
else
{
- DBG("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);\r
+ printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);\r
return -EIO;
}
\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_PROXIMITY\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define ALS_CMD 0x01\r
#define ALS_DT1 0x02\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, proximity_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
#include <linux/input.h>\r
#include <linux/workqueue.h>\r
#include <linux/freezer.h>\r
+#include <linux/proc_fs.h>\r
#include <mach/gpio.h>\r
#include <mach/board.h> \r
#ifdef CONFIG_HAS_EARLYSUSPEND\r
#include <linux/sensor-dev.h>\r
\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
-\r
-#if 0\r
+/*\r
sensor-dev.c v1.1 add pressure and temperature support 2013-2-27\r
sensor-dev.c v1.2 add akm8963 support 2013-3-10\r
-#endif\r
-#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.2 add akm8963 support 2013-3-10"\r
+sensor-dev.c v1.3 add sensor debug support 2013-3-15\r
+*/\r
+\r
+#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.3 add sensor debug support 2013-3-15"\r
\r
\r
struct sensor_private_data *g_sensor[SENSOR_NUM_TYPES];\r
static struct sensor_operate *sensor_ops[SENSOR_NUM_ID]; \r
static struct class *g_sensor_class[SENSOR_NUM_TYPES];\r
\r
+static ssize_t sensor_proc_write(struct file *file, const char __user *buffer,\r
+ size_t count, loff_t *data)\r
+{\r
+ char c;\r
+ int rc;\r
+ int i = 0, num = 0;\r
+ \r
+ rc = get_user(c, buffer);\r
+ if (rc)\r
+ {\r
+ for(i=SENSOR_TYPE_NULL+1; i<SENSOR_NUM_TYPES; i++)\r
+ atomic_set(&g_sensor[i]->flags.debug_flag, SENSOR_TYPE_NULL);\r
+ return rc; \r
+ }\r
+\r
+ \r
+ num = c - '0';\r
+\r
+ printk("%s command list:close:%d, accel:%d, compass:%d, gyro:%d, light:%d, psensor:%d, temp:%d, pressure:%d,total:%d,num=%d\n",__func__,\r
+ \r
+ SENSOR_TYPE_NULL, SENSOR_TYPE_ACCEL,SENSOR_TYPE_COMPASS,SENSOR_TYPE_GYROSCOPE,SENSOR_TYPE_LIGHT,SENSOR_TYPE_PROXIMITY,\r
+\r
+ SENSOR_TYPE_TEMPERATURE,SENSOR_TYPE_PRESSURE,SENSOR_NUM_TYPES,num);\r
+\r
+ if((num > SENSOR_NUM_TYPES) || (num < SENSOR_TYPE_NULL))\r
+ {\r
+ printk("%s:error! only support %d to %d\n",__func__, SENSOR_TYPE_NULL,SENSOR_NUM_TYPES);\r
+ return -1;\r
+ }\r
+\r
+ for(i=SENSOR_TYPE_NULL+1; i<SENSOR_NUM_TYPES; i++)\r
+ {\r
+ if(g_sensor[i])\r
+ atomic_set(&g_sensor[i]->flags.debug_flag, num);\r
+ }\r
+ \r
+ return count; \r
+}\r
+\r
+static const struct file_operations sensor_proc_fops = {\r
+ .owner = THIS_MODULE, \r
+ .write = sensor_proc_write,\r
+};\r
+\r
+\r
\r
static int sensor_get_id(struct i2c_client *client, int *value)\r
{\r
unsigned int cmd, unsigned long arg)\r
{\r
struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
- struct i2c_client *client = sensor->client;\r
+ //struct i2c_client *client = sensor->client;\r
void __user *argp = (void __user *)arg;\r
int result = 0;\r
short flag;\r
struct sensor_platform_data *pdata;\r
int result = 0;\r
int type = 0;\r
+ \r
dev_info(&client->adapter->dev, "%s: %s,0x%x\n", __func__, devid->name,(unsigned int)client);\r
\r
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {\r
atomic_set(&sensor->flags.m_flag, 1);\r
atomic_set(&sensor->flags.a_flag, 1);\r
atomic_set(&sensor->flags.mv_flag, 1); \r
- atomic_set(&sensor->flags.open_flag, 0); \r
+ atomic_set(&sensor->flags.open_flag, 0);\r
+ atomic_set(&sensor->flags.debug_flag, 0);\r
init_waitqueue_head(&sensor->flags.open_wq);\r
sensor->flags.delay = 100;\r
\r
"fail to register misc device %s\n", sensor->i2c_id->name);\r
goto out_misc_device_register_device_failed;\r
}\r
- }\r
+ } \r
\r
#ifdef CONFIG_HAS_EARLYSUSPEND\r
if((sensor->ops->suspend) && (sensor->ops->resume))\r
/*gsensor*/\r
{"gsensor", ACCEL_ID_ALL},\r
{"gs_mma8452", ACCEL_ID_MMA845X}, \r
- {"gs_kxtik", ACCEL_ID_KXTIK},\r
+ {"gs_kxtik", ACCEL_ID_KXTIK}, \r
+ {"gs_kxtj9", ACCEL_ID_KXTJ9},\r
{"gs_lis3dh", ACCEL_ID_LIS3DH},\r
{"gs_mma7660", ACCEL_ID_MMA7660},\r
{"gs_mxc6225", ACCEL_ID_MXC6225},\r
{"compass", COMPASS_ID_ALL},\r
{"ak8975", COMPASS_ID_AK8975}, \r
{"ak8963", COMPASS_ID_AK8963},\r
+ {"ak09911", COMPASS_ID_AK09911},\r
{"mmc314x", COMPASS_ID_MMC314X},\r
/*gyroscope*/\r
{"gyro", GYRO_ID_ALL}, \r
{"l3g4200d_gryo", GYRO_ID_L3G4200D},\r
- {"l3g20d_gryo", GYRO_ID_L3G20D},\r
+ {"l3g20d_gryo", GYRO_ID_L3G20D},\r
{"k3g", GYRO_ID_K3G},\r
/*light sensor*/\r
{"lightsensor", LIGHT_ID_ALL}, \r
{"ls_isl29023", LIGHT_ID_ISL29023},\r
{"ls_ap321xx", LIGHT_ID_AP321XX},\r
{"ls_photoresistor", LIGHT_ID_PHOTORESISTOR},\r
+ {"ls_us5152", LIGHT_ID_US5152},\r
/*proximity sensor*/\r
{"psensor", PROXIMITY_ID_ALL},\r
{"proximity_al3006", PROXIMITY_ID_AL3006}, \r
\r
static int __init sensor_init(void)\r
{\r
- int res = i2c_add_driver(&sensor_driver);\r
+ int res = i2c_add_driver(&sensor_driver); \r
+ struct proc_dir_entry *sensor_proc_entry; \r
pr_info("%s: Probe name %s\n", __func__, sensor_driver.driver.name);\r
if (res)\r
pr_err("%s failed\n", __func__);\r
\r
+ sensor_proc_entry = proc_create("driver/sensor_dbg", 0660, NULL, &sensor_proc_fops); \r
printk("%s\n", SENSOR_VERSION_AND_TIME);\r
return res;\r
}\r
\r
#define SENSOR_I2C_RATE 200*1000\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_COMPASS\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
static int sensor_i2c_write(struct i2c_adapter *i2c_adap,\r
unsigned char address,\r
\r
int sensor_rx_data(struct i2c_client *client, char *rxData, int length)\r
{\r
-#ifdef SENSOR_DEBUG_TYPE\r
struct sensor_private_data* sensor = \r
(struct sensor_private_data *)i2c_get_clientdata(client);\r
int i = 0;\r
-#endif\r
int ret = 0;\r
char reg = rxData[0];\r
ret = senosr_i2c_read(client->adapter, client->addr, reg, length, rxData);\r
\r
-#ifdef SENSOR_DEBUG_TYPE\r
DBG("addr=0x%x,len=%d,rxdata:",reg,length);\r
for(i=0; i<length; i++)\r
DBG("0x%x,",rxData[i]);\r
DBG("\n");\r
-#endif \r
return ret;\r
}\r
EXPORT_SYMBOL(sensor_rx_data);\r
\r
int sensor_tx_data(struct i2c_client *client, char *txData, int length)\r
{\r
-#ifdef SENSOR_DEBUG_TYPE \r
struct sensor_private_data* sensor = \r
(struct sensor_private_data *)i2c_get_clientdata(client);\r
int i = 0;\r
-#endif\r
int ret = 0;\r
-#ifdef SENSOR_DEBUG_TYPE \r
+\r
DBG("addr=0x%x,len=%d,txdata:",txData[0],length);\r
for(i=1; i<length; i++)\r
DBG("0x%x,",txData[i]);\r
DBG("\n");\r
-#endif\r
ret = sensor_i2c_write(client->adapter, client->addr, length, txData);\r
return ret;\r
\r
#endif\r
#include <linux/sensor-dev.h>\r
\r
-#if 0\r
-#define SENSOR_DEBUG_TYPE SENSOR_TYPE_TEMPERATURE\r
-#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
-#else\r
-#define DBG(x...)\r
-#endif\r
\r
#define CMD_RESET 0x1E // ADC reset command \r
#define CMD_ADC_READ 0x00 // ADC read command \r
for (i=0;i<8;i++) \r
{\r
C[i] = prom[2*i] << 8 | prom[2*i + 1];\r
- DBG("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);\r
- DBG("\nC[%d]=%d,",i+1,C[i]);\r
+ //printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);\r
+ //printk("\nC[%d]=%d,",i+1,C[i]);\r
} \r
\r
}\r
int result = 0;\r
int type = ops->type;\r
result = sensor_register_slave(type, NULL, NULL, temperature_get_ops);\r
- DBG("%s\n",__func__);\r
return result;\r
}\r
\r
ACCEL_ID_KXSD9,\r
ACCEL_ID_KXTF9,\r
ACCEL_ID_KXTIK,\r
+ ACCEL_ID_KXTJ9,\r
ACCEL_ID_BMA150,\r
ACCEL_ID_BMA222,\r
ACCEL_ID_BMA250,\r
COMPASS_ID_ALL,\r
COMPASS_ID_AK8975,\r
COMPASS_ID_AK8963,\r
+ COMPASS_ID_AK09911,\r
COMPASS_ID_AK8972,\r
COMPASS_ID_AMI30X,\r
COMPASS_ID_AMI306,\r
\r
GYRO_ID_ALL,\r
GYRO_ID_L3G4200D,\r
- GYRO_ID_L3G20D,\r
+ GYRO_ID_L3G20D,\r
GYRO_ID_K3G,\r
\r
LIGHT_ID_ALL,\r
LIGHT_ID_ISL29023,\r
LIGHT_ID_AP321XX,\r
LIGHT_ID_PHOTORESISTOR, \r
+ LIGHT_ID_US5152,\r
\r
PROXIMITY_ID_ALL,\r
PROXIMITY_ID_AL3006,\r
atomic_t m_flag; \r
atomic_t mv_flag; \r
atomic_t open_flag;\r
+ atomic_t debug_flag;\r
long long delay; \r
wait_queue_head_t open_wq;\r
};\r
struct sensor_platform_data *slave_pdata,\r
struct sensor_operate *(*get_sensor_ops)(void));\r
\r
+#if 1\r
+#define DBG(x...) if((atomic_read(&sensor->flags.debug_flag) == sensor->pdata->type) || (atomic_read(&sensor->flags.debug_flag) == SENSOR_NUM_TYPES))printk(x)\r
+#else\r
+#define DBG(x...)\r
+#endif\r
\r
#define GSENSOR_IOCTL_MAGIC 'a'\r
#define GBUFF_SIZE 12 /* Rx buffer size */\r