summaryrefslogtreecommitdiff
path: root/drivers/input/sensor/dmard09_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/dmard09_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/dmard09_gsensor')
-rwxr-xr-xdrivers/input/sensor/dmard09_gsensor/Makefile35
-rwxr-xr-xdrivers/input/sensor/dmard09_gsensor/dmt09.c1685
-rwxr-xr-xdrivers/input/sensor/dmard09_gsensor/dmt09.h183
3 files changed, 1903 insertions, 0 deletions
diff --git a/drivers/input/sensor/dmard09_gsensor/Makefile b/drivers/input/sensor/dmard09_gsensor/Makefile
new file mode 100755
index 00000000..d9242020
--- /dev/null
+++ b/drivers/input/sensor/dmard09_gsensor/Makefile
@@ -0,0 +1,35 @@
+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_dmard09
+
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := dmt09.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/dmard09_gsensor/dmt09.c b/drivers/input/sensor/dmard09_gsensor/dmt09.c
new file mode 100755
index 00000000..90b03aa3
--- /dev/null
+++ b/drivers/input/sensor/dmard09_gsensor/dmt09.c
@@ -0,0 +1,1685 @@
+/*
+ * @file drivers/misc/dmt09.c
+ * @brief DMT g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.06
+ * @date 2013/08/14
+ * @section LICENSE
+ *
+ * Copyright 2012 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 "dmt09.h"
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/wakelock.h>
+#include <asm/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/clk.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include "../sensor.h"
+
+//////////////////////////////////////////////////////////
+static struct wmt_gsensor_data l_sensorconfig = {
+ .op = 0,
+ .int_gpio = 3,
+ .samp = 5,
+ .xyz_axis = {
+ {ABS_X, -1},
+ {ABS_Y, 1},
+ {ABS_Z, -1},
+ },
+ .sensor_proc = NULL,
+ .isdbg = 0,
+ .sensor_samp = 10, // 1 sample/second
+ .sensor_enable = 1, // enable sensor
+ .test_pass = 0, // for test program
+ .offset={0,0,0},
+};
+
+static struct class* l_dev_class = NULL;
+static void update_var(void);
+
+////////////////////////////////////////////////////////////
+
+
+static unsigned int interval;
+static int D09_write_offset_to_file(struct i2c_client *client);
+void D09_read_offset_from_file(struct i2c_client *client);
+#define DMT_BROADCAST_APK_ENABLE
+char D09_OffsetFileName[] = "/data/misc/gsensor_offset.txt";//"/system/vendor/dmt/gsensor_offset.txt";// /* FILE offset.txt */
+char DmtXXFileName[] = "/data/misc/dmt_sensor.txt";//"/system/vendor/dmt/dmt_sensor.txt";//
+static int create_devidfile(void);
+static struct dmt_data *s_dmt;
+static int device_init(void);
+static void device_exit(void);
+
+static int device_open(struct inode*, struct file*);
+static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+static int device_close(struct inode*, struct file*);
+
+static int dmard09_suspend(struct platform_device *pdev, pm_message_t state);
+static int dmard09_resume(struct platform_device *pdev);
+
+/*static int device_i2c_suspend(struct i2c_client *client, pm_message_t mesg);
+static int device_i2c_resume(struct i2c_client *client);
+static int __devinit device_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
+static int __devexit device_i2c_remove(struct i2c_client *client);*/
+static int D09_i2c_read_xyz(struct i2c_client *client, int *xyz);
+static int device_i2c_rxdata(struct i2c_client *client, unsigned char *rxDat, int length);
+static int device_i2c_txdata(struct i2c_client *client, unsigned char *txData, int length);
+
+static int dmt_get_filter(struct i2c_client *client);
+static int dmt_set_filter(struct i2c_client *client,int);
+static int dmt_get_position(struct i2c_client *client);
+static int dmt_set_position(struct i2c_client *client,int);
+static int DMT_GetOpenStatus(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ GSE_LOG("start active=%d\n",dmt->active.counter);
+ wait_event_interruptible(dmt->open_wq, (atomic_read(&dmt->active) != 0));
+ return 0;
+}
+
+static int DMT_GetCloseStatus(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ GSE_LOG("start active=%d\n",dmt->active.counter);
+ wait_event_interruptible(dmt->open_wq, (atomic_read(&dmt->active) <= 0));
+ return 0;
+}
+
+static void DMT_sysfs_update_active_status(struct dmt_data *dmt , int en){
+ unsigned long dmt_delay;
+ if(en){
+ dmt_delay=msecs_to_jiffies(atomic_read(&dmt->delay));
+ if(dmt_delay<1)
+ dmt_delay=1;
+
+ GSE_LOG("schedule_delayed_work start with delay time=%lu\n",dmt_delay);
+ schedule_delayed_work(&dmt->delaywork,dmt_delay);
+ }
+ else
+ cancel_delayed_work_sync(&dmt->delaywork);
+}
+
+static bool get_value_as_int(char const *buf, size_t size, int *value){
+ long tmp;
+ if (size == 0)
+ return false;
+ /* maybe text format value */
+ if ((buf[0] == '0') && (size > 1)) {
+ if ((buf[1] == 'x') || (buf[1] == 'X')) {
+ /* hexadecimal format */
+ if (0 != strict_strtol(buf, 16, &tmp))
+ return false;
+ } else {
+ /* octal format */
+ if (0 != strict_strtol(buf, 8, &tmp))
+ return false;
+ }
+ } else {
+ /* decimal format */
+ if (0 != strict_strtol(buf, 10, &tmp))
+ return false;
+ }
+
+ if (tmp > INT_MAX)
+ return false;
+
+ *value = tmp;
+ return true;
+}
+static bool get_value_as_int64(char const *buf, size_t size, long long *value)
+{
+ long long tmp;
+ if (size == 0)
+ return false;
+ /* maybe text format value */
+ if ((buf[0] == '0') && (size > 1)) {
+ if ((buf[1] == 'x') || (buf[1] == 'X')) {
+ /* hexadecimal format */
+ if (0 != strict_strtoll(buf, 16, &tmp))
+ return false;
+ } else {
+ /* octal format */
+ if (0 != strict_strtoll(buf, 8, &tmp))
+ return false;
+ }
+ } else {
+ /* decimal format */
+ if (0 != strict_strtoll(buf, 10, &tmp))
+ return false;
+ }
+
+ if (tmp > LLONG_MAX)
+ return false;
+
+ *value = tmp;
+ return true;
+}
+/* sysfs enable show & store */
+static ssize_t dmt_sysfs_enable_show(
+ struct dmt_data *dmt, char *buf, int pos)
+{
+ char str[2][16]={"ACC enable OFF","ACC enable ON"};
+ int flag;
+ flag=atomic_read(&dmt->enable);
+ return sprintf(buf, "%s\n", str[flag]);
+}
+
+static ssize_t dmt_sysfs_enable_store(
+ struct dmt_data *dmt, char const *buf, size_t count, int pos)
+{
+ int en = 0;
+ if (NULL == buf)
+ return -EINVAL;
+ //GSE_LOG("buf=%x %x\n", buf[0], buf[1]);
+ if (0 == count)
+ return 0;
+
+ if (false == get_value_as_int(buf, count, &en))
+ return -EINVAL;
+
+ en = en ? 1 : 0;
+
+ atomic_set(&dmt->enable,en);
+ DMT_sysfs_update_active_status(dmt , en);
+ return count;
+}
+
+static ssize_t dmt_enable_show(struct device *dev, struct device_attribute *attr, char *buf){
+ return dmt_sysfs_enable_show( dev_get_drvdata(dev), buf, ACC_DATA_FLAG);
+}
+
+static ssize_t dmt_enable_store( struct device *dev, struct device_attribute *attr, char const *buf, size_t count){
+ return dmt_sysfs_enable_store( dev_get_drvdata(dev), buf, count, ACC_DATA_FLAG);
+}
+
+/* sysfs delay show & store*/
+static ssize_t dmt_sysfs_delay_show( struct dmt_data *dmt, char *buf, int pos){
+ return sprintf(buf, "%d\n", atomic_read(&dmt->delay));
+}
+
+static ssize_t dmt_sysfs_delay_store( struct dmt_data *dmt, char const *buf, size_t count, int pos){
+ long long val = 0;
+
+ if (NULL == buf)
+ return -EINVAL;
+
+ if (0 == count)
+ return 0;
+
+ if (false == get_value_as_int64(buf, count, &val))
+ return -EINVAL;
+
+ atomic_set(&dmt->delay, (unsigned int) val);
+ GSE_LOG("Driver attribute set delay =%lld\n", val);
+
+ return count;
+}
+
+static ssize_t dmt_delay_show( struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return dmt_sysfs_delay_show( dev_get_drvdata(dev), buf, ACC_DATA_FLAG);
+}
+
+static ssize_t dmt_delay_store( struct device *dev,
+ struct device_attribute *attr,
+ char const *buf,
+ size_t count)
+{
+ return dmt_sysfs_delay_store( dev_get_drvdata(dev), buf, count, ACC_DATA_FLAG);
+}
+/* sysfs position show & store */
+static ssize_t dmt_position_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+
+ return sprintf(buf, "%d\n", dmt_get_position(dmt->client));
+}
+
+static ssize_t dmt_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+ unsigned long position;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &position);
+ if (ret < 0)
+ return count;
+
+ dmt_set_position(dmt->client, position);
+ return count;
+}
+/* sysfs offset show & store */
+static ssize_t dmt_offset_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+ return sprintf(buf, "( %d %d %d )\n", dmt->offset.u.x, dmt->offset.u.y, dmt->offset.u.z);
+}
+
+static ssize_t dmt_offset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+ sscanf(buf, "%d %d %d", (int *)&dmt->offset.v[0], (int *)&dmt->offset.v[1], (int *)&dmt->offset.v[2]);
+ D09_write_offset_to_file(dmt->client);
+ update_var();
+ return count;
+}
+/* sysfs filter show & store */
+static ssize_t dmt_filter_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+
+ return sprintf(buf, "%d\n", dmt_get_filter(dmt->client));
+}
+
+static ssize_t dmt_filter_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+ unsigned long filter;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &filter);
+ if (ret < 0)
+ return count;
+
+ dmt_set_filter(dmt->client, filter);
+ return count;
+}
+
+/* sysfs data show */
+static ssize_t dmt_acc_private_data_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+ raw_data accel;
+
+ mutex_lock(&dmt->data_mutex);
+ accel = dmt->last;
+ mutex_unlock(&dmt->data_mutex);
+
+ return sprintf(buf, "( %d %d %d )\n", dmt->last.v[0], dmt->last.v[1], dmt->last.v[2]);
+}
+/* sysfs id show */
+static ssize_t dmt_id_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ char str[8]={GSENSOR_ID};
+ return sprintf(buf, "%s\n", str);
+}
+/* sysfs debug_suspend show & store */
+#ifdef DMT_DEBUG_DATA
+static ssize_t dmt_debug_suspend_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+ int suspend = dmt->suspend;
+
+ mutex_lock(&dmt->suspend_mutex);
+ suspend = sprintf(buf, "%d\n", dmt->suspend);
+ mutex_unlock(&dmt->suspend_mutex);
+ return suspend;
+}
+
+static ssize_t dmt_debug_suspend_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct dmt_data *dmt = input_get_drvdata(input);
+ unsigned long suspend;
+ pm_message_t msg;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &suspend);
+ if (ret < 0)
+ return count;
+
+ memset(&msg, 0, sizeof(pm_message_t));
+
+ mutex_lock(&dmt->suspend_mutex);
+
+ if (suspend) {
+ dmard09_suspend(dmt->pdevice, msg);
+ dmt->suspend = 1;
+ } else {
+ dmard09_resume(dmt->pdevice);
+ dmt->suspend = 0;
+ }
+
+ mutex_unlock(&dmt->suspend_mutex);
+
+ return count;
+}
+/* sysfs reg_read show & store */
+static ssize_t dmt_reg_read_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct dmt_data *dmt = dev_get_drvdata(dev);
+ int err;
+ unsigned char i2c[1];
+
+ i2c[0] = (unsigned char)atomic_read(&dmt->addr);
+ err = device_i2c_rxdata(dmt->client, i2c, 1);
+ if (err < 0)
+ return err;
+
+ return sprintf(buf, "0x%02X\n", i2c[0]);
+}
+
+static ssize_t dmt_reg_read_store(struct device *dev,
+ struct device_attribute *attr,
+ char const *buf,
+ size_t count)
+{
+ struct dmt_data *dmt = dev_get_drvdata(dev);
+ int addr = 0;
+
+ if (NULL == buf)
+ return -EINVAL;
+
+ if (0 == count)
+ return 0;
+
+ if (false == get_value_as_int(buf, count, &addr))
+ return -EINVAL;
+
+ if (addr < 0 || 128 < addr)
+ return -EINVAL;
+
+ atomic_set(&dmt->addr, addr);
+
+ return 1;
+}
+#endif /* DEBUG */
+/*********************************************************************
+ *
+ * SysFS attribute functions
+ *
+ * directory : /sys/class/accelemeter/dmardXX/
+ * files :
+ * - enable_acc [rw] [t] : enable flag for accelerometer
+ * - delay_acc [rw] [t] : delay in nanosecond for accelerometer
+ * - position [rw] [t] : chip mounting position
+ * - offset [rw] [t] : offset
+ * - data [r] [t] : raw data
+ * - id [r] [t] : chip id
+ *
+ * debug :
+ * - debug_suspend [w] [t] : suspend test
+ * - reg_read [rw] [t] : Read register
+ * - reg_write [rw] [t] : Weite register
+ *
+ * [rw]= read/write
+ * [r] = read only
+ * [w] = write only
+ * [b] = binary format
+ * [t] = text format
+ */
+
+static struct device_attribute DMT_attributes[] = {
+ __ATTR(enable_acc, 0660, dmt_enable_show, dmt_enable_store),
+ __ATTR(delay_acc, 0660, dmt_delay_show, dmt_delay_store),
+ __ATTR(position, 0660, dmt_position_show, dmt_position_store),
+ __ATTR(offset, 0660, dmt_offset_show, dmt_offset_store),
+ __ATTR(filter, 0660, dmt_filter_show, dmt_filter_store),
+ __ATTR(data, 0660, dmt_acc_private_data_show, NULL),
+ __ATTR(id, 0660, dmt_id_show, NULL),
+#ifdef DMT_DEBUG_DATA
+ __ATTR(debug_suspend, 0660, dmt_debug_suspend_show,dmt_debug_suspend_store),
+ __ATTR(reg_read, 0660, dmt_reg_read_show, dmt_reg_read_store),
+ __ATTR(reg_write, 0660, NULL, NULL),
+#endif // DEBUG
+ __ATTR_NULL,
+};
+
+static char const *const ACCELEMETER_CLASS_NAME = "accelemeter";
+static char const *const GSENSOR_DEVICE_NAME = SENSOR_I2C_NAME;
+static char const *const device_link_name = "i2c";
+static dev_t const dmt_device_dev_t = MKDEV(MISC_MAJOR, MISC_DYNAMIC_MINOR);
+
+// dmt sysfs functions
+static int create_device_attributes(struct device *dev, struct device_attribute *attrs){
+ int i;
+ int err = 0;
+ for (i = 0 ; NULL != attrs[i].attr.name ; ++i) {
+ err = device_create_file(dev, &attrs[i]);
+ if (0 != err)
+ break;
+ }
+
+ if (0 != err) {
+ for (; i >= 0 ; --i)
+ device_remove_file(dev, &attrs[i]);
+ }
+ return err;
+}
+
+static void remove_device_attributes(
+ struct device *dev,
+ struct device_attribute *attrs)
+{
+ int i;
+
+ for (i = 0 ; NULL != attrs[i].attr.name ; ++i)
+ device_remove_file(dev, &attrs[i]);
+}
+
+static int create_sysfs_interfaces(struct dmt_data *dmt)
+{
+ int err;
+
+ if (NULL == dmt)
+ return -EINVAL;
+
+ err = 0;
+ dmt->class = class_create(THIS_MODULE, ACCELEMETER_CLASS_NAME);
+ if (IS_ERR(dmt->class)) {
+ err = PTR_ERR(dmt->class);
+ goto exit_class_create_failed;
+ }
+
+ dmt->class_dev = device_create(
+ dmt->class,
+ NULL,
+ dmt_device_dev_t,
+ dmt,
+ GSENSOR_DEVICE_NAME);
+ if (IS_ERR(dmt->class_dev)) {
+ err = PTR_ERR(dmt->class_dev);
+ goto exit_class_device_create_failed;
+ }
+
+ err = sysfs_create_link(
+ &dmt->class_dev->kobj,
+ &dmt->client->dev.kobj,
+ device_link_name);
+ if (0 > err)
+ goto exit_sysfs_create_link_failed;
+
+ err = create_device_attributes(
+ dmt->class_dev,
+ DMT_attributes);
+ if (0 > err)
+ goto exit_device_attributes_create_failed;
+#if 0
+ err = create_device_binary_attributes(
+ &dmt->class_dev->kobj,
+ dmt_bin_attributes);
+ if (0 > err)
+ goto exit_device_binary_attributes_create_failed;
+#endif
+
+ return err;
+
+#if 0
+exit_device_binary_attributes_create_failed:
+ remove_device_attributes(dmt->class_dev, dmt_attributes);
+#endif
+exit_device_attributes_create_failed:
+ sysfs_remove_link(&dmt->class_dev->kobj, device_link_name);
+exit_sysfs_create_link_failed:
+ device_destroy(dmt->class, dmt_device_dev_t);
+exit_class_device_create_failed:
+ dmt->class_dev = NULL;
+ class_destroy(dmt->class);
+exit_class_create_failed:
+ dmt->class = NULL;
+ return err;
+}
+
+static void remove_sysfs_interfaces(struct dmt_data *dmt){
+ if (NULL == dmt)
+ return;
+
+ if (NULL != dmt->class_dev) {
+
+ remove_device_attributes(
+ dmt->class_dev,
+ DMT_attributes);
+ sysfs_remove_link(
+ &dmt->class_dev->kobj,
+ device_link_name);
+ dmt->class_dev = NULL;
+ }
+ if (NULL != dmt->class) {
+ device_destroy(
+ dmt->class,
+ dmt_device_dev_t);
+ class_destroy(dmt->class);
+ dmt->class = NULL;
+ }
+}
+
+int D09_input_init(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ int err = 0;
+ dmt->input = input_allocate_device();
+ if (!dmt->input){
+ GSE_ERR("input device allocate ERROR !!\n");
+ return -ENOMEM;
+ }
+ else
+ GSE_LOG("input device allocate Success !!\n");
+ /* Setup input device */
+ //dmt->input->name = SENSOR_I2C_NAME;
+ set_bit(EV_ABS, dmt->input->evbit);
+ /* Accelerometer [-78.5, 78.5]m/s2 in Q16 */
+ input_set_abs_params(dmt->input, ABS_X, ABSMIN, ABSMAX, 0, 0);
+ input_set_abs_params(dmt->input, ABS_Y, ABSMIN, ABSMAX, 0, 0);
+ input_set_abs_params(dmt->input, ABS_Z, ABSMIN, ABSMAX, 0, 0);
+ /* Set InputDevice Name */
+ dmt->input->name = INPUT_NAME_ACC;
+ /* Register */
+ err = input_register_device(dmt->input);
+ if (err) {
+ GSE_ERR("input_register_device ERROR !!\n");
+ input_free_device(dmt->input);
+ return err;
+ }
+ GSE_LOG("input_register_device SUCCESS %d !! \n",err);
+
+ return err;
+}
+
+int D09_calibrate(struct i2c_client *client)
+{
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ raw_data avg;
+ int i, j;
+ long xyz_acc[SENSOR_DATA_SIZE];
+ int xyz[SENSOR_DATA_SIZE];
+ /* initialize the offset value */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ dmt->offset.v[i] = 0;
+ /* initialize the accumulation buffer */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ xyz_acc[i] = 0;
+
+ for(i = 0; i < AVG_NUM; i++) {
+ D09_i2c_read_xyz(client, (int *)&xyz);
+ for(j = 0; j < SENSOR_DATA_SIZE; ++j)
+ xyz_acc[j] += xyz[j];
+ }
+ /* calculate averages */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ avg.v[i] = xyz_acc[i] / AVG_NUM;
+
+ if(avg.v[2] < 0){
+ dmt->offset.u.x = avg.v[0] ;
+ dmt->offset.u.y = avg.v[1] ;
+ dmt->offset.u.z = avg.v[2] + DEFAULT_SENSITIVITY;
+ return CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_POSITIVE;
+ }
+ else{
+ dmt->offset.u.x = avg.v[0] ;
+ dmt->offset.u.y = avg.v[1] ;
+ dmt->offset.u.z = avg.v[2] - DEFAULT_SENSITIVITY;
+ return CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_NEGATIVE;
+ }
+ return 0;
+}
+
+int dmard09_init(struct i2c_client *client){
+
+ //struct dmt_data *dmt = i2c_get_clientdata(client);
+ unsigned char buffer[7];
+ /* 1. Active Mode */
+ buffer[0] = REG_ACTR;
+ buffer[1] = MODE_ACTIVE;
+ device_i2c_txdata(client, buffer, 2);
+ /* 2. check D09 who am I */
+ buffer[0] = REG_DC;
+ device_i2c_rxdata(client, buffer, 1);
+ if (buffer[0] == VALUE_WHO_AM_I)
+ {
+ printk(KERN_INFO GSE_TAG"D09 WHO_AM_I_VALUE = %d \n", buffer[0]);
+ GSE_LOG("D09 registered I2C driver!\n");
+ }
+ else
+ {
+ GSE_ERR("gsensor I2C err = %d!\n", buffer[0]);
+ return -1;
+ }
+ /* 3. Set Data conversion rate*/
+ buffer[0] = REG_CNT_L1;
+ buffer[1] = VALUE_ODR_100;
+ buffer[2] = VALUE_CNT_L2;
+ device_i2c_txdata(client, buffer, 3);
+ /* 4. open hardware filter */
+ buffer[0] = REG_ODF;
+ buffer[1] = ODF_Ave_4;
+ buffer[2] = 0x00;
+ device_i2c_txdata(client, buffer, 3);
+ /* 5. check hardware filter again */
+ buffer[0] = REG_ODF; //0x07 smooth filter 1/8 Bandwidth */
+ device_i2c_rxdata(client, buffer, 2);
+ printk(KERN_INFO GSE_TAG" REG_ODF = %x , %x\n", buffer[0] , buffer[1]);
+
+ return 0;
+}
+
+void D09_set_offset(struct i2c_client *client, int val[3]){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ int i;
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ dmt->offset.v[i] = val[i];
+}
+
+struct file_operations sensor_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = device_ioctl,
+ .open = device_open,
+ .release = device_close,
+};
+
+static struct miscdevice dmt_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = SENSOR_I2C_NAME,
+ .fops = &sensor_fops,
+};
+
+static int sensor_close_dev(struct i2c_client *client){
+ char buffer[3];
+ buffer[0] = REG_ACTR;
+ device_i2c_rxdata(client, buffer, 2);
+ buffer[1] = buffer[0] & 0xFE; //Mask off last bit (POWER DOWN MODE)
+ //buffer[1] = MODE_POWERDOWN;
+ device_i2c_txdata(client,buffer, 2);
+ return 0;
+}
+
+static void dmard09_shutdown(struct platform_device *pdev)
+{
+ flush_delayed_work_sync(&s_dmt->delaywork);
+ DMT_sysfs_update_active_status(s_dmt , 0);
+}
+
+
+//static int device_i2c_suspend(struct i2c_client *client, pm_message_t mesg){
+static int dmard09_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct dmt_data *dmt = i2c_get_clientdata(s_dmt->client);
+ flush_delayed_work_sync(&dmt->delaywork);
+ DMT_sysfs_update_active_status(dmt , 0);
+ return sensor_close_dev(dmt->client);
+}
+
+//static int device_i2c_resume(struct i2c_client *client){
+static int dmard09_resume(struct platform_device *pdev)
+{
+ struct dmt_data *dmt = i2c_get_clientdata(s_dmt->client);
+ int en = 1;
+ GSE_FUN();
+ printk("dmt->enable=%d",dmt->enable);
+ dmard09_init(dmt->client);
+ atomic_set(&dmt->enable,en);
+ DMT_sysfs_update_active_status(dmt , en);
+ return 0;
+}
+/*
+static int __devexit device_i2c_remove(struct i2c_client *client){
+ return 0;
+}
+
+static const struct i2c_device_id device_i2c_ids[] = {
+ { SENSOR_I2C_NAME, 0},
+ { }
+};
+
+static struct i2c_driver device_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_I2C_NAME,
+ },
+ .class = I2C_CLASS_HWMON,
+ .id_table = device_i2c_ids,
+ .probe = device_i2c_probe,
+ .remove = __devexit_p(device_i2c_remove),
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ .suspend = device_i2c_suspend,
+ .resume = device_i2c_resume,
+#endif
+};
+*/
+static int device_open(struct inode *inode, struct file *filp){
+ return 0;
+}
+
+static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg){
+ //struct i2c_client *client = (struct i2c_client *)file->private_data;
+ //struct dmt_data *dmt = (struct dmt_data*)i2c_get_clientdata(client);
+
+ int err = 0, ret = 0, i;
+ int intBuf[SENSOR_DATA_SIZE], xyz[SENSOR_DATA_SIZE];
+ /* check type */
+ if (_IOC_TYPE(cmd) != IOCTL_MAGIC) return -ENOTTY;
+
+ /* check user space pointer is valid */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
+ if (err) return -EFAULT;
+
+ switch(cmd) {
+ case SENSOR_RESET:
+ ret = dmard09_init(s_dmt->client);
+ return ret;
+
+ case SENSOR_CALIBRATION:
+ /* get orientation info */
+ //if(copy_from_user(&intBuf, (int*)arg, sizeof(intBuf))) return -EFAULT;
+ D09_calibrate(s_dmt->client);
+ GSE_LOG("Sensor_calibration:%d %d %d\n", s_dmt->offset.u.x, s_dmt->offset.u.y, s_dmt->offset.u.z);
+ /* save file */
+ D09_write_offset_to_file(s_dmt->client);
+ update_var();
+
+ /* return the offset */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = s_dmt->offset.v[i];
+
+ ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_GET_OFFSET:
+ /* get data from file */
+ D09_read_offset_from_file(s_dmt->client);
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = s_dmt->offset.v[i];
+
+ ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_SET_OFFSET:
+ ret = copy_from_user(&intBuf, (int *)arg, sizeof(intBuf));
+ D09_set_offset(s_dmt->client , intBuf);
+ /* write into file */
+ D09_write_offset_to_file(s_dmt->client);
+ update_var();
+ return ret;
+
+ case SENSOR_READ_ACCEL_XYZ:
+ D09_i2c_read_xyz(s_dmt->client, (int *)&xyz);
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = xyz[i] - s_dmt->offset.v[i];
+
+ ret = copy_to_user((int*)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_SETYPR:
+ if(copy_from_user(&intBuf, (int*)arg, sizeof(intBuf))) {
+ GSE_LOG("%s: -EFAULT\n",__func__);
+ return -EFAULT;
+ }
+ input_report_abs(s_dmt->input, ABS_X, intBuf[0]);
+ input_report_abs(s_dmt->input, ABS_Y, intBuf[1]);
+ input_report_abs(s_dmt->input, ABS_Z, intBuf[2]);
+ input_sync(s_dmt->input);
+ GSE_LOG("SENSOR_SETYPR OK! x=%d,y=%d,z=%d\n",intBuf[0],intBuf[1],intBuf[2]);
+ return ret;
+
+ case SENSOR_GET_OPEN_STATUS:
+ GSE_LOG("Going into DMT_GetOpenStatus()\n");
+ ret = DMT_GetOpenStatus(s_dmt->client);
+ return ret;
+
+ case SENSOR_GET_CLOSE_STATUS:
+ GSE_LOG("Going into DMT_GetCloseStatus()\n");
+ ret = DMT_GetCloseStatus(s_dmt->client);
+ return ret;
+
+ case SENSOR_GET_DELAY:
+ ret = copy_to_user((int*)arg, &interval, sizeof(interval));
+ return ret;
+
+ default: /* redundant, as cmd was checked against MAXNR */
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static int device_close(struct inode *inode, struct file *filp){
+ return 0;
+}
+
+/***** I2C I/O function ***********************************************/
+static int device_i2c_rxdata( struct i2c_client *client, unsigned char *rxData, int length){
+ struct i2c_msg msgs[] = {
+ {.addr = client->addr, .flags = 0, .len = 1, .buf = rxData,},
+ {.addr = client->addr, .flags = I2C_M_RD, .len = length, .buf = rxData,},
+ };
+ //unsigned char addr = rxData[0];
+ if (i2c_transfer(client->adapter, msgs, 2) < 0) {
+ dev_err(&client->dev, "%s: transfer failed.", __func__);
+ return -EIO;
+ }
+ //DMT_DATA(&client->dev, "RxData: len=%02x, addr=%02x, data=%02x\n",
+ //length, addr, rxData[0]);
+
+ return 0;
+}
+
+static int device_i2c_txdata( struct i2c_client *client, unsigned char *txData, int length){
+ struct i2c_msg msg[] = {
+ {.addr = client->addr, .flags = 0, .len = length, .buf = txData,},
+ };
+
+ if (i2c_transfer(client->adapter, msg, 1) < 0) {
+ dev_err(&client->dev, "%s: transfer failed.", __func__);
+ return -EIO;
+ }
+ //DMT_DATA(&client->dev, "TxData: len=%02x, addr=%02x data=%02x\n",
+ //length, txData[0], txData[1]);
+ return 0;
+}
+
+static int D09_i2c_read_xyz(struct i2c_client *client, int *xyz_p){
+
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ u8 buffer[11];
+ s16 xyzTmp[SENSOR_DATA_SIZE];
+ int pos = dmt->position;
+ int i, j , k;
+ /* get xyz high/low bytes, 0x0A */
+ buffer[0] = REG_STAT;
+ /* Read acceleration data */
+ if (device_i2c_rxdata(client, buffer, 8)!= 0)
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ {
+ xyz_p[i] = 0;
+ xyzTmp[i] = 0;
+ }
+ else
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ xyz_p[i] = 0;
+ xyzTmp[i] = 0;
+ /* merge xyz high/low bytes & 1g = 128 becomes 1g = 1024 */
+ mutex_lock(&dmt->data_mutex);
+ xyzTmp[i] =(((int16_t)((buffer[2*(i+1)+1] << 8)) | buffer[2*(i+1)] ) >> 3) << 5;
+ mutex_unlock(&dmt->data_mutex);
+ }
+#ifdef SW_FILTER
+ if( dmt->aveflag >= dmt->filter){
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ dmt->sum[i] = dmt->sum[i] - dmt->bufferave[i][dmt->pointer] + xyzTmp[i];
+ }
+ /* transfer to the default layout */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ for(j = 0; j < SENSOR_DATA_SIZE; j++)
+ xyz_p[i] += (int)(dmt->sum[j]/dmt->filter * dmt_position_map[pos][i][j]);
+ }
+ }
+ else{
+ /* init dmt->sum */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ dmt->sum[i] = xyzTmp[i];
+#endif
+ /* transfer to the default layout */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ for(j = 0; j < SENSOR_DATA_SIZE; j++){
+ xyz_p[i] += (int)(xyzTmp[j] * dmt_position_map[pos][i][j]);
+ //GSE_LOG("%04d, %04d,%d \n", xyz_p[i], xyzTmp[j], dmt_position_map[pos][i][j]);
+ }
+ }
+ //GSE_LOG("xyz_p: %04d , %04d , %04d\n", xyz_p[0], xyz_p[1], xyz_p[2]);
+#ifdef SW_FILTER
+ dmt->aveflag++;
+ }
+ /* init dmt->sum */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ dmt->sum[i] = 0;
+ }
+ dmt->pointer++;
+ dmt->pointer %= dmt->filter;
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ dmt->bufferave[i][dmt->pointer] = xyzTmp[i];
+ }
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ for(k = 0; k < dmt->filter; ++k){
+ dmt->sum[i] += dmt->bufferave[i][k];
+ }
+ }
+#endif
+ return 0;
+}
+
+static void DMT_work_func(struct work_struct *delaywork){
+ struct dmt_data *dmt = container_of(delaywork, struct dmt_data, delaywork.work);
+ int i;
+ //static bool firsttime=true;
+ raw_data xyz;
+ unsigned long dmt_delay = msecs_to_jiffies(atomic_read(&dmt->delay));
+
+
+ D09_i2c_read_xyz(dmt->client, (int *)&xyz.v);
+ /* dmt->last = RawData - Offset */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ dmt->last.v[i] = xyz.v[i] - dmt->offset.v[i];
+ //GSE_LOG("@DMTRaw @ X/Y/Z axis: %04d , %04d , %04d\n", xyz.v[0], xyz.v[1], xyz.v[2]);
+ //GSE_LOG("@Offset @ X/Y/Z axis: %04d , %04d , %04d\n", dmt->offset.u.x, dmt->offset.u.y, dmt->offset.u.z);
+ //GSE_LOG("@Raw-Offset@ X/Y/Z axis: %04d , %04d , %04d ,dmt_delay=%d\n", dmt->last.u.x, dmt->last.u.y, dmt->last.u.z, atomic_read(&dmt->delay));
+
+#ifdef STABLE_VALUE_FUNCTION
+ if(abs(dmt->last.v[0])< RANGE_XYZ){ dmt->last.v[0] = 0;}
+ if(abs(dmt->last.v[1])< RANGE_XYZ){ dmt->last.v[1] = 0;}
+ if(abs(dmt->last.v[2])< RANGE_XYZ){ dmt->last.v[2] = 0;}
+#endif
+
+
+ input_report_abs(dmt->input, ABS_X, -dmt->last.v[l_sensorconfig.xyz_axis[0][0]]*l_sensorconfig.xyz_axis[0][1]);//dmt->last.v[0]);
+ input_report_abs(dmt->input, ABS_Y, -dmt->last.v[l_sensorconfig.xyz_axis[1][0]]*l_sensorconfig.xyz_axis[1][1]);//dmt->last.v[1]);
+ input_report_abs(dmt->input, ABS_Z, -dmt->last.v[l_sensorconfig.xyz_axis[2][0]]*l_sensorconfig.xyz_axis[2][1]);//dmt->last.v[2]);
+ input_sync(dmt->input);
+
+ if(dmt_delay < 1)
+ dmt_delay = 1;
+ schedule_delayed_work(&dmt->delaywork, dmt_delay);
+}
+
+static int mma09_open(struct inode *node, struct file *fle)
+{
+ GSE_LOG("open...\n");
+ return 0;
+}
+
+static int mma09_close(struct inode *node, struct file *fle)
+{
+ GSE_LOG("close...\n");
+ return 0;
+}
+
+static long mma09_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ //unsigned char data[6];
+ void __user *argp = (void __user *)arg;
+ short delay, enable;
+ unsigned int uval = 0;
+
+
+ /* cmd mapping */
+ 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");
+ return -EFAULT;
+ }
+ klog("Get delay=%d\n", delay);
+
+ if ((delay >=0) && (delay < 20))
+ {
+ delay = 20;
+ } else if (delay > 200)
+ {
+ delay = 200;
+ }
+ l_sensorconfig.sensor_samp = 1000/delay;
+ atomic_set(&s_dmt->delay, 1000/delay);
+ 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");
+ return -EFAULT;
+ }
+ klog("enable=%d\n",enable);
+ if ((enable >=0) && (enable <=1))
+ {
+ //KMSGINF("driver: disable/enable(%d) gsensor.\n", enable);
+
+ l_sensorconfig.sensor_enable = enable;
+ atomic_set(&s_dmt->enable,enable);
+ DMT_sysfs_update_active_status(s_dmt , enable);
+
+ } else {
+ printk(KERN_ERR "Wrong enable argument in %s !!!\n", __FUNCTION__);
+ return -EINVAL;
+ }
+ break;
+ case WMT_IOCTL_SENSOR_GET_DRVID:
+ uval = DMARD09_DRVID;//;
+ if (copy_to_user((unsigned int*)arg, &uval, sizeof(unsigned int)))
+ {
+ return -EFAULT;
+ }
+ GSE_LOG("dmard09_driver_id:%d\n",uval);
+ break;
+ case WMT_IOCTL_SENOR_GET_RESOLUTION:
+ uval = (10<<8) | 1;
+ if (copy_to_user((unsigned int *)arg, &uval, sizeof(unsigned int)))
+ {
+ return -EFAULT;
+ }
+ printk("<<<<<<<resolution:0x%x\n",uval);
+ default:
+ err = -1;
+ break;
+ }
+
+ return err;
+}
+
+static const struct file_operations d09_fops = {
+ .owner = THIS_MODULE,
+ .open = mma09_open,
+ .release = mma09_close,
+ .unlocked_ioctl = mma09_ioctl,
+};
+
+
+static struct miscdevice d09_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = GSENSOR_DEV_NODE,
+ .fops = &d09_fops,
+};
+
+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)
+ {
+ // should do sth
+ }
+ //printk(KERN_ALERT "sensor samp=%d(amsr:%d) has been set.\n", sample, amsr);
+ } else {
+ klog("Wrong sample argumnet of sensor.\n");
+ }
+ } else if (sscanf(buffer, "enable=%d\n", &enable))
+ {
+ if ((enable < 0) || (enable > 1))
+ {
+ klog("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;
+ atomic_set(&s_dmt->enable,1);
+ DMT_sysfs_update_active_status(s_dmt , 1);
+ } else if (sscanf(buffer, "sensor_testend=%d\n", &test))
+ { // Don nothing only to be compatible the before testing program
+ atomic_set(&s_dmt->enable,0);
+ DMT_sysfs_update_active_status(s_dmt , 0);
+ }
+ //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;
+}
+
+
+//static int __devinit device_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id){
+static int __devinit dmard09_probe(struct platform_device *pdev)
+{
+ int i, k, ret = 0;
+ //struct dmt_data *s_dmt = i2c_get_clientdata(client);
+ //struct dmt_data *s_dmt;
+ GSE_FUN();
+/*
+ if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){
+ GSE_ERR("check_functionality failed.\n");
+ ret = -ENODEV;
+ goto exit0;
+ }
+
+ // Allocate memory for driver data
+ s_dmt = kzalloc(sizeof(struct dmt_data), GFP_KERNEL);
+ memset(s_dmt, 0, sizeof(struct dmt_data));
+ if (s_dmt == NULL) {
+ GSE_ERR("alloc data failed.\n");
+ ret = -ENOMEM;
+ goto exit1;
+ }
+*/
+ /*for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ s_dmt->offset.v[i] = 0;*/
+#ifdef SW_FILTER
+ s_dmt->pointer = 0;
+ s_dmt->aveflag = 0;
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ s_dmt->sum[i] = 0;
+ for(k = 0; k < SENSOR_DATA_AVG; ++k){
+ s_dmt->bufferave[i][k] = 0;
+ }
+ }
+ s_dmt->filter = SENSOR_DATA_AVG;
+ GSE_LOG("D09_DEFAULT_FILTER: %d\n", s_dmt->filter);
+#endif
+ /* I2C initialization */
+ //s_dmt->client = client;
+
+ /* set client data */
+ i2c_set_clientdata(s_dmt->client, s_dmt);
+ /*ret = dmard09_init(client);
+ if (ret < 0)
+ goto exit2;
+ */
+ /* input */
+ ret = D09_input_init(s_dmt->client);
+ if (ret){
+ GSE_ERR("D09_input_init fail, error code= %d\n",ret);
+ goto exit3;
+ }
+
+ /* initialize variables in dmt_data */
+ mutex_init(&s_dmt->data_mutex);
+ mutex_init(&s_dmt->enable_mutex);
+#ifdef DMT_DEBUG_DATA
+ mutex_init(&s_dmt->suspend_mutex);
+#endif
+ init_waitqueue_head(&s_dmt->open_wq);
+ atomic_set(&s_dmt->active, 0);
+ atomic_set(&s_dmt->enable, 0);
+ atomic_set(&s_dmt->delay, 0);
+ atomic_set(&s_dmt->addr, 0);
+ /* DMT Acceleration Sensor Mounting Position on Board */
+ s_dmt->position = D09_DEFAULT_POSITION;
+ GSE_LOG("D09_DEFAULT_POSITION: %d\n", s_dmt->position);
+ //s_dmt->position = (CONFIG_INPUT_DMT_ACCELEROMETER_POSITION);
+ //GSE_LOG("CONFIG_INPUT_DMT_ACCELEROMETER_POSITION: %d\n", s_dmt->position);
+ /* Misc device */
+ if (misc_register(&dmt_device) < 0){
+ GSE_ERR("dmt_dev register failed");
+ goto exit4;
+ }
+
+ /* Setup sysfs */
+ if (create_sysfs_interfaces(s_dmt) < 0){
+ GSE_ERR("create sysfs failed.");
+ goto exit5;
+ }
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ s_dmt->early_suspend.suspend = device_i2c_suspend;
+ s_dmt->early_suspend.resume = device_i2c_resume;
+ register_early_suspend(&s_dmt->early_suspend);
+#endif
+ /* Setup driver interface */
+ INIT_DELAYED_WORK(&s_dmt->delaywork, DMT_work_func);
+ GSE_LOG("DMT: INIT_DELAYED_WORK\n");
+
+ //register ctrl dev
+ ret = misc_register(&d09_device);
+ if (ret !=0) {
+ errlog("Can't register d09_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;
+ }
+
+ //create offset file after factory reset
+ D09_read_offset_from_file(s_dmt->client);
+
+ return 0;
+
+exit5:
+ misc_deregister(&dmt_device);
+exit4:
+ input_unregister_device(s_dmt->input);
+exit3:
+ kfree(s_dmt);
+/*exit2:
+exit1:
+exit0:*/
+ return ret;
+}
+/*
+static struct i2c_board_info dmard09_board_info={
+ .type = SENSOR_I2C_NAME,
+ .addr = SENSOR_I2C_ADDR,
+};
+*/
+//static struct i2c_client *client;
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+static int get_axisset(void)
+{
+ char varbuf[64];
+ int n;
+ int varlen;
+
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+ if (wmt_getsyspara("wmt.io.dm09sensor", varbuf, &varlen)) {
+ errlog("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) {
+ errlog("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:%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],
+ l_sensorconfig.offset[0],
+ l_sensorconfig.offset[1],
+ l_sensorconfig.offset[2]
+ );
+ }
+ return 0;
+}
+
+static void dmard09_platform_release(struct device *device)
+{
+ GSE_LOG("...\n");
+ return;
+}
+
+static int __devexit dmard09_remove(struct platform_device *pdev)
+{
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ remove_proc_entry(GSENSOR_PROC_NAME, NULL);
+ l_sensorconfig.sensor_proc = NULL;
+ }
+ //misc_deregister(&d09_device);
+ return 0;
+}
+
+
+static struct platform_device dmard09_device = {
+ .name = SENSOR_I2C_NAME,
+ .id = 0,
+ .dev = {
+ .release = dmard09_platform_release,
+ },
+};
+
+static struct platform_driver dmard09_driver = {
+ .probe = dmard09_probe,
+ .remove = dmard09_remove,
+ .shutdown = dmard09_shutdown,
+ .suspend = dmard09_suspend,
+ .resume = dmard09_resume,
+ .driver = {
+ .name = SENSOR_I2C_NAME,
+ },
+};
+
+
+static int __init device_init(void){
+ //struct device *device;
+ struct i2c_client *this_client;
+ int ret = 0;
+
+ // parse g-sensor u-boot arg
+ ret = get_axisset();
+ if (ret < 0)
+ {
+ printk("<<<<<%s user choose to no sensor chip!\n", __func__);
+ return ret;
+ }
+ GSE_LOG("D09 gsensor driver: initialize.\n");
+
+ if (!(this_client = sensor_i2c_register_device(0, DEVICE_I2C_ADDR, SENSOR_I2C_NAME)))
+ {
+ printk(KERN_ERR"Can't register gsensor i2c device!\n");
+ return -1;
+ }
+
+ if (dmard09_init(this_client))
+ {
+ GSE_ERR("Failed to init dmard09!\n");
+ sensor_i2c_unregister_device(this_client);
+ return -1;
+ }
+
+ /* Allocate memory for driver data */
+ s_dmt = kzalloc(sizeof(struct dmt_data), GFP_KERNEL);
+ //memset(s_dmt, 0, sizeof(struct dmt_data));
+ if (s_dmt == NULL) {
+ GSE_ERR("alloc data failed.\n");
+ return -ENOMEM;
+ }
+
+ s_dmt->client = this_client;
+ s_dmt->pdevice = &dmard09_device;
+ s_dmt->offset.u.x = l_sensorconfig.offset[0];
+ s_dmt->offset.u.y = l_sensorconfig.offset[1];
+ s_dmt->offset.u.z = l_sensorconfig.offset[2];
+
+
+ // create the platform device
+ l_dev_class = class_create(THIS_MODULE, SENSOR_I2C_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;
+ }
+ if((ret = platform_device_register(&dmard09_device)))
+ {
+ GSE_ERR("Can't register dmard09 platform devcie!!!\n");
+ return ret;
+ }
+ if ((ret = platform_driver_register(&dmard09_driver)) != 0)
+ {
+ GSE_ERR("Can't register dmard09 platform driver!!!\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit device_exit(void){
+ //i2c_unregister_device(client);
+ //i2c_del_driver(&device_i2c_driver);
+ GSE_LOG("D09 gsensor driver: release.\n");
+
+ flush_delayed_work_sync(&s_dmt->delaywork);
+ cancel_delayed_work_sync(&s_dmt->delaywork);
+
+ input_unregister_device(s_dmt->input);
+ input_free_device(s_dmt->input);
+ misc_deregister(&dmt_device);
+ misc_deregister(&d09_device);
+ platform_driver_unregister(&dmard09_driver);
+ platform_device_unregister(&dmard09_device);
+ sensor_i2c_unregister_device(s_dmt->client);
+ class_destroy(l_dev_class);
+
+ remove_sysfs_interfaces(s_dmt);
+ kfree(s_dmt);
+}
+
+static int dmt_get_filter(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ return dmt->filter;
+}
+
+static int dmt_set_filter(struct i2c_client *client, int filter){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ if (!((filter >= 1) && (filter <= 32)))
+ return -1;
+ dmt->filter = filter;
+ return 0;
+}
+
+static int dmt_get_position(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ return dmt->position;
+}
+
+static int dmt_set_position(struct i2c_client *client, int position){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ if (!((position >= 0) && (position <= 7)))
+ return -1;
+ dmt->position = position;
+ return 0;
+}
+
+extern int wmt_setsyspara(char *varname, char *varval);
+static void update_var(void)
+{
+ char varbuf[64];
+ int varlen;
+
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+
+ sprintf(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],
+ s_dmt->offset.u.x,
+ s_dmt->offset.u.y,
+ s_dmt->offset.u.z
+ );
+
+ wmt_setsyspara("wmt.io.dm09sensor",varbuf);
+}
+
+static int D09_write_offset_to_file(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ char r_buf[18] = {0};
+ char w_buf[18] = {0};
+ //unsigned int orgfs;
+ struct file *fp;
+ mm_segment_t fs;
+ ssize_t ret;
+ //int8_t i;
+
+ sprintf(w_buf,"%5d %5d %5d", dmt->offset.u.x, dmt->offset.u.y, dmt->offset.u.z);
+ /* Set segment descriptor associated to kernel space */
+ fp = filp_open(D09_OffsetFileName, O_RDWR | O_CREAT, 0777);
+ if(IS_ERR(fp)){
+ GSE_ERR("filp_open %s error!!.:%d\n",D09_OffsetFileName,fp);
+ return -1;
+ }
+ else{
+ fs = get_fs();
+ //set_fs(KERNEL_DS);
+ set_fs(get_ds());
+ GSE_LOG("filp_open %s SUCCESS!!.\n",D09_OffsetFileName);
+ //fp->f_op->write(fp,data,18, &fp->f_pos);
+ //filp_close(fp,NULL);
+ ret = fp->f_op->write(fp,w_buf,18,&fp->f_pos);
+ if(ret != 18)
+ {
+ printk(KERN_ERR "%s: write error!\n", __func__);
+ filp_close(fp,NULL);
+ return -EIO;
+ }
+ //fp->f_pos=0x00;
+ ret = fp->f_op->read(fp,r_buf, 18,&fp->f_pos);
+ if(ret < 0)
+ {
+ printk(KERN_ERR "%s: read error!\n", __func__);
+ filp_close(fp,NULL);
+ return -EIO;
+ }
+ set_fs(fs);
+
+ //
+ //printk(KERN_INFO "%s: read ret=%d!", __func__, ret);
+ /* for(i=0; i<18 ;i++)
+ {
+ if(r_buf[i] != w_buf[i])
+ {
+ printk(KERN_ERR "%s: read back error, r_buf[%x](0x%x) != w_buf[%x](0x%x)\n",
+ __func__, i, r_buf[i], i, w_buf[i]);
+ filp_close(fp,NULL);
+ return -EIO;
+ }
+ }
+ */
+
+ }
+ filp_close(fp,NULL);
+ return 0;
+}
+
+void D09_read_offset_from_file(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ unsigned int orgfs;
+ char data[18];
+ struct file *fp;
+ int ux,uy,uz;
+ orgfs = get_fs();
+ /* Set segment descriptor associated to kernel space */
+ set_fs(KERNEL_DS);
+
+ fp = filp_open(D09_OffsetFileName, O_RDWR , 0);
+ GSE_FUN();
+ if(IS_ERR(fp)){
+ GSE_ERR("Sorry,file open ERROR !\n");
+ if(l_sensorconfig.op){ //first time
+ l_sensorconfig.op=0;
+#if AUTO_CALIBRATION
+ /* get acceleration average reading */
+ D09_calibrate(client);
+ update_var();
+ D09_write_offset_to_file(client);
+#endif
+#ifdef DMT_BROADCAST_APK_ENABLE
+ create_devidfile();
+ return;
+#endif
+ }
+ D09_write_offset_to_file(client);
+ }
+ else{
+ GSE_LOG("filp_open %s SUCCESS!!.\n",D09_OffsetFileName);
+ fp->f_op->read(fp,data,18, &fp->f_pos);
+ GSE_LOG("filp_read result %s\n",data);
+ sscanf(data,"%d %d %d",&ux,&uy,&uz);
+ dmt->offset.u.x=ux;
+ dmt->offset.u.y=uy;
+ dmt->offset.u.z=uz;
+ }
+ set_fs(orgfs);
+}
+static int create_devidfile(void)
+{
+ char data[18];
+ unsigned int orgfs;
+ struct file *fp;
+
+ sprintf(data,"%5d %5d %5d",0,0,0);
+ orgfs = get_fs();
+ /* Set segment descriptor associated to kernel space */
+ set_fs(KERNEL_DS);
+ GSE_FUN();
+ fp = filp_open(DmtXXFileName, O_RDWR | O_CREAT, 0777);
+ if(IS_ERR(fp)){
+ GSE_ERR("Sorry,file open ERROR !\n");
+ return -1;
+ }
+ fp->f_op->write(fp,data,18, &fp->f_pos);
+ set_fs(orgfs);
+ filp_close(fp,NULL);
+ return 0;
+}
+//*********************************************************************************************************
+MODULE_AUTHOR("DMT_RD");
+MODULE_DESCRIPTION("DMT Gsensor Driver");
+MODULE_LICENSE("GPL");
+
+module_init(device_init);
+module_exit(device_exit);
diff --git a/drivers/input/sensor/dmard09_gsensor/dmt09.h b/drivers/input/sensor/dmard09_gsensor/dmt09.h
new file mode 100755
index 00000000..d30e606a
--- /dev/null
+++ b/drivers/input/sensor/dmard09_gsensor/dmt09.h
@@ -0,0 +1,183 @@
+/* @version 1.03
+ * Copyright 2011 Domintech Technology Co., Ltd
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef DMT09_H
+#define DMT09_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include <linux/syscalls.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+//#include <linux/earlysuspend.h>
+#define AUTO_CALIBRATION 0
+#define SW_FILTER /* Enable or Disable Software filter */
+#define SENSOR_DATA_AVG 4//8 /* AVG sensor data */
+
+#define STABLE_VALUE_FUNCTION
+#define RANGE_XYZ 40
+
+//#define DMT_DEBUG_DATA
+#define GSE_TAG "[DMT_Gsensor]"
+#ifdef DMT_DEBUG_DATA
+#define GSE_ERR(fmt, args...) printk(KERN_ERR GSE_TAG"%s %d : "fmt, __FUNCTION__, __LINE__, ##args)
+#define GSE_LOG(fmt, args...) printk(KERN_INFO GSE_TAG fmt, ##args)
+#define GSE_FUN(f) printk(KERN_INFO GSE_TAG" %s: %s: %i\n", __FILE__, __func__, __LINE__)
+#define DMT_DATA(dev, ...) dev_dbg((dev), ##__VA_ARGS__)
+#else
+#define GSE_ERR(fmt, args...)
+#define GSE_LOG(fmt, args...)
+#define GSE_FUN(f)
+#define DMT_DATA(dev, format, ...)
+#endif
+
+#define GSENSOR_ID "DMARD09"
+#define INPUT_NAME_ACC "g-sensor"//"DMT_accel"//"g-sensor"// /* Input Device Name */
+#define SENSOR_I2C_NAME "dmard09"//"dmt"// /* Device name for DMARD09 misc. device */
+#define DEVICE_I2C_ADDR 0x1d
+#define REG_ACTR 0x00
+#define REG_STAT 0x0A
+#define REG_DX 0x0C
+#define REG_DY 0x0E
+#define REG_DZ 0x10
+#define REG_DT 0x12
+#define REG_INL 0x16
+#define REG_DC 0x18
+#define REG_CNT_L1 0x1B
+#define REG_CNT_L2 0x1C
+#define REG_CNT_L3 0x1D
+#define REG_INC 0x1E
+#define REG_ODF 0x20
+#define REG_THR1 0x62
+#define REG_THR2 0x64
+
+#define MODE_ACTIVE 0x61 /* active */
+#define MODE_POWERDOWN 0x60 /* powerdown */
+
+#define VALUE_WHO_AM_I 0x95 /* D09 WMI */
+#define VALUE_ODR_200 0x9C /* conversion rate 200Hz */
+#define VALUE_ODR_100 0x98 /* conversion rate 100Hz */
+#define VALUE_ODR_50 0x94 /* conversion rate 50Hz */
+#define VALUE_ODR_20 0x90 /* conversion rate 20Hz */
+#define VALUE_ODR_10 0x8C /* conversion rate 10Hz */
+#define VALUE_ODR_5 0x88 /* conversion rate 5Hz */
+#define VALUE_ODR_1 0x84 /* conversion rate 1Hz */
+#define VALUE_ODR_0_5 0x80 /* conversion rate 0.5Hz */
+#define VALUE_CNT_L2 0xE4 /* Disable IEN */
+/* Optional Digital Filter [Low Byte and High Byte Order] */
+#define ODF_NoFilter 0x00 /* No filter */
+#define ODF_Ave_4 0x03 /* smooth filter 1/4 Bandwidth */
+#define ODF_Ave_8 0x07 /* smooth filter 1/8 Bandwidth */
+#define ODF_Ave_16 0x0f /* smooth filter 1/16 Bandwidth */
+
+
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_NEGATIVE 1
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_POSITIVE 2
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_NEGATIVE 3
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_POSITIVE 4
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_NEGATIVE 5
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_POSITIVE 6
+
+#define AVG_NUM 16
+#define SENSOR_DATA_SIZE 3
+#define DEFAULT_SENSITIVITY 1024
+
+#define IOCTL_MAGIC 0x09
+#define SENSOR_RESET _IO(IOCTL_MAGIC, 0)
+#define SENSOR_CALIBRATION _IOWR(IOCTL_MAGIC, 1, int[SENSOR_DATA_SIZE])
+#define SENSOR_GET_OFFSET _IOR(IOCTL_MAGIC, 2, int[SENSOR_DATA_SIZE])
+#define SENSOR_SET_OFFSET _IOWR(IOCTL_MAGIC, 3, int[SENSOR_DATA_SIZE])
+#define SENSOR_READ_ACCEL_XYZ _IOR(IOCTL_MAGIC, 4, int[SENSOR_DATA_SIZE])
+#define SENSOR_SETYPR _IOW(IOCTL_MAGIC, 5, int[SENSOR_DATA_SIZE])
+#define SENSOR_GET_OPEN_STATUS _IO(IOCTL_MAGIC, 6)
+#define SENSOR_GET_CLOSE_STATUS _IO(IOCTL_MAGIC, 7)
+#define SENSOR_GET_DELAY _IOR(IOCTL_MAGIC, 8, unsigned int*)
+#define SENSOR_MAXNR 8
+/* Default sensorlayout parameters */
+#define D09_DEFAULT_POSITION 6
+
+/* Transformation matrix for chip mounting position */
+static const int dmt_position_map[][3][3] = {
+ { { 1, 0, 0}, { 0,-1, 0}, { 0, 0,-1}, }, /* top/upper-left */
+ { { 0, 1, 0}, { 1, 0, 0}, { 0, 0,-1}, }, /* top/lower-left */
+ { {-1, 0, 0}, { 0, 1, 0}, { 0, 0,-1}, }, /* top/lower-right */
+ { { 0,-1, 0}, {-1, 0, 0}, { 0, 0,-1}, }, /* top/upper-right */
+ { {-1, 0, 0}, { 0,-1, 0}, { 0, 0, 1}, }, /* bottom/upper-right*/
+ { { 0,-1, 0}, {-1, 0, 0}, { 0, 0, 1}, }, /* bottom/upper-left */
+ { { 1, 0, 0}, { 0, 1, 0}, { 0, 0, 1}, }, /* bottom/lower-right*/
+ { { 0, 1,0}, { 1, 0, 0}, { 0, 0, 1}, }, /* bottom/lower-left */
+};
+
+typedef union {
+ struct {
+ int x;
+ int y;
+ int z;
+ } u;
+ int v[SENSOR_DATA_SIZE];
+} raw_data;
+
+struct dmt_data {
+ struct platform_device *pdevice;
+ struct device *class_dev;
+ struct class *class;
+ struct input_dev *input;
+ struct i2c_client *client;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+ struct delayed_work delaywork;
+ struct work_struct work;
+ struct mutex data_mutex;
+ struct mutex enable_mutex; /* for suspend */
+ raw_data last; /* RawData */
+ raw_data offset; /* Offset */
+#ifdef SW_FILTER
+ int sum[SENSOR_DATA_SIZE]; /* SW_FILTER sum */
+ int bufferave[3][32];
+ s8 aveflag; /* FULL bufferave[][] */
+ s8 pointer; /* last update data */
+#endif
+ wait_queue_head_t open_wq;
+ atomic_t active;
+ atomic_t delay;
+ atomic_t enable;
+ int filter;
+ int position; /* must int type ,for Kconfig setup */
+ atomic_t addr;
+#ifdef DMT_DEBUG_DATA
+ struct mutex suspend_mutex;
+ int suspend;
+#endif
+};
+
+#define ACC_DATA_FLAG 0
+#define MAG_DATA_FLAG 1
+#define ORI_DATA_FLAG 2
+#define DMT_NUM_SENSORS 3
+
+/* ABS axes parameter range [um/s^2] (for input event) */
+#define GRAVITY_EARTH 9806550
+#define ABSMAX (GRAVITY_EARTH * 2)
+#define ABSMIN (-GRAVITY_EARTH * 2)
+
+#endif