summaryrefslogtreecommitdiff
path: root/drivers/input/sensor/dmard06_gsensor
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/input/sensor/dmard06_gsensor
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'drivers/input/sensor/dmard06_gsensor')
-rwxr-xr-xdrivers/input/sensor/dmard06_gsensor/Makefile34
-rwxr-xr-xdrivers/input/sensor/dmard06_gsensor/dmard06.c980
2 files changed, 1014 insertions, 0 deletions
diff --git a/drivers/input/sensor/dmard06_gsensor/Makefile b/drivers/input/sensor/dmard06_gsensor/Makefile
new file mode 100755
index 00000000..a5dfa3cb
--- /dev/null
+++ b/drivers/input/sensor/dmard06_gsensor/Makefile
@@ -0,0 +1,34 @@
+KERNELDIR=../../../../
+#KERNELDIR=/home/hangyan/android8850/kernel/ANDROID_3.0.8
+CROSS = arm_1103_le-
+CC= $(CROSS)gcc
+LD= $(CROSS)ld
+STRIP = $(CROSS)strip
+
+DEBUG = n
+
+# Add your debugging flag (or not) to EXTRA_CFLAGS
+ifeq ($(DEBUG),y)
+# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+
+else
+ DEBFLAGS = -O2 -Wall
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=s_wmt_gsensor_dmard06
+
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := dmard06.o
+
+default:
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
+ $(STRIP) --strip-debug $(MY_MODULE_NAME).ko
+ rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers
+
diff --git a/drivers/input/sensor/dmard06_gsensor/dmard06.c b/drivers/input/sensor/dmard06_gsensor/dmard06.c
new file mode 100755
index 00000000..bcb6e5ad
--- /dev/null
+++ b/drivers/input/sensor/dmard06_gsensor/dmard06.c
@@ -0,0 +1,980 @@
+/*
+ * @file drivers/i2c/chips/dmard06.c
+ * @brief DMARD06 g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.0
+ * @date 2011/8/5
+ *
+ * @section LICENSE
+ *
+ * Copyright 2011 Domintech Technology Co., Ltd
+ *
+ * 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/module.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/cdev.h>
+//#include <linux/earlysuspend.h>
+#include <linux/wakelock.h>
+#include <asm/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <mach/hardware.h>
+#include <linux/miscdevice.h>
+
+//////////////////////////////////////////////////////////
+#define AKMIO 0xA1
+
+/* IOCTLs for AKM library */
+#define ECS_IOCTL_INIT _IO(AKMIO, 0x01)
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x02, char[5])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x03, char[5])
+#define ECS_IOCTL_RESET _IO(AKMIO, 0x04)
+#define ECS_IOCTL_INT_STATUS _IO(AKMIO, 0x05)
+#define ECS_IOCTL_FFD_STATUS _IO(AKMIO, 0x06)
+#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x07, short)
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x08, char[RBUFF_SIZE+1])
+#define ECS_IOCTL_GET_NUMFRQ _IOR(AKMIO, 0x09, char[2])
+#define ECS_IOCTL_SET_PERST _IO(AKMIO, 0x0A)
+#define ECS_IOCTL_SET_G0RST _IO(AKMIO, 0x0B)
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x0C, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x0D, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x0E, int)
+#define ECS_IOCTL_GET_CALI_DATA _IOR(AKMIO, 0x0F, char[MAX_CALI_SIZE])
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, short)
+
+/* IOCTLs for APPs */
+#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short)
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short)
+//#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short)
+#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short)
+#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17)
+//#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, short)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short) /* Set raw magnetic vector flag */
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short) /* Get raw magnetic vector flag */
+
+#define WMTGSENSOR_IOCTL_MAGIC 0x09
+#define WMT_IOCTL_SENSOR_CAL_OFFSET _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x01, int) //offset calibration
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x02, short)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x03, short)
+#define WMT_IOCTL_SENSOR_GET_DRVID _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x04, unsigned int)
+
+
+/* IOCTLs for pedometer */
+#define ECS_IOCTL_SET_STEP_CNT _IOW(AKMIO, 0x20, short)
+//////////////////////////////////////////////////////////////////
+#define SENSOR_DELAY_FASTEST 0
+#define SENSOR_DELAY_GAME 20
+#define SENSOR_DELAY_UI 60
+#define SENSOR_DELAY_NORMAL 200
+
+#define DMARD06_DRVID 3
+
+/////////////////////////////////////////////////////////////////
+
+#undef dbg
+#define dbg(fmt, args...) if (l_sensorconfig.isdbg) printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__, ## args)
+
+#undef errlog
+#undef klog
+#define errlog(fmt, args...) printk(KERN_ERR "[%s]: " fmt, __FUNCTION__, ## args)
+#define klog(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__, ## args)
+
+#define DMARD06_I2C_NAME "dmard06"
+#define DMARD06_I2C_ADDR 0x1c
+
+#define GSENSOR_PROC_NAME "gsensor_config"
+#define GSENSOR_MAJOR 161
+#define GSENSOR_NAME "dmard06"
+#define GSENSOR_DRIVER_NAME "dmard06_drv"
+
+#define GSENDMARD06_UBOOT_NAME "wmt.io.d06sensor"
+
+#define MAX_WR_DMARD06_LEN (1+1)
+
+#define LSG 32
+
+static char const *const ACCELEMETER_CLASS_NAME = "accelemeter";
+static char const *const DMARD06_DEVICE_NAME = "dmard06";
+////////////////////////////////////////////////////////////
+#define ID_REG_ADDR 0x0F
+#define SWRESET_REG_ADDR 0x53
+#define T_REG_ADDR 0x40
+#define XYZ_REG_ADDR 0x41
+#define CTR1_REG_ADDR 0x44
+#define CTR2_REG_ADDR 0x45
+#define CTR3_REG_ADDR 0x46
+#define CTR4_REG_ADDR 0x47
+#define CTR5_REG_ADDR 0x48
+#define STAT_REG_ADDR 0x49
+
+
+
+static int dmard06_init(void);
+static void dmard06_exit(void);
+
+static int dmard06_file_open(struct inode*, struct file*);
+static ssize_t dmard06_file_write(struct file*, const char*, size_t, loff_t*);
+static ssize_t dmard06_file_read(struct file*, char*, size_t, loff_t*);
+static int dmard06_file_close(struct inode*, struct file*);
+
+static int dmard06_i2c_suspend(struct platform_device *pdev, pm_message_t state);
+static int dmard06_i2c_resume(struct platform_device *pdev);
+static int dmard06_i2c_probe(void);
+static int dmard06_i2c_remove(void);
+static void dmard06_i2c_read_xyz(s8 *x, s8 *y, s8 *z);
+static void dmard06_i2c_accel_value(s8 *val);
+static int dmard06_probe(
+ struct platform_device *pdev);
+static int dmard06_remove(struct platform_device *pdev);
+static int dmard06_i2c_xyz_read_reg(u8* index ,u8 *buffer, int length);
+
+
+
+//extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg, unsigned int num, int bus_id);
+extern int i2c_api_do_send(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size);
+extern int i2c_api_do_recv(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size);
+
+extern int wmt_setsyspara(char *varname, unsigned char *varval);
+
+/////////////////////////////////////////////////////////////////
+struct work_struct poll_work;
+static struct mutex sense_data_mutex;
+
+
+struct dmard06_config
+{
+ int op;
+ int int_gpio; //0-3
+ int samp;
+ int xyz_axis[3][3]; // (axis,direction)
+ int irq;
+ struct proc_dir_entry* sensor_proc;
+ //int sensorlevel;
+ //int shake_enable; // 1--enable shake, 0--disable shake
+ //int manual_rotation; // 0--landance, 90--vertical
+ struct input_dev *input_dev;
+ //struct work_struct work;
+ struct delayed_work work; // for polling
+ struct workqueue_struct *queue;
+ int isdbg; // 0-- no debug log, 1--show debug log
+ int sensor_samp; //
+ int sensor_enable; // 0 --> disable sensor, 1 --> enable sensor
+ int test_pass;
+ spinlock_t spinlock;
+ int pollcnt; // the counts of polling
+ int offset[3]; // for calibration
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend earlysuspend;
+#endif
+};
+
+static struct dmard06_config l_sensorconfig = {
+ .op = 0,
+ .int_gpio = 3,
+ .samp = 16,
+ .xyz_axis = {
+ {ABS_X, -1},
+ {ABS_Y, 1},
+ {ABS_Z, -1},
+ },
+ .irq = 6,
+ .int_gpio = 3,
+ .sensor_proc = NULL,
+ //.sensorlevel = SENSOR_GRAVITYGAME_MODE,
+ //.shake_enable = 0, // default enable shake
+ .isdbg = 0,
+ .sensor_samp = 1, // 1 sample/second
+ .sensor_enable = 1, // enable sensor
+ .test_pass = 0, // for test program
+ .pollcnt = 0, // Don't report the x,y,z when the driver is loaded until 2~3 seconds
+ .offset = {0, 0, 0},
+};
+
+static struct class* l_dev_class = NULL;
+static struct device *l_clsdevice = NULL;
+
+
+struct raw_data
+{
+ short x;
+ short y;
+ short z;
+};
+
+struct dev_data
+{
+ dev_t devno;
+ struct cdev cdev;
+ struct class *class;
+ struct i2c_client *client;
+};
+
+static struct dev_data dev;
+
+struct file_operations dmard06_fops =
+{
+ .owner = THIS_MODULE,
+ .read = dmard06_file_read,
+ .write = dmard06_file_write,
+ .open = dmard06_file_open,
+ .release = dmard06_file_close,
+};
+
+static int dmard06_file_open(struct inode *inode, struct file *filp)
+{
+ dbg("open...\n");
+
+ return 0;
+}
+
+static ssize_t dmard06_file_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+{
+ dbg("write...\n");
+
+ return 0;
+}
+
+unsigned int sample_rate_2_memsec(unsigned int rate)
+{
+ return (1000/rate);
+}
+
+static int dmard06_packet_rptValue(int x, int y, int z)
+{
+ return ((0xFF&z) | ((0xFF&y)<<8) | ((0xFF&x)<<16));
+}
+
+
+static void dmard06_work_func(struct work_struct *work)
+{
+ u8 buffer[3];
+ //buffer[0] = 0x41;
+ u8 index = 0x41;
+ s8 x,y,z;
+ int xyz,tx,ty,tz;
+
+ mutex_lock(&sense_data_mutex);
+ //read data
+ dmard06_i2c_xyz_read_reg(&index, buffer, 3);
+ mutex_unlock(&sense_data_mutex);
+ // check whether it's valid
+ // report the data
+ x = (s8)buffer[0];
+ y = (s8)buffer[1];
+ z = (s8)buffer[2];
+ dmard06_i2c_accel_value(&x);
+ dmard06_i2c_accel_value(&y);
+ dmard06_i2c_accel_value(&z);
+ tx = x*l_sensorconfig.xyz_axis[0][1]+l_sensorconfig.offset[0];
+ ty = y*l_sensorconfig.xyz_axis[1][1]+l_sensorconfig.offset[1];
+ tz = z*l_sensorconfig.xyz_axis[2][1]+l_sensorconfig.offset[2];
+ xyz = dmard06_packet_rptValue(tx, ty, tz);
+ input_report_abs(l_sensorconfig.input_dev, ABS_X, xyz);
+
+ //input_report_abs(l_sensorconfig.input_dev, l_sensorconfig.xyz_axis[0][0],
+ // x*l_sensorconfig.xyz_axis[0][1]+l_sensorconfig.offset[0]);
+ //input_report_abs(l_sensorconfig.input_dev, l_sensorconfig.xyz_axis[1][0],
+ // y*l_sensorconfig.xyz_axis[1][1]+l_sensorconfig.offset[1]);
+ //input_report_abs(l_sensorconfig.input_dev, l_sensorconfig.xyz_axis[2][0],
+ //z*l_sensorconfig.xyz_axis[2][1]+l_sensorconfig.offset[2]);
+ input_sync(l_sensorconfig.input_dev);
+ dbg("x=%2x(tx=%2x),y=%2x(ty=%2x),z=%2x(tz=%2x),xyz=%x",
+ (char)x, (char)tx, (char)y, (char)ty, (char)z, (char)tz, xyz);
+
+ // for next polling
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ //klog("%d=%d,%d=%d,%d=%d\n", l_sensorconfig.xyz_axis[0][0], x*l_sensorconfig.xyz_axis[0][1],
+ // l_sensorconfig.xyz_axis[1][0], y*l_sensorconfig.xyz_axis[1][1],
+ // l_sensorconfig.xyz_axis[2][0], z*l_sensorconfig.xyz_axis[2][1]);
+ //klog("the polling period:%d\n", msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+
+}
+
+
+static ssize_t dmard06_file_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+ int ret;
+ s8 x, y, z;
+ struct raw_data rdata;
+
+ dbg("read...\n");
+ mutex_lock(&sense_data_mutex);
+ dmard06_i2c_read_xyz(&x, &y, &z);
+ rdata.x = x;
+ rdata.y = y;
+ rdata.z = z;
+
+ ret = copy_to_user(buf, &rdata, count);
+ mutex_unlock(&sense_data_mutex);
+
+ return count;
+}
+
+static int dmard06_file_close(struct inode *inode, struct file *filp)
+{
+ dbg("close...\n");
+
+ return 0;
+}
+
+static void dmard06_platform_release(struct device *device)
+{
+ return;
+}
+
+
+static struct platform_device dmard06_device = {
+ .name = GSENSOR_NAME,
+ .id = 0,
+ .dev = {
+ .release = dmard06_platform_release,
+ },
+};
+
+static struct platform_driver dmard06_driver = {
+ .probe = dmard06_probe,
+ .remove = dmard06_remove,
+ .suspend = dmard06_i2c_suspend,
+ .resume = dmard06_i2c_resume,
+ .driver = {
+ .name = GSENSOR_NAME,
+ },
+};
+
+static int dmard06_i2c_xyz_write_reg(u8* index ,u8 *buffer, int length)
+{
+ /*int ret = 0;
+ u8 buf[MAX_WR_DMARD06_LEN];
+ struct i2c_msg msg[1];
+
+ buf[0] = *index;
+ memcpy(buf+1, buffer, length);
+ msg[0].addr = DMARD06_I2C_ADDR;
+ msg[0].flags = 0 ;
+ msg[0].flags &= ~(I2C_M_RD);
+ msg[0].len = length+1;
+ msg[0].buf = buf;
+ if ((ret = wmt_i2c_xfer_continue_if_4(msg,1,0)) <= 0)
+ {
+ errlog("write error!\n");
+ }
+ return ret;*/
+ return i2c_api_do_send(0, DMARD06_I2C_ADDR, index, buffer, length);
+}
+
+static int dmard06_i2c_xyz_read_reg(u8* index ,u8 *buffer, int length)
+{
+ /*int ret = 0;
+
+ struct i2c_msg msg[] =
+ {
+ {.addr = DMARD06_I2C_ADDR, .flags = 0, .len = 1, .buf = index,},
+ {.addr = DMARD06_I2C_ADDR, .flags = I2C_M_RD, .len = length, .buf = buffer,},
+ };
+ ret = wmt_i2c_xfer_continue_if_4(msg, 2,0);
+ if (ret <= 0)
+ {
+ errlog("read error!\n");
+ }
+ return ret;*/
+ return i2c_api_do_recv(0, DMARD06_I2C_ADDR, index, buffer, length);
+}
+
+static void dmard06_i2c_read_xyz(s8 *x, s8 *y, s8 *z)
+{
+
+ u8 buffer[3];
+ //buffer[0] = 0x41;
+ u8 index = 0x41;
+
+ dmard06_i2c_xyz_read_reg(&index, buffer, 3);
+ *x = (s8)buffer[0];
+ *y = (s8)buffer[1];
+ *z = (s8)buffer[2];
+ dmard06_i2c_accel_value(x);
+ dmard06_i2c_accel_value(y);
+ dmard06_i2c_accel_value(z);
+ if (ABS_X == l_sensorconfig.xyz_axis[0][0])
+ {
+ *x = l_sensorconfig.xyz_axis[0][1]*(*x);
+ *y = l_sensorconfig.xyz_axis[1][1]*(*y);
+ } else {
+ *x = l_sensorconfig.xyz_axis[0][1]*(*y);
+ *y = l_sensorconfig.xyz_axis[1][1]*(*x);
+ }
+ *z = l_sensorconfig.xyz_axis[2][1]*(*z);
+
+ dbg("dmrd06:x=%x,y=%x,z=%x\n", *x, *y, *z);
+}
+
+static void dmard06_i2c_accel_value(s8 *val)
+{
+ *val >>= 1;
+}
+
+static int dmard06_CalOffset(int side)
+{
+ u8 buffer[3];
+ //buffer[0] = 0x41;
+ u8 index = 0x41;
+ s8 x,y,z;
+
+ //mutex_lock(&sense_data_mutex);
+ //read data
+ dmard06_i2c_xyz_read_reg(&index, buffer, 3);
+ //mutex_unlock(&sense_data_mutex);
+ // check whether it's valid
+ // report the data
+ x = (s8)buffer[0];
+ y = (s8)buffer[1];
+ z = (s8)buffer[2];
+ dmard06_i2c_accel_value(&x);
+ dmard06_i2c_accel_value(&y);
+ dmard06_i2c_accel_value(&z);
+ l_sensorconfig.offset[0] = 0 - x*l_sensorconfig.xyz_axis[0][1];
+ l_sensorconfig.offset[1] = 0 - y*l_sensorconfig.xyz_axis[1][1];
+ l_sensorconfig.offset[2] = LSG - z*l_sensorconfig.xyz_axis[2][1];
+ return 0;
+
+}
+
+static int dmard06_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ dbg("...\n");
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+
+ return 0;
+}
+
+static int is_dmard06(void)
+{
+ int err = 0;
+ u8 cAddress = 0, cData = 0;
+ char buf[4];
+
+ cAddress = 0x53;
+ //i2c_master_send( client, (char*)&cAddress, 1);
+ //i2c_master_recv( client, (char*)&cData, 1);
+ if (dmard06_i2c_xyz_read_reg(&cAddress, &cData,1) <= 0)
+ {
+ errlog("Error to read SW_RESET register!\n");
+ }
+ dbg("i2c Read 0x53 = %x \n", cData);
+
+ cAddress = 0x0f;
+ //i2c_master_send( client, (char*)&cAddress, 1);
+ //i2c_master_recv( client, (char*)&cData, 1);
+ if (dmard06_i2c_xyz_read_reg(&cAddress, &cData,1) <= 0)
+ {
+ errlog("Can't find dmard06!\n");
+ return -1;
+ }
+ dbg("i2c Read 0x0f = %d \n", cData);
+
+ if(( cData&0x00FF) == 0x0006)
+ {
+ klog("Find DMARD06!\n");
+ }
+ else
+ {
+ errlog("ID isn't 0x06.(0x%x) !\n",cData);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int dmard06_i2c_remove(void)
+{
+
+ return 0;
+}
+
+static int dmard06_i2c_resume(struct platform_device *pdev)
+{
+ dbg("...\n");
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+
+
+ return 0;
+}
+
+static int sensor_writeproc( struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data )
+{
+
+ int inputval = -1;
+ int enable, sample = -1;
+ char tembuf[8];
+ unsigned int amsr = 0;
+ int test = 0;
+
+ mutex_lock(&sense_data_mutex);
+ memset(tembuf, 0, sizeof(tembuf));
+ // get sensor level and set sensor level
+ if (sscanf(buffer, "isdbg=%d\n", &l_sensorconfig.isdbg))
+ {
+ // only set the dbg flag
+ } else if (sscanf(buffer, "samp=%d\n", &sample))
+ {
+ if (sample > 0)
+ {
+ if (sample != l_sensorconfig.sensor_samp)
+ {
+ }
+ //printk(KERN_ALERT "sensor samp=%d(amsr:%d) has been set.\n", sample, amsr);
+ } else {
+ printk(KERN_ALERT "Wrong sample argumnet of sensor.\n");
+ }
+ } else if (sscanf(buffer, "enable=%d\n", &enable))
+ {
+ if ((enable < 0) || (enable > 1))
+ {
+ printk(KERN_ERR "The argument to enable/disable g-sensor should be 0 or 1 !!!\n");
+ } else if (enable != l_sensorconfig.sensor_enable)
+ {
+ //mma_enable_disable(enable);
+ l_sensorconfig.sensor_enable = enable;
+ }
+ } else if (sscanf(buffer, "sensor_test=%d\n", &test))
+ { // for test begin
+ l_sensorconfig.test_pass = 0;
+ } else if (sscanf(buffer, "sensor_testend=%d\n", &test))
+ { // Don nothing only to be compatible the before testing program
+ }
+ mutex_unlock(&sense_data_mutex);
+ return count;
+}
+
+static int sensor_readproc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len = sprintf(page,
+ "test_pass=%d\nisdbg=%d\nrate=%d\nenable=%d\n",
+ l_sensorconfig.test_pass,
+ l_sensorconfig.isdbg,
+ l_sensorconfig.sensor_samp,
+ l_sensorconfig.sensor_enable
+ );
+ return len;
+}
+
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+static int get_axisset(void* param)
+{
+ char varbuf[64];
+ int n;
+ int varlen;
+
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+ if (wmt_getsyspara("wmt.io.d06sensor", varbuf, &varlen)) {
+ printk(KERN_DEBUG "Can't get gsensor config in u-boot!!!!\n");
+ return -1;
+ } else {
+ n = sscanf(varbuf, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ &l_sensorconfig.op,
+ &l_sensorconfig.int_gpio,
+ &l_sensorconfig.samp,
+ &(l_sensorconfig.xyz_axis[0][0]),
+ &(l_sensorconfig.xyz_axis[0][1]),
+ &(l_sensorconfig.xyz_axis[1][0]),
+ &(l_sensorconfig.xyz_axis[1][1]),
+ &(l_sensorconfig.xyz_axis[2][0]),
+ &(l_sensorconfig.xyz_axis[2][1]),
+ &l_sensorconfig.offset[0],
+ &l_sensorconfig.offset[1],
+ &l_sensorconfig.offset[2]);
+ if (n != 12) {
+ printk(KERN_ERR "gsensor format is error in u-boot!!!\n");
+ return -1;
+ }
+ l_sensorconfig.sensor_samp = l_sensorconfig.samp;
+
+ dbg("get the sensor config: %d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+ l_sensorconfig.op,
+ l_sensorconfig.int_gpio,
+ l_sensorconfig.samp,
+ l_sensorconfig.xyz_axis[0][0],
+ l_sensorconfig.xyz_axis[0][1],
+ l_sensorconfig.xyz_axis[1][0],
+ l_sensorconfig.xyz_axis[1][1],
+ l_sensorconfig.xyz_axis[2][0],
+ l_sensorconfig.xyz_axis[2][1]
+ );
+ }
+ return 0;
+}
+
+// To contol the g-sensor for UI
+static int mmad_open(struct inode *inode, struct file *file)
+{
+ dbg("Open the g-sensor node...\n");
+ return 0;
+}
+
+static int mmad_release(struct inode *inode, struct file *file)
+{
+ dbg("Close the g-sensor node...\n");
+ return 0;
+}
+
+
+static int
+mmad_ioctl(/*struct inode *inode,*/ struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ char rwbuf[5];
+ short delay, enable, amsr = -1;
+ unsigned int sample;
+ int ret = 0;
+ int side;
+ char varbuff[80];
+ unsigned int uval = 0;
+
+ dbg("g-sensor ioctr...\n");
+ memset(rwbuf, 0, sizeof(rwbuf));
+ mutex_lock(&sense_data_mutex);
+ switch (cmd) {
+ case ECS_IOCTL_APP_SET_DELAY:
+ // set the rate of g-sensor
+ if (copy_from_user(&delay, argp, sizeof(short)))
+ {
+ printk(KERN_ALERT "Can't get set delay!!!\n");
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ klog("set delay=%d \n", delay);
+ //klog("before change sensor sample:%d...\n", l_sensorconfig.sensor_samp);
+ if ((delay >=0) && (delay < 20))
+ {
+ delay = 20;
+ } else if (delay > 200)
+ {
+ delay = 200;
+ }
+ if (delay > 0)
+ {
+ l_sensorconfig.sensor_samp = 1000/delay;
+ } else {
+ errlog("error delay argument(delay=%d)!!!\n",delay);
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ break;
+ case ECS_IOCTL_APP_SET_AFLAG:
+ // enable/disable sensor
+ if (copy_from_user(&enable, argp, sizeof(short)))
+ {
+ printk(KERN_ERR "Can't get enable flag!!!\n");
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ if ((enable >=0) && (enable <=1))
+ {
+ dbg("driver: disable/enable(%d) gsensor.\n", enable);
+
+ if (enable != l_sensorconfig.sensor_enable)
+ {
+ //mma_enable_disable(enable);
+ /*if (enable != 0)
+ {
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ } else {
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ flush_workqueue(l_sensorconfig.queue);
+ }*/
+ l_sensorconfig.sensor_enable = enable;
+
+ }
+ } else {
+ printk(KERN_ERR "Wrong enable argument in %s !!!\n", __FUNCTION__);
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ break;
+ case WMT_IOCTL_SENSOR_GET_DRVID:
+ uval = DMARD06_DRVID;
+ if (copy_to_user((unsigned int*)arg, &uval, sizeof(unsigned int)))
+ {
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ dbg("dmard06_driver_id:%d\n",uval);
+ break;
+ case WMT_IOCTL_SENSOR_CAL_OFFSET:
+ klog("-->WMT_IOCTL_SENSOR_CAL_OFFSET\n");
+ if(copy_from_user(&side, (int*)argp, sizeof(int)))
+ {
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ dbg("side=%d\n",side);
+ if (dmard06_CalOffset(side) != 0)
+ {
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ // save the param
+ sprintf(varbuff, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ l_sensorconfig.op,
+ l_sensorconfig.int_gpio,
+ 10,//l_sensorconfig.samp,
+ (l_sensorconfig.xyz_axis[0][0]),
+ (l_sensorconfig.xyz_axis[0][1]),
+ (l_sensorconfig.xyz_axis[1][0]),
+ (l_sensorconfig.xyz_axis[1][1]),
+ (l_sensorconfig.xyz_axis[2][0]),
+ (l_sensorconfig.xyz_axis[2][1]),
+ l_sensorconfig.offset[0],
+ l_sensorconfig.offset[1],
+ l_sensorconfig.offset[2]
+ );
+ wmt_setsyspara(GSENDMARD06_UBOOT_NAME, varbuff);
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+
+ /*switch (cmd) {
+ case ECS_IOCTL_READ:
+ if (copy_to_user(argp, &rwbuf, sizeof(rwbuf)))
+ return -EFAULT;
+ break;
+ default:
+ break;
+ }*/
+errioctl:
+ mutex_unlock(&sense_data_mutex);
+ return ret;
+}
+
+
+static struct file_operations mmad_fops = {
+ .owner = THIS_MODULE,
+ .open = mmad_open,
+ .release = mmad_release,
+ .unlocked_ioctl = mmad_ioctl,
+};
+
+
+static struct miscdevice mmad_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "sensor_ctrl",
+ .fops = &mmad_fops,
+};
+
+static int dmard06_probe(
+ struct platform_device *pdev)
+{
+ int err = 0;
+
+ //register ctrl dev
+ err = misc_register(&mmad_device);
+ if (err != 0)
+ {
+ errlog("Can't register mma_device!\n");
+ return -1;
+ }
+ // register rd/wr proc
+ l_sensorconfig.sensor_proc = create_proc_entry(GSENSOR_PROC_NAME, 0666, NULL/*&proc_root*/);
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ l_sensorconfig.sensor_proc->write_proc = sensor_writeproc;
+ l_sensorconfig.sensor_proc->read_proc = sensor_readproc;
+ }
+ // init work queue
+ l_sensorconfig.queue = create_singlethread_workqueue("sensor-data-report");
+ //INIT_WORK(&l_sensorconfig.work, mma_work_func);
+ INIT_DELAYED_WORK(&l_sensorconfig.work, dmard06_work_func);
+ mutex_init(&sense_data_mutex);
+ l_sensorconfig.input_dev = input_allocate_device();
+ if (!l_sensorconfig.input_dev) {
+ err = -ENOMEM;
+ errlog("Failed to allocate input device\n");
+ goto exit_input_dev_alloc_failed;
+ }
+ //set_bit(EV_KEY, l_sensorconfig.input_dev->evbit);
+ //set_bit(EV_ABS, l_sensorconfig.input_dev->evbit);
+ l_sensorconfig.input_dev->evbit[0] = BIT(EV_ABS) | BIT_MASK(EV_KEY);
+ //set_bit(KEY_NEXTSONG, l_sensorconfig.input_dev->keybit);
+
+ /* yaw */
+ //input_set_abs_params(l_sensorconfig.input_dev, ABS_RX, 0, 360*100, 0, 0);
+ /* pitch */
+ //input_set_abs_params(l_sensorconfig.input_dev, ABS_RY, -180*100, 180*100, 0, 0);
+ /* roll */
+ //input_set_abs_params(l_sensorconfig.input_dev, ABS_RZ, -90*100, 90*100, 0, 0);
+ /* x-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_X, -128, 128, 0, 0);
+ /* y-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_Y, -128, 128, 0, 0);
+ /* z-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_Z, -128, 128, 0, 0);
+
+ l_sensorconfig.input_dev->name = "g-sensor";
+
+ err = input_register_device(l_sensorconfig.input_dev);
+
+ if (err) {
+ errlog("Unable to register input device: %s\n",
+ l_sensorconfig.input_dev->name);
+ goto exit_input_register_device_failed;
+ }
+
+ return 0;
+exit_input_register_device_failed:
+ input_free_device(l_sensorconfig.input_dev);
+exit_input_dev_alloc_failed:
+ // release proc
+ remove_proc_entry(GSENSOR_PROC_NAME, NULL);
+ l_sensorconfig.sensor_proc = NULL;
+ // unregister the ctrl dev
+ misc_deregister(&mmad_device);
+ return err;
+}
+
+static int dmard06_remove(struct platform_device *pdev)
+{
+ if (NULL != l_sensorconfig.queue)
+ {
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ flush_workqueue(l_sensorconfig.queue);
+ destroy_workqueue(l_sensorconfig.queue);
+ l_sensorconfig.queue = NULL;
+ }
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ remove_proc_entry(GSENSOR_PROC_NAME, NULL);
+ l_sensorconfig.sensor_proc = NULL;
+ }
+ misc_deregister(&mmad_device);
+ return 0;
+}
+#if 0
+static void dmard06_early_suspend(struct early_suspend *h)
+{
+ dbg("start\n");
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ dbg("exit\n");
+}
+
+static void dmard06_late_resume(struct early_suspend *h)
+{
+ dbg("start\n");
+ // init
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ dbg("exit\n");
+}
+#endif
+
+static int __init dmard06_init(void)
+{
+ int ret = 0;
+
+ // detech the device
+ if (is_dmard06() != 0)
+ {
+ return -1;
+ }
+ // parse g-sensor u-boot arg
+ ret = get_axisset(NULL);
+ if (ret < 0)
+ {
+ printk("<<<<<%s user choose to no sensor chip!\n", __func__);
+ return ret;
+ }
+ /*if ((ret != 0) || !l_sensorconfig.op)
+ return -EINVAL;
+ */
+
+ // Create device node
+ if (register_chrdev (GSENSOR_MAJOR, GSENSOR_NAME, &dmard06_fops)) {
+ printk (KERN_ERR "unable to get major %d\n", GSENSOR_MAJOR);
+ return -EIO;
+ }
+
+ l_dev_class = class_create(THIS_MODULE, GSENSOR_NAME);
+ if (IS_ERR(l_dev_class)){
+ ret = PTR_ERR(l_dev_class);
+ printk(KERN_ERR "Can't class_create gsensor device !!\n");
+ return ret;
+ }
+ l_clsdevice = device_create(l_dev_class, NULL, MKDEV(GSENSOR_MAJOR, 0), NULL, GSENSOR_NAME);
+ if (IS_ERR(l_clsdevice)){
+ ret = PTR_ERR(l_clsdevice);
+ printk(KERN_ERR "Failed to create device %s !!!",GSENSOR_NAME);
+ return ret;
+ }
+ INIT_WORK(&poll_work, dmard06_work_func);
+
+
+ if((ret = platform_device_register(&dmard06_device)))
+ {
+ printk(KERN_ERR "%s Can't register mma7660 platform devcie!!!\n", __FUNCTION__);
+ return ret;
+ }
+ if ((ret = platform_driver_register(&dmard06_driver)) != 0)
+ {
+ printk(KERN_ERR "%s Can't register mma7660 platform driver!!!\n", __FUNCTION__);
+ return ret;
+ }
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ l_sensorconfig.earlysuspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ l_sensorconfig.earlysuspend.suspend = dmard06_early_suspend;
+ l_sensorconfig.earlysuspend.resume = dmard06_late_resume;
+ register_early_suspend(&l_sensorconfig.earlysuspend);
+#endif
+
+ klog("dmard06 g-sensor driver load!\n");
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+
+ return 0;
+}
+
+static void __exit dmard06_exit(void)
+{
+ //unregister_early_suspend(&l_sensorconfig.earlysuspend);
+ platform_driver_unregister(&dmard06_driver);
+ platform_device_unregister(&dmard06_device);
+ device_destroy(l_dev_class, MKDEV(GSENSOR_MAJOR, 0));
+ unregister_chrdev(GSENSOR_MAJOR, GSENSOR_NAME);
+ class_destroy(l_dev_class);
+
+}
+
+MODULE_AUTHOR("DMT_RD");
+MODULE_DESCRIPTION("DMARD06 g-sensor Driver");
+MODULE_LICENSE("GPL");
+
+module_init(dmard06_init);
+module_exit(dmard06_exit);