From 79bcb477e221edf413372f00b6283af9580b25ef Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Mon, 5 Nov 2018 09:40:18 +0800 Subject: [PATCH] drivers/input: remove unused gsensor drivers Change-Id: I9a895925a37f775244d04a7a4bf6b2d4c43cdc3a Signed-off-by: Tao Huang --- drivers/input/gsensor/Kconfig | 43 - drivers/input/gsensor/Makefile | 8 - drivers/input/gsensor/bma023.c | 1009 --------------- drivers/input/gsensor/l3g4200d.c | 879 ------------- drivers/input/gsensor/lis3dh.c | 1006 --------------- drivers/input/gsensor/lis3dh.h | 186 --- drivers/input/gsensor/lis3dh_acc_misc.c | 1505 ----------------------- drivers/input/gsensor/lis3dh_acc_misc.h | 137 --- drivers/input/gsensor/mma7660.c | 639 ---------- drivers/input/gsensor/mma8452.c | 833 ------------- 10 files changed, 6245 deletions(-) delete mode 100644 drivers/input/gsensor/Kconfig delete mode 100644 drivers/input/gsensor/Makefile delete mode 100755 drivers/input/gsensor/bma023.c delete mode 100755 drivers/input/gsensor/l3g4200d.c delete mode 100644 drivers/input/gsensor/lis3dh.c delete mode 100644 drivers/input/gsensor/lis3dh.h delete mode 100755 drivers/input/gsensor/lis3dh_acc_misc.c delete mode 100755 drivers/input/gsensor/lis3dh_acc_misc.h delete mode 100644 drivers/input/gsensor/mma7660.c delete mode 100755 drivers/input/gsensor/mma8452.c diff --git a/drivers/input/gsensor/Kconfig b/drivers/input/gsensor/Kconfig deleted file mode 100644 index 745750e9c91f..000000000000 --- a/drivers/input/gsensor/Kconfig +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# gsensor drivers configuration -# - -menuconfig G_SENSOR_DEVICE - bool "g_sensor device support" - help - Enable this to be able to choose the drivers for controlling the - g_sensor on some platforms, for example on PDAs. - -if G_SENSOR_DEVICE - -config GS_MMA7660 - bool "gs_mma7660" - help - To have support for your specific gsesnor you will have to - select the proper drivers which depend on this option. - -config GS_MMA8452 - bool "gs_mma8452" - 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 "gs_lis3dh" - help - To have support for your specific gsesnor you will have to - select the proper drivers which depend on this option. - -config GS_L3G4200D - bool "gs_l3g4200d" - help - To have support for your specific gsesnor you will have to - select the proper drivers which depend on this option. - -config GS_BMA023 - bool "gs_bma023" - help - To have support for your specific gsesnor you will have to - select the proper drivers which depend on this option. -endif diff --git a/drivers/input/gsensor/Makefile b/drivers/input/gsensor/Makefile deleted file mode 100644 index 7c9fa680b407..000000000000 --- a/drivers/input/gsensor/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# gsensor drivers - -obj-$(CONFIG_GS_MMA7660) += mma7660.o -obj-$(CONFIG_GS_MMA8452) += mma8452.o -obj-$(CONFIG_GS_L3G4200D) += l3g4200d.o -obj-$(CONFIG_GS_LIS3DH) += lis3dh.o -obj-$(CONFIG_GS_BMA023) += bma023.o diff --git a/drivers/input/gsensor/bma023.c b/drivers/input/gsensor/bma023.c deleted file mode 100755 index 33a5c8aec1a6..000000000000 --- a/drivers/input/gsensor/bma023.c +++ /dev/null @@ -1,1009 +0,0 @@ -/* drivers/i2c/chips/bma023.c - bma023 compass driver - * - * Copyright (C) 2007-2008 HTC Corporation. - * Author: Hou-Kun Chen - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - - -#if 0 -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - - -#define SENSOR_NAME "bma150" -#define GRAVITY_EARTH 9806550 -#define ABSMIN_2G (-GRAVITY_EARTH * 2) -#define ABSMAX_2G (GRAVITY_EARTH * 2) -#define BMA150_MAX_DELAY 200 -#define BMA150_CHIP_ID 2 -#define BMA150_RANGE_SET 0 -#define BMA150_BW_SET 4 - - - -#define BMA150_CHIP_ID_REG 0x00 -#define BMA150_X_AXIS_LSB_REG 0x02 -#define BMA150_X_AXIS_MSB_REG 0x03 -#define BMA150_Y_AXIS_LSB_REG 0x04 -#define BMA150_Y_AXIS_MSB_REG 0x05 -#define BMA150_Z_AXIS_LSB_REG 0x06 -#define BMA150_Z_AXIS_MSB_REG 0x07 -#define BMA150_STATUS_REG 0x09 -#define BMA150_CTRL_REG 0x0a -#define BMA150_CONF1_REG 0x0b - -#define BMA150_CUSTOMER1_REG 0x12 -#define BMA150_CUSTOMER2_REG 0x13 -#define BMA150_RANGE_BWIDTH_REG 0x14 -#define BMA150_CONF2_REG 0x15 - -#define BMA150_OFFS_GAIN_X_REG 0x16 -#define BMA150_OFFS_GAIN_Y_REG 0x17 -#define BMA150_OFFS_GAIN_Z_REG 0x18 -#define BMA150_OFFS_GAIN_T_REG 0x19 -#define BMA150_OFFSET_X_REG 0x1a -#define BMA150_OFFSET_Y_REG 0x1b -#define BMA150_OFFSET_Z_REG 0x1c -#define BMA150_OFFSET_T_REG 0x1d - -#define BMA150_CHIP_ID__POS 0 -#define BMA150_CHIP_ID__MSK 0x07 -#define BMA150_CHIP_ID__LEN 3 -#define BMA150_CHIP_ID__REG BMA150_CHIP_ID_REG - -/* DATA REGISTERS */ - -#define BMA150_NEW_DATA_X__POS 0 -#define BMA150_NEW_DATA_X__LEN 1 -#define BMA150_NEW_DATA_X__MSK 0x01 -#define BMA150_NEW_DATA_X__REG BMA150_X_AXIS_LSB_REG - -#define BMA150_ACC_X_LSB__POS 6 -#define BMA150_ACC_X_LSB__LEN 2 -#define BMA150_ACC_X_LSB__MSK 0xC0 -#define BMA150_ACC_X_LSB__REG BMA150_X_AXIS_LSB_REG - -#define BMA150_ACC_X_MSB__POS 0 -#define BMA150_ACC_X_MSB__LEN 8 -#define BMA150_ACC_X_MSB__MSK 0xFF -#define BMA150_ACC_X_MSB__REG BMA150_X_AXIS_MSB_REG - -#define BMA150_ACC_Y_LSB__POS 6 -#define BMA150_ACC_Y_LSB__LEN 2 -#define BMA150_ACC_Y_LSB__MSK 0xC0 -#define BMA150_ACC_Y_LSB__REG BMA150_Y_AXIS_LSB_REG - -#define BMA150_ACC_Y_MSB__POS 0 -#define BMA150_ACC_Y_MSB__LEN 8 -#define BMA150_ACC_Y_MSB__MSK 0xFF -#define BMA150_ACC_Y_MSB__REG BMA150_Y_AXIS_MSB_REG - -#define BMA150_ACC_Z_LSB__POS 6 -#define BMA150_ACC_Z_LSB__LEN 2 -#define BMA150_ACC_Z_LSB__MSK 0xC0 -#define BMA150_ACC_Z_LSB__REG BMA150_Z_AXIS_LSB_REG - -#define BMA150_ACC_Z_MSB__POS 0 -#define BMA150_ACC_Z_MSB__LEN 8 -#define BMA150_ACC_Z_MSB__MSK 0xFF -#define BMA150_ACC_Z_MSB__REG BMA150_Z_AXIS_MSB_REG - -/* CONTROL BITS */ - -#define BMA150_SLEEP__POS 0 -#define BMA150_SLEEP__LEN 1 -#define BMA150_SLEEP__MSK 0x01 -#define BMA150_SLEEP__REG BMA150_CTRL_REG - -#define BMA150_SOFT_RESET__POS 1 -#define BMA150_SOFT_RESET__LEN 1 -#define BMA150_SOFT_RESET__MSK 0x02 -#define BMA150_SOFT_RESET__REG BMA150_CTRL_REG - -#define BMA150_EE_W__POS 4 -#define BMA150_EE_W__LEN 1 -#define BMA150_EE_W__MSK 0x10 -#define BMA150_EE_W__REG BMA150_CTRL_REG - -#define BMA150_UPDATE_IMAGE__POS 5 -#define BMA150_UPDATE_IMAGE__LEN 1 -#define BMA150_UPDATE_IMAGE__MSK 0x20 -#define BMA150_UPDATE_IMAGE__REG BMA150_CTRL_REG - -#define BMA150_RESET_INT__POS 6 -#define BMA150_RESET_INT__LEN 1 -#define BMA150_RESET_INT__MSK 0x40 -#define BMA150_RESET_INT__REG BMA150_CTRL_REG - -/* BANDWIDTH dependend definitions */ - -#define BMA150_BANDWIDTH__POS 0 -#define BMA150_BANDWIDTH__LEN 3 -#define BMA150_BANDWIDTH__MSK 0x07 -#define BMA150_BANDWIDTH__REG BMA150_RANGE_BWIDTH_REG - -/* RANGE */ - -#define BMA150_RANGE__POS 3 -#define BMA150_RANGE__LEN 2 -#define BMA150_RANGE__MSK 0x18 -#define BMA150_RANGE__REG BMA150_RANGE_BWIDTH_REG - -/* WAKE UP */ - -#define BMA150_WAKE_UP__POS 0 -#define BMA150_WAKE_UP__LEN 1 -#define BMA150_WAKE_UP__MSK 0x01 -#define BMA150_WAKE_UP__REG BMA150_CONF2_REG - -#define BMA150_WAKE_UP_PAUSE__POS 1 -#define BMA150_WAKE_UP_PAUSE__LEN 2 -#define BMA150_WAKE_UP_PAUSE__MSK 0x06 -#define BMA150_WAKE_UP_PAUSE__REG BMA150_CONF2_REG - -#define BMA150_GET_BITSLICE(regvar, bitname)\ - ((regvar & bitname##__MSK) >> bitname##__POS) - - -#define BMA150_SET_BITSLICE(regvar, bitname, val)\ - ((regvar & ~bitname##__MSK) | ((val<>1)); - comres += bma150_smbus_write_byte(client, - BMA150_WAKE_UP__REG, &data1); - comres += bma150_smbus_write_byte(client, - BMA150_SLEEP__REG, &data2); - mutex_lock(&bma150->mode_mutex); - bma150->mode = (unsigned char) Mode; - mutex_unlock(&bma150->mode_mutex); - - } else{ - comres = -1; - } - } - - return comres; -} - - -static int bma150_set_range(struct i2c_client *client, unsigned char Range) -{ - int comres = 0; - unsigned char data; - - if (client == NULL) { - comres = -1; - } else{ - if (Range < 3) { - - comres = bma150_smbus_read_byte(client, - BMA150_RANGE__REG, &data); - data = BMA150_SET_BITSLICE(data, BMA150_RANGE, Range); - comres += bma150_smbus_write_byte(client, - BMA150_RANGE__REG, &data); - - } else{ - comres = -1; - } - } - - return comres; -} - -static int bma150_get_range(struct i2c_client *client, unsigned char *Range) -{ - int comres = 0; - unsigned char data; - - if (client == NULL) { - comres = -1; - } else{ - comres = bma150_smbus_read_byte(client, - BMA150_RANGE__REG, &data); - - *Range = BMA150_GET_BITSLICE(data, BMA150_RANGE); - - } - - return comres; -} - - - -static int bma150_set_bandwidth(struct i2c_client *client, unsigned char BW) -{ - int comres = 0; - unsigned char data; - - if (client == NULL) { - comres = -1; - } else{ - if (BW < 8) { - comres = bma150_smbus_read_byte(client, - BMA150_BANDWIDTH__REG, &data); - data = BMA150_SET_BITSLICE(data, BMA150_BANDWIDTH, BW); - comres += bma150_smbus_write_byte(client, - BMA150_BANDWIDTH__REG, &data); - - } else{ - comres = -1; - } - } - - return comres; -} - -static int bma150_get_bandwidth(struct i2c_client *client, unsigned char *BW) -{ - int comres = 0; - unsigned char data; - - if (client == NULL) { - comres = -1; - } else{ - - - comres = bma150_smbus_read_byte(client, - BMA150_BANDWIDTH__REG, &data); - - *BW = BMA150_GET_BITSLICE(data, BMA150_BANDWIDTH); - - - } - - return comres; -} - -static int bma150_read_accel_xyz(struct i2c_client *client, - struct bma150acc *acc) -{ - int comres; - unsigned char data[6]; - if (client == NULL) { - comres = -1; - } else{ - - - comres = bma150_smbus_read_byte_block(client, - BMA150_ACC_X_LSB__REG, &data[0], 6); - - acc->x = BMA150_GET_BITSLICE(data[0], BMA150_ACC_X_LSB) | - (BMA150_GET_BITSLICE(data[1], BMA150_ACC_X_MSB)<< - BMA150_ACC_X_LSB__LEN); - if (acc->x < BMA150_BOUNDARY) - acc->x = acc->x * BMA150_GRAVITY_STEP; - else - acc->x = ~( ((~acc->x & (0x7fff>>(16-BMA150_PRECISION)) ) + 1) - * BMA150_GRAVITY_STEP) + 1; -#if 0 - acc->x = acc->x << (sizeof(short)*8-(BMA150_ACC_X_LSB__LEN+ - BMA150_ACC_X_MSB__LEN)); - acc->x = acc->x >> (sizeof(short)*8-(BMA150_ACC_X_LSB__LEN+ - BMA150_ACC_X_MSB__LEN)); -#endif - - acc->y = BMA150_GET_BITSLICE(data[2], BMA150_ACC_Y_LSB) | - (BMA150_GET_BITSLICE(data[3], BMA150_ACC_Y_MSB)<< - BMA150_ACC_Y_LSB__LEN); - if (acc->y < BMA150_BOUNDARY) - acc->y = acc->y * BMA150_GRAVITY_STEP; - else - acc->y = ~( ((~acc->y & (0x7fff>>(16-BMA150_PRECISION)) ) + 1) - * BMA150_GRAVITY_STEP) + 1; -#if 0 - acc->y = acc->y << (sizeof(short)*8-(BMA150_ACC_Y_LSB__LEN + - BMA150_ACC_Y_MSB__LEN)); - acc->y = acc->y >> (sizeof(short)*8-(BMA150_ACC_Y_LSB__LEN + - BMA150_ACC_Y_MSB__LEN)); -#endif - - - acc->z = BMA150_GET_BITSLICE(data[4], BMA150_ACC_Z_LSB); - acc->z |= (BMA150_GET_BITSLICE(data[5], BMA150_ACC_Z_MSB)<< - BMA150_ACC_Z_LSB__LEN); - if (acc->z < BMA150_BOUNDARY) - acc->z = acc->z * BMA150_GRAVITY_STEP; - else - acc->z = ~( ((~acc->z & (0x7fff>>(16-BMA150_PRECISION)) ) + 1) - * BMA150_GRAVITY_STEP) + 1; -#if 0 - acc->z = acc->z << (sizeof(short)*8-(BMA150_ACC_Z_LSB__LEN+ - BMA150_ACC_Z_MSB__LEN)); - acc->z = acc->z >> (sizeof(short)*8-(BMA150_ACC_Z_LSB__LEN+ - BMA150_ACC_Z_MSB__LEN)); -#endif - - } - - return comres; -} - -static void bma150_work_func(struct work_struct *work) -{ - struct bma150_data *bma150 = container_of((struct delayed_work *)work, - struct bma150_data, work); - static struct bma150acc acc; - s32 x,y,z; - unsigned long delay = msecs_to_jiffies(atomic_read(&bma150->delay)); - struct bma023_platform_data *pdata = pdata = (bma150->bma150_client)->dev.platform_data; - - bma150_read_accel_xyz(bma150->bma150_client, &acc); - if (pdata->swap_xyz) { - x = (pdata->orientation[0])*acc.x + (pdata->orientation[1])*acc.y + (pdata->orientation[2])*acc.z; - y = (pdata->orientation[3])*acc.x + (pdata->orientation[4])*acc.y + (pdata->orientation[5])*acc.z; - z = (pdata->orientation[6])*acc.x + (pdata->orientation[7])*acc.y + (pdata->orientation[8])*acc.z; - } - else { - x = acc.x; - y = acc.y; - z = acc.z; - } - input_report_abs(bma150->input, ABS_X, x); - input_report_abs(bma150->input, ABS_Y, y); - input_report_abs(bma150->input, ABS_Z, z); - input_sync(bma150->input); - mutex_lock(&bma150->value_mutex); - bma150->value.x = x; - bma150->value.y = y; - bma150->value.z = z; - mutex_unlock(&bma150->value_mutex); - DBG("bma150_work_func acc.x=%d,acc.y=%d,acc.z=%d\n",acc.x,acc.y,acc.z); - schedule_delayed_work(&bma150->work, delay); - -} -#if 0 -static ssize_t bma150_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned char data; - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - mutex_lock(&bma150->mode_mutex); - data = bma150->mode; - mutex_unlock(&bma150->mode_mutex); - - return sprintf(buf, "%d\n", data); -} - -static ssize_t bma150_mode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if (bma150_set_mode(bma150->bma150_client, (unsigned char) data) < 0) - return -EINVAL; - - - return count; -} -static ssize_t bma150_range_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned char data; - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - if (bma150_get_range(bma150->bma150_client, &data) < 0) - return sprintf(buf, "Read error\n"); - - return sprintf(buf, "%d\n", data); -} - -static ssize_t bma150_range_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if (bma150_set_range(bma150->bma150_client, (unsigned char) data) < 0) - return -EINVAL; - - return count; -} - -static ssize_t bma150_bandwidth_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned char data; - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - if (bma150_get_bandwidth(bma150->bma150_client, &data) < 0) - return sprintf(buf, "Read error\n"); - - return sprintf(buf, "%d\n", data); - -} - -static ssize_t bma150_bandwidth_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if (bma150_set_bandwidth(bma150->bma150_client, - (unsigned char) data) < 0) - return -EINVAL; - - return count; -} - -static ssize_t bma150_value_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct input_dev *input = to_input_dev(dev); - struct bma150_data *bma150 = input_get_drvdata(input); - struct bma150acc acc_value; - - mutex_lock(&bma150->value_mutex); - acc_value = bma150->value; - mutex_unlock(&bma150->value_mutex); - - return sprintf(buf, "%ll %ll %ll\n", acc_value.x, acc_value.y, - acc_value.z); -} - - - -static ssize_t bma150_delay_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - return sprintf(buf, "%d\n", atomic_read(&bma150->delay)); - -} - -static ssize_t bma150_delay_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if (data > BMA150_MAX_DELAY) - data = BMA150_MAX_DELAY; - atomic_set(&bma150->delay, (unsigned int) data); - - return count; -} - -static ssize_t bma150_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - - return sprintf(buf, "%d\n", atomic_read(&bma150->enable)); - -} - -static void bma150_set_enable(struct device *dev, int enable) -{ - struct i2c_client *client = to_i2c_client(dev); - struct bma150_data *bma150 = i2c_get_clientdata(client); - int pre_enable = atomic_read(&bma150->enable); - - mutex_lock(&bma150->enable_mutex); - if (enable) { - if (pre_enable ==0) { - bma150_set_mode(bma150->bma150_client, - BMA150_MODE_NORMAL); - schedule_delayed_work(&bma150->work, - msecs_to_jiffies(atomic_read(&bma150->delay))); - atomic_set(&bma150->enable, 1); - } - - } else { - if (pre_enable ==1) { - bma150_set_mode(bma150->bma150_client, - BMA150_MODE_SLEEP); - cancel_delayed_work_sync(&bma150->work); - atomic_set(&bma150->enable, 0); - } - } - mutex_unlock(&bma150->enable_mutex); - -} - -static ssize_t bma150_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if ((data == 0)||(data==1)) { - bma150_set_enable(dev,data); - } - - return count; -} - -static DEVICE_ATTR(range, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, - bma150_range_show, bma150_range_store); -static DEVICE_ATTR(bandwidth, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, - bma150_bandwidth_show, bma150_bandwidth_store); -static DEVICE_ATTR(mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, - bma150_mode_show, bma150_mode_store); -static DEVICE_ATTR(value, S_IRUGO|S_IWUSR|S_IWGRP, - bma150_value_show, NULL); -static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, - bma150_delay_show, bma150_delay_store); -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, - bma150_enable_show, bma150_enable_store); - -static struct attribute *bma150_attributes[] = { - &dev_attr_range.attr, - &dev_attr_bandwidth.attr, - &dev_attr_mode.attr, - &dev_attr_value.attr, - &dev_attr_delay.attr, - &dev_attr_enable.attr, - NULL -}; - -static struct attribute_group bma150_attribute_group = { - .attrs = bma150_attributes -}; -#endif -static int bma150_input_init(struct bma150_data *bma150) -{ - struct input_dev *dev; - int err; - - dev = input_allocate_device(); - if (!dev) - return -ENOMEM; - dev->name = "gsensor";//SENSOR_NAME; - dev->id.bustype = BUS_I2C; - - input_set_capability(dev, EV_ABS, ABS_MISC); - input_set_abs_params(dev, ABS_X, ABSMIN_2G, ABSMAX_2G, 0, 0); - input_set_abs_params(dev, ABS_Y, ABSMIN_2G, ABSMAX_2G, 0, 0); - input_set_abs_params(dev, ABS_Z, ABSMIN_2G, ABSMAX_2G, 0, 0); - input_set_drvdata(dev, bma150); - - err = input_register_device(dev); - if (err < 0) { - input_free_device(dev); - return err; - } - bma150->input = dev; - - return 0; -} - -static void bma150_input_delete(struct bma150_data *bma150) -{ - struct input_dev *dev = bma150->input; - - input_unregister_device(dev); - input_free_device(dev); -} - - -static int bma023_open(struct inode *inode, struct file *file) -{ - printk("%s\n",__FUNCTION__); - return 0;//nonseekable_open(inode, file); -} - -static int bma023_release(struct inode *inode, struct file *file) -{ - return 0; -} -static struct file_operations bma023_fops = { - .owner = THIS_MODULE, - .open = bma023_open, - .release = bma023_release, - .unlocked_ioctl = bma023_ioctl, -}; -static struct miscdevice bma023_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "mma8452_daemon",//"mma8452_daemon", - .fops = &bma023_fops, -}; - - -static bma023_enable(struct i2c_client *client, int enable) -{ - - struct bma150_data *bma150 = i2c_get_clientdata(client); - int pre_enable = atomic_read(&bma150->enable); - - mutex_lock(&bma150->enable_mutex); - - if(enable) - { - if(pre_enable==0) - { - bma150_set_mode(client,BMA150_MODE_NORMAL); - schedule_delayed_work(&bma150->work, - msecs_to_jiffies(atomic_read(&bma150->delay))); - atomic_set(&bma150->enable, 1); - } - } - else - { - bma150_set_mode(client,BMA150_MODE_SLEEP); - cancel_delayed_work_sync(&bma150->work); - atomic_set(&bma150->enable, 0); - } - - mutex_unlock(&bma150->enable_mutex); - -} - - -static long bma023_ioctl( struct file *file, unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - - struct i2c_client *client = container_of(bma023_device.parent, struct i2c_client, dev); - struct bma150_data *bma150 = i2c_get_clientdata(client);; - switch (cmd) { - case BMA_IOCTL_START: - bma023_enable(client, 1); - DBG("%s:%d,cmd=BMA_IOCTL_START\n",__FUNCTION__,__LINE__); - break; - - case BMA_IOCTL_CLOSE: - bma023_enable(client, 0); - DBG("%s:%d,cmd=BMA_IOCTL_CLOSE\n",__FUNCTION__,__LINE__); - break; - - case BMA_IOCTL_APP_SET_RATE: - atomic_set(&bma150->delay, 20);//20ms - DBG("%s:%d,cmd=BMA_IOCTL_APP_SET_RATE\n",__FUNCTION__,__LINE__); - break; - - case BMA_IOCTL_GETDATA: - mutex_lock(&bma150->value_mutex); - if(abs(sense_data.x-bma150->value.x)>40000)//防抖动 - sense_data.x=bma150->value.x; - if(abs(sense_data.y-(bma150->value.y))>40000)//防抖动 - sense_data.y=bma150->value.y; - if(abs(sense_data.z-(bma150->value.z))>40000)//防抖动 - sense_data.z=bma150->value.z; - //bma150->value = acc; - mutex_unlock(&bma150->value_mutex); - - if ( copy_to_user(argp, &sense_data, sizeof(sense_data) ) ) { - printk("failed to copy sense data to user space."); - return -EFAULT; - } - - DBG("%s:%d,cmd=BMA_IOCTL_GETDATA\n",__FUNCTION__,__LINE__); - break; - default: - printk("%s:%d,error,cmd=%x\n",__FUNCTION__,__LINE__,cmd); - break; - } - return 0; -} - -static int bma150_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err = 0; - int tempvalue; - struct bma150_data *data; - printk(KERN_INFO "bma150_probe \n"); - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - printk(KERN_INFO "i2c_check_functionality error\n"); - goto exit; - } - data = kzalloc(sizeof(struct bma150_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - tempvalue = 0; - tempvalue = i2c_smbus_read_word_data(client, BMA150_CHIP_ID_REG); - - if ((tempvalue&0x00FF) == BMA150_CHIP_ID) { - printk(KERN_INFO "Bosch Sensortec Device detected!\n" \ - "BMA150 registered I2C driver!\n"); - } else{ - printk(KERN_INFO "Bosch Sensortec Device not found" \ - "i2c error %d \n", tempvalue); - err = -1; - goto kfree_exit; - } - i2c_set_clientdata(client, data); - data->bma150_client = client; - mutex_init(&data->value_mutex); - mutex_init(&data->mode_mutex); - mutex_init(&data->enable_mutex); - bma150_set_bandwidth(client, BMA150_BW_SET); - bma150_set_range(client, BMA150_RANGE_SET); - - - INIT_DELAYED_WORK(&data->work, bma150_work_func); - atomic_set(&data->delay, BMA150_MAX_DELAY); - atomic_set(&data->enable, 0); - err = bma150_input_init(data); - if (err < 0) - goto kfree_exit; -#if 0 - err = sysfs_create_group(&data->input->dev.kobj, - &bma150_attribute_group); - if (err < 0) - goto error_sysfs; -#endif - data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - data->early_suspend.suspend = bma150_early_suspend; - data->early_suspend.resume = bma150_late_resume; - register_early_suspend(&data->early_suspend); - bma023_device.parent = &client->dev; - misc_register(&bma023_device); - return 0; - -//error_sysfs: -// bma150_input_delete(data); - -kfree_exit: - kfree(data); -exit: - return err; -} - - -static int bma150_remove(struct i2c_client *client) -{ - struct bma150_data *data = i2c_get_clientdata(client); - - bma023_enable(&client->dev, 0); - unregister_early_suspend(&data->early_suspend); - //sysfs_remove_group(&data->input->dev.kobj, &bma150_attribute_group); - bma150_input_delete(data); - kfree(data); - - return 0; -} - - - - -static void bma150_early_suspend(struct early_suspend *h) -{ - struct bma150_data *data = - container_of(h, struct bma150_data, early_suspend); - - mutex_lock(&data->enable_mutex); - if (atomic_read(&data->enable)==1) { - bma150_set_mode(data->bma150_client, BMA150_MODE_SLEEP); - cancel_delayed_work_sync(&data->work); - } - mutex_unlock(&data->enable_mutex); -} - - -static void bma150_late_resume(struct early_suspend *h) -{ - struct bma150_data *data = - container_of(h, struct bma150_data, early_suspend); - - mutex_lock(&data->enable_mutex); - if (atomic_read(&data->enable)==1) { - bma150_set_mode(data->bma150_client, BMA150_MODE_NORMAL); - schedule_delayed_work(&data->work, - msecs_to_jiffies(atomic_read(&data->delay))); - } - mutex_unlock(&data->enable_mutex); -} - -static const struct i2c_device_id bma150_id[] = { - { SENSOR_NAME, 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, bma150_id); - -static struct i2c_driver bma150_driver = { - .driver = { - .owner = THIS_MODULE, - .name = SENSOR_NAME, - }, - .id_table = bma150_id, - .probe = bma150_probe, - .remove = bma150_remove, - -}; - -static int __init BMA150_init(void) -{ - return i2c_add_driver(&bma150_driver); -} - -static void __exit BMA150_exit(void) -{ - i2c_del_driver(&bma150_driver); -} - -MODULE_AUTHOR("Lan Bin Yuan "); -MODULE_DESCRIPTION("BMA150 driver"); -MODULE_LICENSE("GPL"); - -module_init(BMA150_init); -module_exit(BMA150_exit); diff --git a/drivers/input/gsensor/l3g4200d.c b/drivers/input/gsensor/l3g4200d.c deleted file mode 100755 index df4874699fd7..000000000000 --- a/drivers/input/gsensor/l3g4200d.c +++ /dev/null @@ -1,879 +0,0 @@ -/* drivers/i2c/chips/l3g4200d.c - l3g4200d compass driver - * - * Copyright (C) 2007-2008 HTC Corporation. - * Author: Hou-Kun Chen - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - -#if 1 -#define mmaprintk(x...) printk(x) -#else -#define mmaprintk(x...) -#endif -static int l3g4200d_probe(struct i2c_client *client, const struct i2c_device_id *id); - -#define L3G4200D_SPEED 200 * 1000 -#define L3G4200D_DEVID 0xD3 - -#define L3G4200D_MAJOR 102 -#define L3G4200D_MINOR 4 - -/* l3g4200d gyroscope registers */ -#define WHO_AM_I 0x0F - -#define CTRL_REG1 0x20 /* power control reg */ -#define CTRL_REG2 0x21 /* power control reg */ -#define CTRL_REG3 0x22 /* power control reg */ -#define CTRL_REG4 0x23 /* interrupt control reg */ -#define CTRL_REG5 0x24 /* interrupt control reg */ -#define AXISDATA_REG 0x28 - - -/* Addresses to scan -- protected by sense_data_mutex */ -//static char sense_data[RBUFF_SIZE + 1]; -static struct i2c_client *this_client; -static struct l3g4200d_data *this_data; -static struct miscdevice l3g4200d_device; - -static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq); - -#ifdef CONFIG_HAS_EARLYSUSPEND -static struct early_suspend l3g4200d_early_suspend; -#endif -static int revision = -1; -/* AKM HW info */ -static ssize_t gsensor_vendor_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - - sprintf(buf, "%#x\n", revision); - ret = strlen(buf) + 1; - - return ret; -} - -static DEVICE_ATTR(vendor, 0444, gsensor_vendor_show, NULL); - -static struct kobject *android_gsensor_kobj; - -static int gsensor_sysfs_init(void) -{ - int ret ; - - android_gsensor_kobj = kobject_create_and_add("android_gyrosensor", NULL); - if (android_gsensor_kobj == NULL) { - mmaprintk(KERN_ERR - "L3G4200D gsensor_sysfs_init:"\ - "subsystem_register failed\n"); - ret = -ENOMEM; - goto err; - } - - ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr); - if (ret) { - mmaprintk(KERN_ERR - "L3G4200D gsensor_sysfs_init:"\ - "sysfs_create_group failed\n"); - goto err4; - } - - return 0 ; -err4: - kobject_del(android_gsensor_kobj); -err: - return ret ; -} - -#if 0 -static int l3g4200d_rx_data(struct i2c_client *client, char *rxData, int length) -{ - int ret = 0; - char reg = rxData[0]; - ret = i2c_master_reg8_recv(client, reg, rxData, length, L3G4200D_SPEED); - return (ret > 0)? 0 : ret; -} -#else -static int l3g4200d_rx_data(struct i2c_client *client, char *rxData, int length) -{ - int ret = 0; - int retry = 3; - char reg = rxData[0]; -again: - ret = i2c_master_reg8_recv(client, reg, rxData, length, L3G4200D_SPEED); - if(ret < 0) - { - retry--; - mdelay(1); - goto again; - } - return (ret > 0)? 0 : ret; -} -#endif -#if 0 -static int l3g4200d_tx_data(struct i2c_client *client, char *txData, int length) -{ - int ret = 0; - char reg = txData[0]; - ret = i2c_master_reg8_send(client, reg, &txData[1], length-1, L3G4200D_SPEED); - return (ret > 0)? 0 : ret; -} -#else -static int l3g4200d_tx_data(struct i2c_client *client, char *txData, int length) -{ - int ret = 0; - char reg = txData[0]; - int retry = 3; -again: - ret = i2c_master_reg8_send(client, reg, &txData[1], length-1, L3G4200D_SPEED); - if(ret < 0) - { - retry--; - mdelay(1); - goto again; - } - return (ret > 0)? 0 : ret; -} -#endif - - -static int gyro_rx_data(struct i2c_client *client, char *rxData, int length) -{ - int ret = 0; - int retry = 3; - char reg = rxData[0]; -again: - ret = i2c_master_reg8_recv(client, reg, rxData, length, L3G4200D_SPEED); - if(ret < 0) - { - retry--; - mdelay(1); - goto again; - } - return (ret > 0)? 0 : ret; -} - -static int gyro_tx_data(struct i2c_client *client, char *txData, int length) -{ - int ret = 0; - char reg = txData[0]; - int retry = 3; -again: - ret = i2c_master_reg8_send(client, reg, &txData[1], length-1, L3G4200D_SPEED); - if(ret < 0) - { - retry--; - mdelay(1); - goto again; - } - return (ret > 0)? 0 : ret; -} - - - - - - -/* i2c read routine for l3g4200d digital gyroscope */ -static char l3g4200d_i2c_read(unsigned char reg_addr, - unsigned char *data, - unsigned char len) -{ - char tmp; - int ret = 0; - if (this_client == NULL) /* No global client pointer? */ - return -1; - - data[0]=reg_addr; - ret = gyro_rx_data(this_client, data, len); - return tmp; -} -/* i2c write routine for l3g4200d digital gyroscope */ -static char l3g4200d_i2c_write(unsigned char reg_addr, - unsigned char *data, - unsigned char len) -{ - - char buffer[3]; - int ret = 0; - int i = 0; - if (this_client == NULL) /* No global client pointer? */ - return -1; - for (i = 0; i < len; i++) - { - buffer[0] = reg_addr+i; - buffer[1] = data[i]; - ret = gyro_tx_data(this_client, &buffer[0], 2); - } - return ret; - -} - -static char l3g4200d_read_reg(struct i2c_client *client,int addr) -{ - char tmp; - int ret = 0; - - tmp = addr; -// ret = l3g4200d_tx_data(client, &tmp, 1); - ret = l3g4200d_rx_data(client, &tmp, 1); - return tmp; -} - -static int l3g4200d_write_reg(struct i2c_client *client,int addr,int value) -{ - char buffer[3]; - int ret = 0; - - buffer[0] = addr; - buffer[1] = value; - ret = l3g4200d_tx_data(client, &buffer[0], 2); - return ret; -} - - -static char l3g4200d_get_devid(struct i2c_client *client) -{ - int tempvalue; - tempvalue=l3g4200d_read_reg(client, WHO_AM_I); - if ((tempvalue & 0x00FF) == 0x00D3) { - #if DEBUG - printk(KERN_INFO "I2C driver registered!\n"); - #endif - return 1; - } else { - - #if DEBUG - printk(KERN_INFO "I2C driver %d!\n",tempvalue); - #endif - return 0; - } -} - -static int l3g4200d_active(struct i2c_client *client,int enable) -{ - int tmp; - int ret = 0; - - tmp = l3g4200d_read_reg(client,CTRL_REG1); - if(enable) - tmp |=ACTIVE_MASK; - else - tmp &=~ACTIVE_MASK; - mmaprintk("l3g4200d_active %s (0x%x)\n",enable?"active":"standby",tmp); - ret = l3g4200d_write_reg(client,CTRL_REG1,tmp); - return ret; -} - - - -static int device_init(void) -{ - int res; - unsigned char buf[5]; - buf[0] = 0x07; //27 - buf[1] = 0x00; - buf[2] = 0x00; - buf[3] = 0x20; //0x00 - buf[4] = 0x00; - res = l3g4200d_i2c_write(CTRL_REG1, &buf[0], 5); - return res; -} - -int l3g4200d_set_bandwidth(char bw) -{ - int res = 0; - unsigned char data; - - res = l3g4200d_read_reg(this_client, CTRL_REG1); - if (res >= 0) - data = res & 0x000F; - - data = data + bw; - res = l3g4200d_i2c_write(CTRL_REG1, &data, 1); - return res; -} - -static int l3g4200d_start_dev(struct i2c_client *client, char rate) -{ - int ret = 0; - int tmp; - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(client); - - /* standby */ - l3g4200d_active(client,0); - device_init(); - l3g4200d_set_bandwidth(rate); - l3g4200d_active(client,1); - - enable_irq(client->irq); - return ret; - -} - -static int l3g4200d_start(struct i2c_client *client, char rate) -{ - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(client); - - printk("%s::enter\n",__FUNCTION__); - if (l3g4200d->status == L3G4200D_OPEN) { - return 0; - } - l3g4200d->status = L3G4200D_OPEN; - return l3g4200d_start_dev(client, rate); -} - -static int l3g4200d_close_dev(struct i2c_client *client) -{ - mmaprintk("%s :enter\n",__FUNCTION__); - disable_irq_nosync(client->irq); - return l3g4200d_active(client,0); -} - -static int l3g4200d_close(struct i2c_client *client) -{ - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(client); - printk("%s::enter\n",__FUNCTION__); - l3g4200d->status = L3G4200D_CLOSE; - - return l3g4200d_close_dev(client); -} - -static int l3g4200d_reset_rate(struct i2c_client *client, char rate) -{ - int ret = 0; - - mmaprintk("\n----------------------------l3g4200d_reset_rate------------------------\n"); - - ret = l3g4200d_close_dev(client); - ret = l3g4200d_start_dev(client, rate); - - return ret ; -} - -static inline int l3g4200d_convert_to_int(char value) -{ - int result; - - if (value < 1) { - result = value * 1; - } else { - result = ~(((~value & 0x7f) + 1)* 1) + 1; - } - - return result; -} - -static void l3g4200d_report_value(struct i2c_client *client, struct l3g4200d_axis *axis) -{ - struct l3g4200d_data *l3g4200d = i2c_get_clientdata(client); - //struct l3g4200d_axis *axis = (struct l3g4200d_axis *)rbuf; - - /* Report acceleration sensor information */ - input_report_abs(l3g4200d->input_dev, ABS_RX, axis->x); - input_report_abs(l3g4200d->input_dev, ABS_RY, axis->y); - input_report_abs(l3g4200d->input_dev, ABS_RZ, axis->z); - input_sync(l3g4200d->input_dev); - mmaprintk("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z); -} - - -static int l3g4200d_get_data(struct i2c_client *client) -{ - char buffer[6]; - int ret,i; - struct l3g4200d_axis axis; - struct l3g4200d_platform_data *pdata = pdata = client->dev.platform_data; - - int res; - unsigned char gyro_data[6]; - /* x,y,z hardware data */ - int hw_d[3] = { 0 }; - - for(i=0;i<6;i++) - { - gyro_data[i] = AXISDATA_REG+i; - //ret = l3g4200d_tx_data(client, &buffer[0], 1); - ret = l3g4200d_rx_data(client, &gyro_data[i], 1); - } - - hw_d[0] = (short) (((gyro_data[1]) << 8) | gyro_data[0]); - hw_d[1] = (short) (((gyro_data[3]) << 8) | gyro_data[2]); - hw_d[2] = (short) (((gyro_data[5]) << 8) | gyro_data[4]); - - //mmaprintk("Gsensor x==%d y==%d z==%d x==%d y==%d z==%d\n",gyro_data[0],gyro_data[1],gyro_data[2],gyro_data[3],gyro_data[4],gyro_data[5]); - - - axis.x = ((this_data->pdata->negate_x) ? (-hw_d[this_data->pdata->axis_map_x]) - : (hw_d[this_data->pdata->axis_map_x])); - axis.y = ((this_data->pdata->negate_y) ? (-hw_d[this_data->pdata->axis_map_y]) - : (hw_d[this_data->pdata->axis_map_y])); - axis.z = ((this_data->pdata->negate_z) ? (-hw_d[this_data->pdata->axis_map_z]) - : (hw_d[this_data->pdata->axis_map_z])); - - l3g4200d_report_value(client, &axis); - - return 0; -} - -/* -static int l3g4200d_trans_buff(char *rbuf, int size) -{ - //wait_event_interruptible_timeout(data_ready_wq, - // atomic_read(&data_ready), 1000); - wait_event_interruptible(data_ready_wq, - atomic_read(&data_ready)); - - atomic_set(&data_ready, 0); - memcpy(rbuf, &sense_data[0], size); - - return 0; -} -*/ - -static int l3g4200d_open(struct inode *inode, struct file *file) -{ - mmaprintk("%s :enter\n",__FUNCTION__); - return 0;//nonseekable_open(inode, file); -} - -static int l3g4200d_release(struct inode *inode, struct file *file) -{ - mmaprintk("%s :enter\n",__FUNCTION__); - return 0; -} -#define RBUFF_SIZE 12 /* Rx buffer size */ - -static int l3g4200d_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(this_client); - void __user *argp = (void __user *)arg; - char msg[RBUFF_SIZE + 1]; - int ret = -1; - char rate; - struct i2c_client *client = container_of(l3g4200d_device.parent, struct i2c_client, dev); - printk(KERN_ERR "l3g4200d_ioctl,%d,%d,%d,%d,%d,%d,%d\n",cmd,GYROSENSOR_IOCTL_ENABLE,GYROSENSOR_IOCTL_GET_ENABLED,ECS_IOCTL_APP_GET_ABS,ECS_IOCTL_START,ECS_IOCTL_CLOSE,ECS_IOCTL_APP_SET_RATE); - switch (cmd) { - case ECS_IOCTL_APP_SET_RATE: - if (copy_from_user(&rate, argp, sizeof(rate))) - return -EFAULT; - break; - default: - break; - } - - switch (cmd) { - case ECS_IOCTL_START: - case GYROSENSOR_IOCTL_ENABLE: - ret = l3g4200d_start(client, ODR100_BW12_5); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_CLOSE: - ret = l3g4200d_close(client); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_APP_SET_RATE: - ret = l3g4200d_reset_rate(client, 0x00);//rate<<4);//0x20 - printk(KERN_ERR "%d\n",rate); - - if (ret < 0) - return ret; - break; - case GYROSENSOR_IOCTL_GET_ENABLED: - break; - /* - case ECS_IOCTL_GETDATA: - ret = l3g4200d_trans_buff(msg, RBUFF_SIZE); - if (ret < 0) - return ret; - break; - */ - default: - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_GETDATA: - case ECS_IOCTL_APP_GET_ABS: - if (copy_to_user(argp, &msg, sizeof(msg))) - return -EFAULT; - break; - case GYROSENSOR_IOCTL_GET_ENABLED: - mmaprintk("%s :enter\n",__FUNCTION__); - ret=!l3g4200d->status; - if (copy_to_user(argp, &ret, sizeof(ret))) - return 0; - break; - default: - break; - } - - return 0; -} - -static void l3g4200d_work_func(struct work_struct *work) -{ - struct l3g4200d_data *l3g4200d = container_of(work, struct l3g4200d_data, work); - struct i2c_client *client = l3g4200d->client; - - if (l3g4200d_get_data(client) < 0) - mmaprintk(KERN_ERR "L3G4200D mma_work_func: Get data failed\n"); - - enable_irq(client->irq); -} - -static void l3g4200d_delaywork_func(struct work_struct *work) -{ - struct delayed_work *delaywork = container_of(work, struct delayed_work, work); - struct l3g4200d_data *l3g4200d = container_of(delaywork, struct l3g4200d_data, delaywork); - struct i2c_client *client = l3g4200d->client; - - if (l3g4200d_get_data(client) < 0) - mmaprintk(KERN_ERR "L3G4200D mma_work_func: Get data failed\n"); - enable_irq(client->irq); -} - -static irqreturn_t l3g4200d_interrupt(int irq, void *dev_id) -{ - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)dev_id; - - disable_irq_nosync(irq); - schedule_delayed_work(&l3g4200d->delaywork, msecs_to_jiffies(200)); - //mmaprintk("%s :enter\n",__FUNCTION__); - return IRQ_HANDLED; -} - -static struct file_operations l3g4200d_fops = { - .owner = THIS_MODULE, - .open = l3g4200d_open, - .release = l3g4200d_release, - .ioctl = l3g4200d_ioctl, -}; - -static struct miscdevice l3g4200d_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "gyrosensor",//"l3g4200d_daemon", - .fops = &l3g4200d_fops, -}; - -static int l3g4200d_remove(struct i2c_client *client) -{ - struct l3g4200d_data *l3g4200d = i2c_get_clientdata(client); - - misc_deregister(&l3g4200d_device); - input_unregister_device(l3g4200d->input_dev); - input_free_device(l3g4200d->input_dev); - free_irq(client->irq, l3g4200d); - kfree(l3g4200d); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&l3g4200d_early_suspend); -#endif - this_client = NULL; - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void l3g4200d_suspend(struct early_suspend *h) -{ - struct i2c_client *client = container_of(l3g4200d_device.parent, struct i2c_client, dev); - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(client); -// if(l3g4200d->status == L3G4200D_OPEN) -// { - //l3g4200d->status = L3G4200D_SUSPEND; -// l3g4200d_close_dev(client); -// } -} - -static void l3g4200d_resume(struct early_suspend *h) -{ - struct i2c_client *client = container_of(l3g4200d_device.parent, struct i2c_client, dev); - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(client); - mmaprintk("Gsensor mma7760 resume!! l3g4200d->status %d\n",l3g4200d->status); - //if((l3g4200d->status == L3G4200D_SUSPEND) && (l3g4200d->status != L3G4200D_OPEN)) -// if (l3g4200d->status == L3G4200D_OPEN) -// l3g4200d_start_dev(client,l3g4200d->curr_tate); -} -#else -static int l3g4200d_suspend(struct i2c_client *client, pm_message_t mesg) -{ - int ret; - mmaprintk("Gsensor mma7760 enter 2 level suspend l3g4200d->status %d\n",l3g4200d->status); - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(client); -// if(l3g4200d->status == L3G4200D_OPEN) -// { - // l3g4200d->status = L3G4200D_SUSPEND; -// ret = l3g4200d_close_dev(client); -// } - return ret; -} -static int l3g4200d_resume(struct i2c_client *client) -{ - int ret; - struct l3g4200d_data *l3g4200d = (struct l3g4200d_data *)i2c_get_clientdata(client); - mmaprintk("Gsensor mma7760 2 level resume!! l3g4200d->status %d\n",l3g4200d->status); -// if((l3g4200d->status == L3G4200D_SUSPEND) && (l3g4200d->status != L3G4200D_OPEN)) -//if (l3g4200d->status == L3G4200D_OPEN) -// ret = l3g4200d_start_dev(client, l3g4200d->curr_tate); - return ret; -} -#endif - -static const struct i2c_device_id l3g4200d_id[] = { - {"gs_l3g4200d", 0}, - { } -}; - -static struct i2c_driver l3g4200d_driver = { - .driver = { - .name = "gs_l3g4200d", - }, - .id_table = l3g4200d_id, - .probe = l3g4200d_probe, - .remove = __devexit_p(l3g4200d_remove), -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = &l3g4200d_suspend, - .resume = &l3g4200d_resume, -#endif -}; - - -static int l3g4200d_init_client(struct i2c_client *client) -{ - struct l3g4200d_data *l3g4200d; - int ret; - l3g4200d = i2c_get_clientdata(client); - mmaprintk("gpio_to_irq(%d) is %d\n",client->irq,gpio_to_irq(client->irq)); - if ( !gpio_is_valid(client->irq)) { - mmaprintk("+++++++++++gpio_is_invalid\n"); - return -EINVAL; - } - ret = gpio_request(client->irq, "l3g4200d_int"); - if (ret) { - mmaprintk( "failed to request mma7990_trig GPIO%d\n",gpio_to_irq(client->irq)); - return ret; - } - ret = gpio_direction_input(client->irq); - if (ret) { - mmaprintk("failed to set mma7990_trig GPIO gpio input\n"); - return ret; - } - gpio_pull_updown(client->irq, GPIOPullUp); - client->irq = gpio_to_irq(client->irq); - ret = request_irq(client->irq, l3g4200d_interrupt, IRQF_TRIGGER_LOW, client->dev.driver->name, l3g4200d); - mmaprintk("request irq is %d,ret is 0x%x\n",client->irq,ret); - if (ret ) { - mmaprintk(KERN_ERR "l3g4200d_init_client: request irq failed,ret is %d\n",ret); - return ret; - } - disable_irq(client->irq); - init_waitqueue_head(&data_ready_wq); - - return 0; -} - - -static int l3g4200d_validate_pdata(struct l3g4200d_data *gyro) -{ - if (gyro->pdata->axis_map_x > 2 || - gyro->pdata->axis_map_y > 2 || - gyro->pdata->axis_map_z > 2) { - dev_err(&gyro->client->dev, - "invalid axis_map value x:%u y:%u z%u\n", - gyro->pdata->axis_map_x, gyro->pdata->axis_map_y, - gyro->pdata->axis_map_z); - return -EINVAL; - } - - /* Only allow 0 and 1 for negation boolean flag */ - if (gyro->pdata->negate_x > 1 || - gyro->pdata->negate_y > 1 || - gyro->pdata->negate_z > 1) { - dev_err(&gyro->client->dev, - "invalid negate value x:%u y:%u z:%u\n", - gyro->pdata->negate_x, gyro->pdata->negate_y, - gyro->pdata->negate_z); - return -EINVAL; - } - - return 0; -} - - - - -static int l3g4200d_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct l3g4200d_data *l3g4200d; - struct l3g4200d_platform_data *pdata = pdata = client->dev.platform_data; - int err; - - mmaprintk("%s enter\n",__FUNCTION__); - - l3g4200d = kzalloc(sizeof(struct l3g4200d_data), GFP_KERNEL); - if (!l3g4200d) { - mmaprintk("[l3g4200d]:alloc data failed.\n"); - err = -ENOMEM; - goto exit_alloc_data_failed; - } - - INIT_WORK(&l3g4200d->work, l3g4200d_work_func); - INIT_DELAYED_WORK(&l3g4200d->delaywork, l3g4200d_delaywork_func); - - l3g4200d->client = client; - i2c_set_clientdata(client, l3g4200d); - - this_client = client; - - err = l3g4200d_init_client(client); - if (err < 0) { - mmaprintk(KERN_ERR - "l3g4200d_probe: l3g4200d_init_client failed\n"); - goto exit_request_gpio_irq_failed; - } - - - l3g4200d->pdata = kmalloc(sizeof(*l3g4200d->pdata), GFP_KERNEL); - - if (l3g4200d->pdata == NULL) - goto exit_kfree; - - memcpy(l3g4200d->pdata, client->dev.platform_data, sizeof(*l3g4200d->pdata)); - - err = l3g4200d_validate_pdata(l3g4200d); - if (err < 0) { - dev_err(&client->dev, "failed to validate platform data\n"); - goto exit_kfree_pdata; - } - this_data=l3g4200d; - - - - - l3g4200d->input_dev = input_allocate_device(); - if (!l3g4200d->input_dev) { - err = -ENOMEM; - mmaprintk(KERN_ERR - "l3g4200d_probe: Failed to allocate input device\n"); - goto exit_input_allocate_device_failed; - } - - set_bit(EV_ABS, l3g4200d->input_dev->evbit); - - /* x-axis acceleration */ - input_set_abs_params(l3g4200d->input_dev, ABS_RX, -28571, 28571, 0, 0); //2g full scale range - /* y-axis acceleration */ - input_set_abs_params(l3g4200d->input_dev, ABS_RY, -28571, 28571, 0, 0); //2g full scale range - /* z-axis acceleration */ - input_set_abs_params(l3g4200d->input_dev, ABS_RZ, -28571, 28571, 0, 0); //2g full scale range - - l3g4200d->input_dev->name = "gyro"; - l3g4200d->input_dev->dev.parent = &client->dev; - - err = input_register_device(l3g4200d->input_dev); - if (err < 0) { - mmaprintk(KERN_ERR - "l3g4200d_probe: Unable to register input device: %s\n", - l3g4200d->input_dev->name); - goto exit_input_register_device_failed; - } - - l3g4200d_device.parent = &client->dev; - err = misc_register(&l3g4200d_device); - if (err < 0) { - mmaprintk(KERN_ERR - "l3g4200d_probe: mmad_device register failed\n"); - goto exit_misc_device_register_l3g4200d_device_failed; - } - - err = gsensor_sysfs_init(); - if (err < 0) { - mmaprintk(KERN_ERR - "l3g4200d_probe: gsensor sysfs init failed\n"); - goto exit_gsensor_sysfs_init_failed; - } - -#ifdef CONFIG_HAS_EARLYSUSPEND - l3g4200d_early_suspend.suspend = l3g4200d_suspend; - l3g4200d_early_suspend.resume = l3g4200d_resume; - l3g4200d_early_suspend.level = 0x2; - register_early_suspend(&l3g4200d_early_suspend); -#endif - if(l3g4200d_get_devid(this_client)) - printk(KERN_INFO "l3g4200d probe ok\n"); - else - printk(KERN_INFO "l3g4200d probe error\n"); - - - l3g4200d->status = -1; -#if 0 -// l3g4200d_start_test(this_client); - l3g4200d_start(client, L3G4200D_RATE_12P5); -#endif - return 0; - -exit_gsensor_sysfs_init_failed: - misc_deregister(&l3g4200d_device); -exit_misc_device_register_l3g4200d_device_failed: - input_unregister_device(l3g4200d->input_dev); -exit_input_register_device_failed: - input_free_device(l3g4200d->input_dev); -exit_input_allocate_device_failed: - free_irq(client->irq, l3g4200d); -exit_kfree_pdata: - kfree(l3g4200d->pdata); -exit_kfree: -exit_request_gpio_irq_failed: - kfree(l3g4200d); -exit_alloc_data_failed: - ; -exit: - mmaprintk("%s error\n",__FUNCTION__); - return err; -} - - -static int __init l3g4200d_i2c_init(void) -{ - return i2c_add_driver(&l3g4200d_driver); -} - -static void __exit l3g4200d_i2c_exit(void) -{ - i2c_del_driver(&l3g4200d_driver); -} - -module_init(l3g4200d_i2c_init); -module_exit(l3g4200d_i2c_exit); - - diff --git a/drivers/input/gsensor/lis3dh.c b/drivers/input/gsensor/lis3dh.c deleted file mode 100644 index 6bd453e55404..000000000000 --- a/drivers/input/gsensor/lis3dh.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - - /**************************************************************************************** - * File: driver/input/gsensor/lis3dh.c - * Copyright: Copyright (C) 2012-2013 RK Corporation. - * Author: LiBing - * Date: 2012.03.06 - * Description: This driver use for rk29 chip extern gsensor. Use i2c IF ,the chip is - * STMicroelectronics lis3dh. - *****************************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - -#include "lis3dh.h" - -#if 0 -#define stprintk(x...) printk(x) -#else -#define stprintk(x...) -#endif - -#if 0 -#define stprintkd(x...) printk(x) -#else -#define stprintkd(x...) -#endif - -#if 0 -#define stprintkf(x...) printk(x) -#else -#define stprintkf(x...) -#endif - - -static struct i2c_client *this_client; -static struct miscdevice lis3dh_device; -static struct kobject *android_gsensor_kobj; -static const char* vendor = "STMicroelectronics"; -static int suspend_flag; -static int lis3dh_probe(struct i2c_client *client, const struct i2c_device_id *id); -static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq); - -/* AKM HW info */ -static ssize_t gsensor_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - ssize_t liRet = 0; - - sprintf(buf, "%s.\n", vendor); - liRet = strlen(buf) + 1; - - return liRet; -} - -static DEVICE_ATTR(vendor, 0444, gsensor_vendor_show, NULL); - -static int gsensor_sysfs_init(void) -{ - int liRet ; - - android_gsensor_kobj = kobject_create_and_add("android_gsensor", NULL); - if (android_gsensor_kobj == NULL) - { - stprintk(KERN_ERR "LIS3DH gsensor_sysfs_init:subsystem_register failed\n"); - liRet = -ENOMEM; - goto kobject_create_failed; - } - else - { - //nothing - } - - liRet = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr); // "vendor" - if (liRet) { - stprintk(KERN_ERR "LIS3DH gsensor_sysfs_init:sysfs_create_group failed\n"); - goto sysfs_create_failed; - } - else - { - //nothing - } - - return 0 ; - -sysfs_create_failed: - kobject_del(android_gsensor_kobj); - -kobject_create_failed: - return liRet ; - -} - -static int lis3dh_rx_data(struct i2c_client *client, char *rxData, int length) -{ - int liRet = 0; - char lcReg = rxData[0]; - liRet = i2c_master_reg8_recv(client, lcReg, rxData, length, LIS3DH_SPEED); - - return (liRet > 0)? 0 : liRet; -} - -static int lis3dh_tx_data(struct i2c_client *client, char *txData, int length) -{ - int liRet = 0; - char lcReg = txData[0]; - liRet = i2c_master_reg8_send(client, lcReg, &txData[1], length-1, LIS3DH_SPEED); - - return (liRet > 0)? 0 : liRet; -} - -static char lis3dh_read_reg(struct i2c_client *client, int addr) -{ - char liTmp; - int liRet = 0; - - liTmp = addr; - liRet = lis3dh_rx_data(client, &liTmp, 1); - return liTmp; -} - -static int lis3dh_write_reg(struct i2c_client *client,int addr,int value) -{ - char buffer[3]; - int liRet = 0; - buffer[0] = addr; - buffer[1] = value; - - liRet = lis3dh_tx_data(client, &buffer[0], 2); - return liRet; -} - -static int lis3dh_init_device(struct lis3dh_data *lis3dh) -{ - int liRet =-1; - - memset(lis3dh->resume_state, 0, ARRAY_SIZE(lis3dh->resume_state)); - lis3dh->resume_state[RES_CTRL_REG1] = LIS3DH_ACC_ENABLE_ALL_AXES; - lis3dh->resume_state[RES_CTRL_REG2] = 0x00; - lis3dh->resume_state[RES_CTRL_REG3] = 0x40; - lis3dh->resume_state[RES_CTRL_REG4] = 0x08; - lis3dh->resume_state[RES_CTRL_REG5] = 0x08; - lis3dh->resume_state[RES_CTRL_REG6] = 0x40; - lis3dh->resume_state[RES_TEMP_CFG_REG] = 0x00; - lis3dh->resume_state[RES_FIFO_CTRL_REG] = 0x00; - lis3dh->resume_state[RES_INT_CFG1] = 0xFF; - lis3dh->resume_state[RES_INT_THS1] = 0x7F; - lis3dh->resume_state[RES_INT_DUR1] = 0x7F; //0x00->ox7f - lis3dh->resume_state[RES_TT_CFG] = 0x00; - lis3dh->resume_state[RES_TT_THS] = 0x00; - lis3dh->resume_state[RES_TT_LIM] = 0x00; - lis3dh->resume_state[RES_TT_TLAT] = 0x00; - lis3dh->resume_state[RES_TT_TW] = 0x00; - - liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG1, lis3dh->resume_state[RES_CTRL_REG1]); - if (liRet < 0) - { - printk("RES_CTRL_REG1 err\n"); - return 0; - } - else - { - //nothing - } - - liRet =lis3dh_write_reg(lis3dh->client, TEMP_CFG_REG, lis3dh->resume_state[RES_TEMP_CFG_REG]); - if (liRet < 0) - { - printk("TEMP_CFG_REG err\n"); - return 0; - } - else - { - //nothing - } - - liRet =lis3dh_write_reg(lis3dh->client, FIFO_CTRL_REG, lis3dh->resume_state[RES_FIFO_CTRL_REG]); - if(liRet < 0) - { - printk("FIFO_CTRL_REG err\n"); - return 0; - } - else - { - //nothing - } - - liRet =lis3dh_write_reg(lis3dh->client, TT_THS, lis3dh->resume_state[RES_TT_THS]); - liRet =lis3dh_write_reg(lis3dh->client, TT_LIM, lis3dh->resume_state[RES_TT_LIM]); - liRet =lis3dh_write_reg(lis3dh->client, TT_TLAT, lis3dh->resume_state[RES_TT_TLAT]); - liRet =lis3dh_write_reg(lis3dh->client, TT_TW, lis3dh->resume_state[RES_TT_TW]); - if(liRet < 0) - { - printk("I2C_AUTO_INCREMENT err\n"); - return 0; - } - else - { - //nothing - } - - liRet =lis3dh_write_reg(lis3dh->client, TT_CFG, lis3dh->resume_state[RES_TT_CFG]); - if(liRet < 0) - { - printk("TT_CFG err\n"); - return 0; - } - else - { - //nothing - } - - liRet =lis3dh_write_reg(lis3dh->client, INT_THS1, lis3dh->resume_state[RES_INT_THS1]); - liRet =lis3dh_write_reg(lis3dh->client, INT_DUR1, lis3dh->resume_state[RES_INT_DUR1]); - if(liRet < 0) - { - printk("I2C_AUTO_INCREMENT err\n"); - return 0; - } - else - { - //nothing - } - - liRet =lis3dh_write_reg(lis3dh->client, INT_CFG1, lis3dh->resume_state[RES_INT_CFG1]); - if(liRet < 0) - { - printk("INT_CFG1 err\n"); - return 0; - } - else - { - //nothing - } - - liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG2, lis3dh->resume_state[RES_CTRL_REG2]); - liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG3, lis3dh->resume_state[RES_CTRL_REG3]); - liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG4, lis3dh->resume_state[RES_CTRL_REG4]); - liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG5, lis3dh->resume_state[RES_CTRL_REG5]); - liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG6, lis3dh->resume_state[RES_CTRL_REG6]); - if(liRet < 0) - { - printk("I2C_AUTO_INCREMENT err\n"); - return 0; - } - else - { - //nothing - } - - return liRet; -} - -static char lis3dh_get_devid(struct lis3dh_data *lis3dh) -{ - char lcDeviceID; - - lcDeviceID = lis3dh_read_reg(lis3dh->client,WHO_AM_I); - if(lcDeviceID < 0) - { - printk("devid err\n"); - return 0; - } - else - { - printk("lis3dh devid:%x\n",lcDeviceID); - } - - return lcDeviceID; -} - -static int lis3dh_active(struct i2c_client *client,int enable) -{ - int liTmp = 0; - int liRet = 0; - - liTmp =lis3dh_read_reg(client, CTRL_REG1); - if(enable) - { - liTmp |= LIS3DH_ACC_ENABLE_ALL_AXES; - } - else - { - liTmp = 0x08; - } - - liRet =lis3dh_write_reg(client, CTRL_REG1, liTmp); - - return liRet; -} - -static int lis3dh_start_dev(struct i2c_client *client, char rate) -{ - int liRet = 0; - int liRate = 0; - char lcTmp = 0x0; - struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - - if((int)rate == 5) - { - liRate = 3; - } - else if((int)rate == 6) - { - liRate = 2; - } - else - { - liRate = 4; - } - - lcTmp = liRate<<4 | LIS3DH_ACC_ENABLE_ALL_AXES; - - liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG1, lcTmp); - if (liRet < 0) - { - printk(KERN_ERR "lis3dh_start_dev err\n"); - } - else - { - stprintkf("lis3dh_start_dev\n"); - } - lis3dh_active(client,1); - enable_irq(client->irq); - return liRet; -} - -static int lis3dh_start(struct i2c_client *client, char rate) -{ - struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - - stprintkf("%s::enter\n",__FUNCTION__); - if (lis3dh->status == LIS3DH_OPEN) - { - return 0; - } - else - { - //nothing - } - lis3dh->status = LIS3DH_OPEN; - - return lis3dh_start_dev(client, rate); -} - -static int lis3dh_close_dev(struct i2c_client *client) -{ - disable_irq_nosync(client->irq); - return lis3dh_active(client,0); -} - -static int lis3dh_close(struct i2c_client *client) -{ - struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - stprintkf("%s::enter\n",__FUNCTION__); - lis3dh->status = LIS3DH_CLOSE; - return lis3dh_close_dev(client); -} - -static int lis3dh_reset_rate(struct i2c_client *client, char rate) -{ - int liRet = 0; - - liRet = lis3dh_close_dev(client); - liRet = lis3dh_start_dev(client, rate); - - return liRet ; -} - -static void lis3dh_report_value(struct i2c_client *client, struct lis3dh_axis *axis) -{ - struct lis3dh_data *lis3dh = i2c_get_clientdata(client); - - /* Report acceleration sensor information */ - input_report_abs(lis3dh->input_dev, ABS_X, axis->x); - input_report_abs(lis3dh->input_dev, ABS_Y, axis->y); - input_report_abs(lis3dh->input_dev, ABS_Z, axis->z); - input_sync(lis3dh->input_dev); - stprintkd("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z); -} - -static inline s64 lis3dh_convert_to_int(const char High_Value, const char Low_Value) -{ - s64 liResult; - - liResult = ((long) High_Value << 8) | Low_Value; - - if (liResult < LIS3DH_BOUNDARY) - { - liResult = liResult * LIS3DH_GRAVITY_STEP; - } - else - { - liResult = ~(((~liResult & 0x7fff) + 1)* LIS3DH_GRAVITY_STEP) + 1; - } - - return liResult; -} - -/**get the gsensor data. */ -static int lis3dh_get_data(struct i2c_client *client) -{ - int liResult; - int x,y,z; - char acc_data[6]; - - struct lis3dh_axis axis; - struct lis3dh_data* lis3dh = i2c_get_clientdata(client); - struct gsensor_platform_data *pdata = pdata = client->dev.platform_data; - - /* x,y,z hardware data */ - do { - - memset(acc_data, 0, 6); - acc_data[0] = (I2C_AUTO_INCREMENT | AXISDATA_REG); - - liResult = lis3dh_rx_data(client, &acc_data[0], 6); - if (liResult < 0) - { - return liResult; - } - else - { - //nothing - } - } while (0); - - stprintkd("0x%02x 0x%02x 0x%02x \n",acc_data[1],acc_data[3],acc_data[5]); - - z = -lis3dh_convert_to_int(acc_data[1],acc_data[0]); - x = -lis3dh_convert_to_int(acc_data[3],acc_data[2]); - y = lis3dh_convert_to_int(acc_data[5],acc_data[4]); - - axis.x = x; - axis.y = z; - axis.z = y; - - if (pdata->swap_xyz) - { - 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; - } - else - { - axis.x = x; - axis.y = y; - axis.z = z; - } - - if(pdata->swap_xy) - { - axis.x = -axis.x; - swap(axis.x,axis.y); - } - - stprintkd( "%s: GetData axis = %d %d %d-------\n",__func__, axis.x, axis.y, axis.z); - - lis3dh_report_value(client, &axis); - - /* Caching data mutually exclusive.*/ - mutex_lock(&(lis3dh->sense_data_mutex) ); - lis3dh->sense_data = axis; - mutex_unlock(&(lis3dh->sense_data_mutex) ); - - /* set data_ready */ - atomic_set(&(lis3dh->data_ready), 1); - /* wakeup the data_ready,the first of wait queue */ - wake_up(&(lis3dh->data_ready_wq) ); - - return 0; -} - -static int lis3dh_get_cached_data(struct i2c_client* client, struct lis3dh_axis* sense_data) -{ - struct lis3dh_data* lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - - wait_event_interruptible_timeout(lis3dh->data_ready_wq, - atomic_read(&(lis3dh->data_ready) ),msecs_to_jiffies(1000) ); - - if ( 0 == atomic_read(&(lis3dh->data_ready) ) ) - { - printk("waiting 'data_ready_wq' timed out."); - return -1; - } - else - { - //nothing - } - - mutex_lock(&(lis3dh->sense_data_mutex)); - *sense_data = lis3dh->sense_data; - mutex_unlock(&(lis3dh->sense_data_mutex)); - - return 0; -} - -static int lis3dh_open(struct inode *inode, struct file *file) -{ - return 0;//nonseekable_open(inode, file); -} - -static int lis3dh_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static long lis3dh_ioctl(struct file *file, unsigned int cmd,unsigned long arg) -{ - int liRet = -1; - char rate; - void __user *argp = (void __user *)arg; - - struct lis3dh_axis sense_data = {0}; - struct i2c_client *client = container_of(lis3dh_device.parent, struct i2c_client, dev); - struct lis3dh_data* lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - - switch (cmd) - { - case ST_IOCTL_APP_SET_RATE: - - if (copy_from_user(&rate, argp, sizeof(rate))) - { - return -EFAULT; - } - else - { - //nothing - } - - break; - - default: - break; - } - - switch (cmd) - { - case ST_IOCTL_START: - - mutex_lock(&(lis3dh->operation_mutex) ); - stprintkd("to perform 'ST_IOCTL_START', former 'start_count' is %d.", lis3dh->start_count); - (lis3dh->start_count)++; - - if ( 1 == lis3dh->start_count ) - { - atomic_set(&(lis3dh->data_ready), 0); - if ( (liRet = lis3dh_start(client, LIS3DH_RATE_12P5) ) < 0 ) - { - mutex_unlock(&(lis3dh->operation_mutex) ); - return liRet; - } - else - { - //nothing - } - } - else - { - //nothing - } - mutex_unlock(&(lis3dh->operation_mutex) ); - stprintkd("finish 'ST_IOCTL_START', ret = %d.", liRet); - return 0; - - case ST_IOCTL_CLOSE: - - mutex_lock(&(lis3dh->operation_mutex) ); - stprintkd("to perform 'ST_IOCTL_CLOSE', former 'start_count' is %d, PID : %d", lis3dh->start_count, get_current()->pid); - if ( 0 == (--(lis3dh->start_count) ) ) - { - atomic_set(&(lis3dh->data_ready), 0); - if ( (liRet = lis3dh_close(client) ) < 0 ) - { - mutex_unlock(&(lis3dh->operation_mutex) ); - return liRet; - } - else - { - //nothing - } - } - mutex_unlock(&(lis3dh->operation_mutex) ); - return 0; - - case ST_IOCTL_APP_SET_RATE: - - liRet = lis3dh_reset_rate(client, rate); - if (liRet< 0) - { - return liRet; - } - else - { - //nothing - } - - break; - - case ST_IOCTL_GETDATA: - if ( (liRet = lis3dh_get_cached_data(client, &sense_data) ) < 0 ) - { - printk("failed to get cached sense data, ret = %d.", liRet); - return liRet; - } - else - { - //nothing - } - break; - - default: - return -ENOTTY; - } - - switch (cmd) - { - case ST_IOCTL_GETDATA: - if ( copy_to_user(argp, &sense_data, sizeof(sense_data) ) ) - { - printk("failed to copy sense data to user space."); - return -EFAULT; - } - else - { - //npthing - } - break; - - default: - break; - } - return 0; -} - -static void lis3dh_work_func(struct work_struct *work) -{ - struct lis3dh_data *lis3dh = container_of(work, struct lis3dh_data, work); - struct i2c_client *client = lis3dh->client; - - if (lis3dh_get_data(client) < 0) - { - stprintkd(KERN_ERR "LIS3DH lis3dh_work_func: Get data failed\n"); - } - else - { - //nothing - } - - enable_irq(client->irq); -} - -static void lis3dh_delaywork_func(struct work_struct *work) -{ - struct delayed_work *delaywork = container_of(work, struct delayed_work, work); - struct lis3dh_data *lis3dh = container_of(delaywork, struct lis3dh_data, delaywork); - struct i2c_client *client = lis3dh->client; - - if (lis3dh_get_data(client) < 0) - { - printk(KERN_ERR " lis3dh_work_func: Get data failed\n"); - } - else - { - //nothing - } - - stprintkd("%s :int src:0x%02x\n",__FUNCTION__,lis3dh_read_reg(lis3dh->client,INT_SRC1)); - if(0==suspend_flag){ - enable_irq(client->irq); - } -} - -static irqreturn_t lis3dh_interrupt(int irq, void *dev_id) -{ - struct lis3dh_data *lis3dh = (struct lis3dh_data *)dev_id; - - disable_irq_nosync(irq); - schedule_delayed_work(&lis3dh->delaywork, msecs_to_jiffies(30)); - stprintkf("%s :enter\n",__FUNCTION__); - return IRQ_HANDLED; -} - -static struct file_operations lis3dh_fops = { - .owner = THIS_MODULE, - .open = lis3dh_open, - .release = lis3dh_release, - .unlocked_ioctl = lis3dh_ioctl, -}; - -static struct miscdevice lis3dh_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "mma8452_daemon",//"mma8452_daemon", - .fops = &lis3dh_fops, -}; - -static int lis3dh_remove(struct i2c_client *client) -{ - struct lis3dh_data *lis3dh = i2c_get_clientdata(client); - - misc_deregister(&lis3dh_device); - input_unregister_device(lis3dh->input_dev); - input_free_device(lis3dh->input_dev); - free_irq(client->irq, lis3dh); - kfree(lis3dh); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&lis3dh_early_suspend); -#endif - this_client = NULL; - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void lis3dh_suspend(struct early_suspend *h) -{ - struct i2c_client *client = container_of(lis3dh_device.parent, struct i2c_client, dev); - struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - suspend_flag=1; - cancel_delayed_work_sync(&(lis3dh->delaywork)); - lis3dh_close(client); -} - -static void lis3dh_resume(struct early_suspend *h) -{ - struct i2c_client *client = container_of(lis3dh_device.parent, struct i2c_client, dev); - struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - suspend_flag=0; - lis3dh_start_dev(client,lis3dh->curr_tate); - enable_irq(client->irq); -} -#else -static int lis3dh_suspend(struct i2c_client *client, pm_message_t mesg) -{ - int liRet; - stprintkd("Gsensor lis3dh enter 2 level suspend lis3dh->status %d\n",lis3dh->status); - struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - - return liRet; -} -static int lis3dh_resume(struct i2c_client *client) -{ - int liRet; - struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client); - stprintkd("Gsensor lis3dh 2 level resume!! lis3dh->status %d\n",lis3dh->status); - return liRet; -} -#endif - -static const struct i2c_device_id lis3dh_id[] = { - {"lis3dh", 0}, - { } -}; - -static struct i2c_driver lis3dh_driver = { - .driver = { - .name = "lis3dh", - }, - .id_table = lis3dh_id, - .probe = lis3dh_probe, - .remove = __devexit_p(lis3dh_remove), -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = &lis3dh_suspend, - .resume = &lis3dh_resume, -#endif -}; - -static int lis3dh_init_client(struct i2c_client *client) -{ - int liRet = 0; - int irq = 0; - struct lis3dh_data *lis3dh; - - lis3dh = i2c_get_clientdata(client); - - liRet = gpio_request(client->irq, "lis3dh_int"); - if (liRet) { - stprintk( "failed to request lis3dh_trig GPIO%d\n",gpio_to_irq(client->irq)); - return liRet; - } - else - { - //nothing - } - - gpio_direction_output(client->irq, 1); - liRet = gpio_direction_input(client->irq); - if (liRet) - { - stprintk("failed to set lis3dh_trig GPIO gpio input\n"); - gpio_free(client->irq); - return liRet; - } - else - { - //nothing - } - - irq = gpio_to_irq(client->irq); - liRet = request_irq(irq, lis3dh_interrupt, IRQF_TRIGGER_LOW, client->dev.driver->name, lis3dh); - if (liRet ) - { - gpio_free(client->irq); - stprintk(KERN_ERR "lis3dh_init_client: request irq failed,ret is %d\n",liRet); - return liRet; - } - else - { - stprintk("request irq is %d,ret is 0x%x\n",irq,liRet); - } - - client->irq = irq; - disable_irq(client->irq); - init_waitqueue_head(&data_ready_wq); - - return 0; -} - -static int lis3dh_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct lis3dh_data *lis3dh; - struct lis3dh_platform_data *pdata = pdata = client->dev.platform_data; - int liRet = -1; - char devid; - - stprintkf("%s enter\n",__FUNCTION__); - - lis3dh = kzalloc(sizeof(struct lis3dh_data), GFP_KERNEL); - if (!lis3dh) - { - stprintk("[lis3dh]:alloc data failed.\n"); - liRet = -ENOMEM; - goto exit_alloc_data_failed; - } - else - { - //nothig - } - - INIT_WORK(&lis3dh->work, lis3dh_work_func); - INIT_DELAYED_WORK(&lis3dh->delaywork, lis3dh_delaywork_func); - - memset(&(lis3dh->sense_data), 0, sizeof(struct lis3dh_axis) ); - mutex_init(&(lis3dh->sense_data_mutex) ); - - atomic_set(&(lis3dh->data_ready), 0); - init_waitqueue_head(&(lis3dh->data_ready_wq) ); - - lis3dh->start_count = 0; - mutex_init(&(lis3dh->operation_mutex) ); - - lis3dh->status = LIS3DH_CLOSE; - lis3dh->client = client; - - i2c_set_clientdata(client, lis3dh); - - this_client = client; - - devid = lis3dh_get_devid(lis3dh); - if (devid != WHOAMI_LIS3DH_ACC) - { - pr_info("lis3dh: invalid devid\n"); - goto exit_invalid_devid; - } - else - { - //nothing - } - - liRet = lis3dh_init_device(lis3dh); - if (devid < 0) - { - pr_info("lis3dh: init err\n"); - goto exit_invalid_devid; - } - else - { - //nothing - } - - liRet = lis3dh_init_client(client); - if (liRet < 0) - { - stprintk(KERN_ERR "lis3dh_probe: lis3dh_init_client failed\n"); - goto exit_request_irq_failed; - } - else - { - //nothing - } - - lis3dh->input_dev = input_allocate_device(); - if (!lis3dh->input_dev) - { - liRet = -ENOMEM; - stprintk(KERN_ERR "lis3dh_probe: Failed to allocate input device\n"); - goto exit_input_allocate_device_failed; - } - else - { - //nothing - } - - set_bit(EV_ABS, lis3dh->input_dev->evbit); - - /* x-axis acceleration */ - input_set_abs_params(lis3dh->input_dev, ABS_X, -LIS3DH_RANGE, LIS3DH_RANGE, 0, 0); //2g full scale range - /* y-axis acceleration */ - input_set_abs_params(lis3dh->input_dev, ABS_Y, -LIS3DH_RANGE, LIS3DH_RANGE, 0, 0); //2g full scale range - /* z-axis acceleration */ - input_set_abs_params(lis3dh->input_dev, ABS_Z, -LIS3DH_RANGE, LIS3DH_RANGE, 0, 0); //2g full scale range - - lis3dh->input_dev->name = "gsensor"; - lis3dh->input_dev->dev.parent = &client->dev; - - liRet = input_register_device(lis3dh->input_dev); - if (liRet < 0) - { - stprintk(KERN_ERR "lis3dh_probe: Unable to register input device: %s\n",lis3dh->input_dev->name); - goto exit_input_register_device_failed; - } - else - { - //nothing - } - - lis3dh_device.parent = &client->dev; - liRet = misc_register(&lis3dh_device); - if (liRet < 0) - { - stprintk(KERN_ERR"lis3dh_probe: mmad_device register failed\n"); - goto exit_misc_device_failed; - } - else - { - //nothing - } - - liRet = gsensor_sysfs_init(); - if (liRet < 0) - { - stprintk(KERN_ERR "lis3dh_probe: gsensor sysfs init failed\n"); - goto exit_gsensor_sysfs_init_failed; - } - else - { - //nothing - } - -#ifdef CONFIG_HAS_EARLYSUSPEND - lis3dh_early_suspend.suspend = lis3dh_suspend; - lis3dh_early_suspend.resume = lis3dh_resume; - lis3dh_early_suspend.level = 0x2; - register_early_suspend(&lis3dh_early_suspend); -#endif - suspend_flag=0; - printk(KERN_INFO "lis3dh probe ok\n"); - - return 0; - -exit_gsensor_sysfs_init_failed: - misc_deregister(&lis3dh_device); -exit_misc_device_failed: - input_unregister_device(lis3dh->input_dev); -exit_input_register_device_failed: - input_free_device(lis3dh->input_dev); -exit_input_allocate_device_failed: - free_irq(client->irq, lis3dh); -exit_request_irq_failed: - cancel_delayed_work_sync(&lis3dh->delaywork); - cancel_work_sync(&lis3dh->work); -exit_invalid_devid: - kfree(lis3dh); -exit_alloc_data_failed: - stprintk("%s error\n",__FUNCTION__); - return -1; -} - -static int __init lis3dh_i2c_init(void) -{ - return i2c_add_driver(&lis3dh_driver); -} - -static void __exit lis3dh_i2c_exit(void) -{ - i2c_del_driver(&lis3dh_driver); -} - -module_init(lis3dh_i2c_init); -module_exit(lis3dh_i2c_exit); - -MODULE_DESCRIPTION ("STMicroelectronics gsensor driver"); -MODULE_AUTHOR("LB"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/gsensor/lis3dh.h b/drivers/input/gsensor/lis3dh.h deleted file mode 100644 index c356d062a283..000000000000 --- a/drivers/input/gsensor/lis3dh.h +++ /dev/null @@ -1,186 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/**************************************************************************************** - * File: driver/input/gsensor/lis3dh.h - * Copyright: Copyright (C) 2012-2013 RK Corporation. - * Author: LiBing - * Date: 2012.03.06 - * Description: This driver use for rk29 chip extern gsensor. Use i2c IF ,the chip is - * STMicroelectronics lis3dh. - *****************************************************************************************/ - -#ifndef LIS3DH_H -#define LIS3DH_H - -#include - -#define ODR1 0x10 /* 1Hz output data rate */ -#define ODR10 0x20 /* 10Hz output data rate */ -#define ODR25 0x30 /* 25Hz output data rate */ -#define ODR50 0x40 /* 50Hz output data rate */ -#define ODR100 0x50 /* 100Hz output data rate */ -#define ODR200 0x60 /* 200Hz output data rate */ -#define ODR400 0x70 /* 400Hz output data rate */ -#define ODR1250 0x90 /* 1250Hz output data rate */ - -#define SENSITIVITY_2G 1 /** mg/LSB */ -#define SENSITIVITY_4G 2 /** mg/LSB */ -#define SENSITIVITY_8G 4 /** mg/LSB */ -#define SENSITIVITY_16G 12 /** mg/LSB */ - -#define HIGH_RESOLUTION 0x08 - -/* Accelerometer Sensor Full Scale */ -#define LIS3DH_ACC_FS_MASK 0x30 -#define LIS3DH_ACC_G_2G 0x00 -#define LIS3DH_ACC_G_4G 0x10 -#define LIS3DH_ACC_G_8G 0x20 -#define LIS3DH_ACC_G_16G 0x30 - -#define WHO_AM_I 0x0F -#define WHOAMI_LIS3DH_ACC 0x33 -#define AXISDATA_REG 0x28 - -#define I2C_AUTO_INCREMENT 0x80 -#define I2C_RETRY_DELAY 5 -#define I2C_RETRIES 5 - -#define RESUME_ENTRIES 17 - -#define RES_CTRL_REG1 0 -#define RES_CTRL_REG2 1 -#define RES_CTRL_REG3 2 -#define RES_CTRL_REG4 3 -#define RES_CTRL_REG5 4 -#define RES_CTRL_REG6 5 - -#define RES_INT_CFG1 6 -#define RES_INT_THS1 7 -#define RES_INT_DUR1 8 - -#define RES_TT_CFG 9 -#define RES_TT_THS 10 -#define RES_TT_LIM 11 -#define RES_TT_TLAT 12 -#define RES_TT_TW 13 -#define TT_CFG 0x38 /* tap config */ -#define TT_SRC 0x39 /* tap source */ -#define TT_THS 0x3A /* tap threshold */ -#define TT_LIM 0x3B /* tap time limit */ -#define TT_TLAT 0x3C /* tap time latency */ -#define TT_TW 0x3D /* tap time window */ - -#define RES_TEMP_CFG_REG 14 -#define RES_REFERENCE_REG 15 -#define RES_FIFO_CTRL_REG 16 - -#define CTRL_REG1 0x20 /* control reg 1 */ -#define CTRL_REG2 0x21 /* control reg 2 */ -#define CTRL_REG3 0x22 /* control reg 3 */ -#define CTRL_REG4 0x23 /* control reg 4 */ -#define CTRL_REG5 0x24 /* control reg 5 */ -#define CTRL_REG6 0x25 /* control reg 6 */ - -#define TEMP_CFG_REG 0x1F /* temper sens control reg */ - -#define FIFO_CTRL_REG 0x2E /* FiFo control reg */ - -#define INT_CFG1 0x30 /* interrupt 1 config */ -#define INT_SRC1 0x31 /* interrupt 1 source */ -#define INT_THS1 0x32 /* interrupt 1 threshold */ -#define INT_DUR1 0x33 /* interrupt 1 duration */ - -/* Default register settings */ -#define RBUFF_SIZE 12 /* Rx buffer size */ -#define STIO 0xA1 - -/* IOCTLs for LIS3DH library */ -#define ST_IOCTL_INIT _IO(STIO, 0x01) -#define ST_IOCTL_RESET _IO(STIO, 0x04) -#define ST_IOCTL_CLOSE _IO(STIO, 0x02) -#define ST_IOCTL_START _IO(STIO, 0x03) -#define ST_IOCTL_GETDATA _IOR(STIO, 0x08, char[RBUFF_SIZE+1]) - -/* IOCTLs for APPs */ -#define ST_IOCTL_APP_SET_RATE _IOW(STIO, 0x10, char) - -/*rate*/ -#define LIS3DH_RATE_800 0 -#define LIS3DH_RATE_400 1 -#define LIS3DH_RATE_200 2 -#define LIS3DH_RATE_100 3 -#define LIS3DH_RATE_50 4 -#define LIS3DH_RATE_12P5 5 -#define LIS3DH_RATE_6P25 6 -#define LIS3DH_RATE_1P56 7 -#define LIS3DH_RATE_SHIFT 3 -#define LIS3DH_ASLP_RATE_50 0 -#define LIS3DH_ASLP_RATE_12P5 1 -#define LIS3DH_ASLP_RATE_6P25 2 -#define LIS3DH_ASLP_RATE_1P56 3 -#define LIS3DH_ASLP_RATE_SHIFT 6 - -#define ACTIVE_MASK 1 -#define FREAD_MASK 2 - -/*status*/ -#define LIS3DH_SUSPEND 2 -#define LIS3DH_OPEN 1 -#define LIS3DH_CLOSE 0 -#define LIS3DH_SPEED 200 * 1000 - -#define LIS3DH_ACC_ENABLE_ALL_AXES 0x07 - -#define LIS3DH_RANGE 2000000 -#define LIS3DH_PRECISION 16 //8bit data -#define LIS3DH_BOUNDARY (0x1 << (LIS3DH_PRECISION - 1)) -#define LIS3DH_GRAVITY_STEP LIS3DH_RANGE / LIS3DH_BOUNDARY //2g full scale range - -#ifdef CONFIG_HAS_EARLYSUSPEND -static struct early_suspend lis3dh_early_suspend; -#endif - -struct -{ - unsigned int cutoff_ms; - unsigned int mask; -}lis3dh_acc_odr_table[] = -{ - { 1, ODR1250}, - { 3, ODR400 }, - { 5, ODR200 }, - { 10, ODR100 }, - { 20, ODR50 }, - { 40, ODR25 }, - { 100, ODR10 }, - { 1000, ODR1 }, -}; - -struct lis3dh_axis { - int x; - int y; - int z; -}; - - -struct lis3dh_data { - char status; - char curr_tate; - - unsigned int poll_interval; - unsigned int min_interval; - - struct input_dev *input_dev; - struct i2c_client *client; - struct work_struct work; - struct delayed_work delaywork; /*report second event*/ - struct lis3dh_axis sense_data; - struct mutex sense_data_mutex; - struct mutex operation_mutex; - - atomic_t data_ready; - wait_queue_head_t data_ready_wq; - int start_count; - u8 resume_state[RESUME_ENTRIES]; -}; - -#endif diff --git a/drivers/input/gsensor/lis3dh_acc_misc.c b/drivers/input/gsensor/lis3dh_acc_misc.c deleted file mode 100755 index 9805ceb807eb..000000000000 --- a/drivers/input/gsensor/lis3dh_acc_misc.c +++ /dev/null @@ -1,1505 +0,0 @@ -/******************** (C) COPYRIGHT 2010 STMicroelectronics ******************** - * - * File Name : lis3dh_acc.c - * Authors : MSH - Motion Mems BU - Application Team - * : Carmine Iascone (carmine.iascone@st.com) - * : Matteo Dameno (matteo.dameno@st.com) - * Version : V.1.0.5 - * Date : 16/08/2010 - * Description : LIS3DH accelerometer sensor API - * - ******************************************************************************* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES - * OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE - * PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT. - * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, - * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE - * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING - * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS. - * - ****************************************************************************** - Revision 1.0.0 05/11/09 - First Release - Revision 1.0.3 22/01/2010 - Linux K&R Compliant Release; - Revision 1.0.5 16/08/2010 - modified _get_acceleration_data function - modified _update_odr function - manages 2 interrupts - - ******************************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -//#include -#include "lis3dh_acc_misc.h" - - -#define DEBUG 1 - -#define INTERRUPT_MANAGEMENT 1 - -#define G_MAX 16000 /** Maximum polled-device-reported g value */ - -/* -#define SHIFT_ADJ_2G 4 -#define SHIFT_ADJ_4G 3 -#define SHIFT_ADJ_8G 2 -#define SHIFT_ADJ_16G 1 -*/ - -#define SENSITIVITY_2G 1 /** mg/LSB */ -#define SENSITIVITY_4G 2 /** mg/LSB */ -#define SENSITIVITY_8G 4 /** mg/LSB */ -#define SENSITIVITY_16G 12 /** mg/LSB */ - - -#define HIGH_RESOLUTION 0x08 - -#define AXISDATA_REG 0x28 -#define WHOAMI_LIS3DH_ACC 0x33 /* Expctd content for WAI */ - -/* CONTROL REGISTERS */ -#define WHO_AM_I 0x0F /* WhoAmI register */ -#define TEMP_CFG_REG 0x1F /* temper sens control reg */ -/* ctrl 1: ODR3 ODR2 ODR ODR0 LPen Zenable Yenable Zenable */ -#define CTRL_REG1 0x20 /* control reg 1 */ -#define CTRL_REG2 0x21 /* control reg 2 */ -#define CTRL_REG3 0x22 /* control reg 3 */ -#define CTRL_REG4 0x23 /* control reg 4 */ -#define CTRL_REG5 0x24 /* control reg 5 */ -#define CTRL_REG6 0x25 /* control reg 6 */ - -#define FIFO_CTRL_REG 0x2E /* FiFo control reg */ - -#define INT_CFG1 0x30 /* interrupt 1 config */ -#define INT_SRC1 0x31 /* interrupt 1 source */ -#define INT_THS1 0x32 /* interrupt 1 threshold */ -#define INT_DUR1 0x33 /* interrupt 1 duration */ - -#define INT_CFG2 0x34 /* interrupt 2 config */ -#define INT_SRC2 0x35 /* interrupt 2 source */ -#define INT_THS2 0x36 /* interrupt 2 threshold */ -#define INT_DUR2 0x37 /* interrupt 2 duration */ - -#define TT_CFG 0x38 /* tap config */ -#define TT_SRC 0x39 /* tap source */ -#define TT_THS 0x3A /* tap threshold */ -#define TT_LIM 0x3B /* tap time limit */ -#define TT_TLAT 0x3C /* tap time latency */ -#define TT_TW 0x3D /* tap time window */ -/* end CONTROL REGISTRES */ - - -#define ENABLE_HIGH_RESOLUTION 1 - -#define LIS3DH_ACC_PM_OFF 0x00 -#define LIS3DH_ACC_ENABLE_ALL_AXES 0x07 - -#define PMODE_MASK 0x08 -#define ODR_MASK 0XF0 - -#define ODR1 0x10 /* 1Hz output data rate */ -#define ODR10 0x20 /* 10Hz output data rate */ -#define ODR25 0x30 /* 25Hz output data rate */ -#define ODR50 0x40 /* 50Hz output data rate */ -#define ODR100 0x50 /* 100Hz output data rate */ -#define ODR200 0x60 /* 200Hz output data rate */ -#define ODR400 0x70 /* 400Hz output data rate */ -#define ODR1250 0x90 /* 1250Hz output data rate */ - - - -#define IA 0x40 -#define ZH 0x20 -#define ZL 0x10 -#define YH 0x08 -#define YL 0x04 -#define XH 0x02 -#define XL 0x01 -/* */ -/* CTRL REG BITS*/ -#define CTRL_REG3_I1_AOI1 0x40 -#define CTRL_REG6_I2_TAPEN 0x80 -#define CTRL_REG6_HLACTIVE 0x02 -/* */ - -/* TAP_SOURCE_REG BIT */ -#define DTAP 0x20 -#define STAP 0x10 -#define SIGNTAP 0x08 -#define ZTAP 0x04 -#define YTAP 0x02 -#define XTAZ 0x01 - - -#define FUZZ 32 -#define FLAT 32 -#define I2C_RETRY_DELAY 5 -#define I2C_RETRIES 5 -#define I2C_AUTO_INCREMENT 0x80 - -/* RESUME STATE INDICES */ -#define RES_CTRL_REG1 0 -#define RES_CTRL_REG2 1 -#define RES_CTRL_REG3 2 -#define RES_CTRL_REG4 3 -#define RES_CTRL_REG5 4 -#define RES_CTRL_REG6 5 - -#define RES_INT_CFG1 6 -#define RES_INT_THS1 7 -#define RES_INT_DUR1 8 -#define RES_INT_CFG2 9 -#define RES_INT_THS2 10 -#define RES_INT_DUR2 11 - -#define RES_TT_CFG 12 -#define RES_TT_THS 13 -#define RES_TT_LIM 14 -#define RES_TT_TLAT 15 -#define RES_TT_TW 16 - -#define RES_TEMP_CFG_REG 17 -#define RES_REFERENCE_REG 18 -#define RES_FIFO_CTRL_REG 19 - -#define RESUME_ENTRIES 20 -/* end RESUME STATE INDICES */ - -struct { - unsigned int cutoff_ms; - unsigned int mask; -} lis3dh_acc_odr_table[] = { - { 1, ODR1250 }, - { 3, ODR400 }, - { 5, ODR200 }, - { 10, ODR100 }, - { 20, ODR50 }, - { 40, ODR25 }, - { 100, ODR10 }, - { 1000, ODR1 }, -}; - -struct lis3dh_acc_data { - struct i2c_client *client; - struct lis3dh_acc_platform_data *pdata; - - struct mutex lock; - struct delayed_work input_work; - - struct input_dev *input_dev; - - int hw_initialized; - /* hw_working=-1 means not tested yet */ - int hw_working; - atomic_t enabled; - int on_before_suspend; - - u8 sensitivity; - - u8 resume_state[RESUME_ENTRIES]; - - int irq1; - struct work_struct irq1_work; - struct workqueue_struct *irq1_work_queue; - int irq2; - struct work_struct irq2_work; - struct workqueue_struct *irq2_work_queue; -}; - -/* - * Because misc devices can not carry a pointer from driver register to - * open, we keep this global. This limits the driver to a single instance. - */ -struct lis3dh_acc_data *lis3dh_acc_misc_data; - -static int lis3dh_acc_i2c_read(struct lis3dh_acc_data *acc, u8 * buf, int len) -{ - int err; - int tries = 0; - - struct i2c_msg msgs[] = { - { - .addr = acc->client->addr, - .flags = acc->client->flags & I2C_M_TEN, - .len = 1, - .buf = buf, }, - { - .addr = acc->client->addr, - .flags = (acc->client->flags & I2C_M_TEN) | I2C_M_RD, - .len = len, - .buf = buf, }, - }; - - do { - err = i2c_transfer(acc->client->adapter, msgs, 2); - if (err != 2) - msleep_interruptible(I2C_RETRY_DELAY); - } while ((err != 2) && (++tries < I2C_RETRIES)); - - if (err != 2) { - dev_err(&acc->client->dev, "read transfer error\n"); - err = -EIO; - } else { - err = 0; - } - - return err; -} - -static int lis3dh_acc_i2c_write(struct lis3dh_acc_data *acc, u8 * buf, int len) -{ - int err; - int tries = 0; - - struct i2c_msg msgs[] = { { .addr = acc->client->addr, - .flags = acc->client->flags & I2C_M_TEN, - .len = len + 1, .buf = buf, }, }; - do { - err = i2c_transfer(acc->client->adapter, msgs, 1); - if (err != 1) - msleep_interruptible(I2C_RETRY_DELAY); - } while ((err != 1) && (++tries < I2C_RETRIES)); - - if (err != 1) { - dev_err(&acc->client->dev, "write transfer error\n"); - err = -EIO; - } else { - err = 0; - } - - return err; -} - -static int lis3dh_acc_hw_init(struct lis3dh_acc_data *acc) -{ - int err = -1; - u8 buf[7]; - - printk(KERN_INFO "%s: hw init start\n", LIS3DH_ACC_DEV_NAME); - - buf[0] = WHO_AM_I; - err = lis3dh_acc_i2c_read(acc, buf, 1); - if (err < 0) - goto error_firstread; - else - acc->hw_working = 1; - if (buf[0] != WHOAMI_LIS3DH_ACC) { - err = -1; /* choose the right coded error */ - goto error_unknown_device; - } - - buf[0] = CTRL_REG1; - buf[1] = acc->resume_state[RES_CTRL_REG1]; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - goto error1; - - buf[0] = TEMP_CFG_REG; - buf[1] = acc->resume_state[RES_TEMP_CFG_REG]; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - goto error1; - - buf[0] = FIFO_CTRL_REG; - buf[1] = acc->resume_state[RES_FIFO_CTRL_REG]; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - goto error1; - - buf[0] = (I2C_AUTO_INCREMENT | TT_THS); - buf[1] = acc->resume_state[RES_TT_THS]; - buf[2] = acc->resume_state[RES_TT_LIM]; - buf[3] = acc->resume_state[RES_TT_TLAT]; - buf[4] = acc->resume_state[RES_TT_TW]; - err = lis3dh_acc_i2c_write(acc, buf, 4); - if (err < 0) - goto error1; - buf[0] = TT_CFG; - buf[1] = acc->resume_state[RES_TT_CFG]; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - goto error1; - - buf[0] = (I2C_AUTO_INCREMENT | INT_THS1); - buf[1] = acc->resume_state[RES_INT_THS1]; - buf[2] = acc->resume_state[RES_INT_DUR1]; - err = lis3dh_acc_i2c_write(acc, buf, 2); - if (err < 0) - goto error1; - buf[0] = INT_CFG1; - buf[1] = acc->resume_state[RES_INT_CFG1]; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - goto error1; - - buf[0] = (I2C_AUTO_INCREMENT | INT_THS2); - buf[1] = acc->resume_state[RES_INT_THS2]; - buf[2] = acc->resume_state[RES_INT_DUR2]; - err = lis3dh_acc_i2c_write(acc, buf, 2); - if (err < 0) - goto error1; - buf[0] = INT_CFG2; - buf[1] = acc->resume_state[RES_INT_CFG2]; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - goto error1; - - buf[0] = (I2C_AUTO_INCREMENT | CTRL_REG2); - buf[1] = acc->resume_state[RES_CTRL_REG2]; - buf[2] = acc->resume_state[RES_CTRL_REG3]; - buf[3] = acc->resume_state[RES_CTRL_REG4]; - buf[4] = acc->resume_state[RES_CTRL_REG5]; - buf[5] = acc->resume_state[RES_CTRL_REG6]; - err = lis3dh_acc_i2c_write(acc, buf, 5); - if (err < 0) - goto error1; - - acc->hw_initialized = 1; - printk(KERN_INFO "%s: hw init done\n", LIS3DH_ACC_DEV_NAME); - return 0; - -error_firstread: - acc->hw_working = 0; - dev_warn(&acc->client->dev, "Error reading WHO_AM_I: is device " - "available/working?\n"); - goto error1; -error_unknown_device: - dev_err(&acc->client->dev, - "device unknown. Expected: 0x%x," - " Replies: 0x%x\n", WHOAMI_LIS3DH_ACC, buf[0]); -error1: - acc->hw_initialized = 0; - dev_err(&acc->client->dev, "hw init error 0x%x,0x%x: %d\n", buf[0], - buf[1], err); - return err; -} - -static void lis3dh_acc_device_power_off(struct lis3dh_acc_data *acc) -{ - int err; - u8 buf[2] = { CTRL_REG1, LIS3DH_ACC_PM_OFF }; - - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - dev_err(&acc->client->dev, "soft power off failed: %d\n", err); - - if (acc->pdata->power_off) { - disable_irq_nosync(acc->irq1); - disable_irq_nosync(acc->irq2); - acc->pdata->power_off(); - acc->hw_initialized = 0; - } - if (acc->hw_initialized) { - disable_irq_nosync(acc->irq1); - disable_irq_nosync(acc->irq2); - acc->hw_initialized = 0; - } - -} - -static int lis3dh_acc_device_power_on(struct lis3dh_acc_data *acc) -{ - int err = -1; - - if (acc->pdata->power_on) { - err = acc->pdata->power_on(); - if (err < 0) { - dev_err(&acc->client->dev, - "power_on failed: %d\n", err); - return err; - } - enable_irq(acc->irq1); - enable_irq(acc->irq2); - } - - if (!acc->hw_initialized) { - err = lis3dh_acc_hw_init(acc); - if (acc->hw_working == 1 && err < 0) { - lis3dh_acc_device_power_off(acc); - return err; - } - } - - if (acc->hw_initialized) { - enable_irq(acc->irq1); - enable_irq(acc->irq2); - printk(KERN_INFO "%s: power on: irq enabled\n", - LIS3DH_ACC_DEV_NAME); - } - return 0; -} - -static irqreturn_t lis3dh_acc_isr1(int irq, void *dev) -{ - struct lis3dh_acc_data *acc = dev; - - disable_irq_nosync(irq); - queue_work(acc->irq1_work_queue, &acc->irq1_work); - printk(KERN_INFO "%s: isr1 queued\n", LIS3DH_ACC_DEV_NAME); - - return IRQ_HANDLED; -} - -static irqreturn_t lis3dh_acc_isr2(int irq, void *dev) -{ - struct lis3dh_acc_data *acc = dev; - - disable_irq_nosync(irq); - queue_work(acc->irq2_work_queue, &acc->irq2_work); - printk(KERN_INFO "%s: isr2 queued\n", LIS3DH_ACC_DEV_NAME); - - return IRQ_HANDLED; -} - - - -static void lis3dh_acc_irq1_work_func(struct work_struct *work) -{ - - struct lis3dh_acc_data *acc = - container_of(work, struct lis3dh_acc_data, irq1_work); - /* TODO add interrupt service procedure. - ie:lis3dh_acc_get_int1_source(acc); */ - ; - /* */ - printk(KERN_INFO "%s: IRQ1 triggered\n", LIS3DH_ACC_DEV_NAME); -exit: - enable_irq(acc->irq1); -} - -static void lis3dh_acc_irq2_work_func(struct work_struct *work) -{ - - struct lis3dh_acc_data *acc = - container_of(work, struct lis3dh_acc_data, irq2_work); - /* TODO add interrupt service procedure. - ie:lis3dh_acc_get_tap_source(acc); */ - ; - /* */ - - printk(KERN_INFO "%s: IRQ2 triggered\n", LIS3DH_ACC_DEV_NAME); -exit: - enable_irq(acc->irq2); -} - -int lis3dh_acc_update_g_range(struct lis3dh_acc_data *acc, u8 new_g_range) -{ - int err; - - u8 sensitivity; - u8 buf[2]; - u8 updated_val; - u8 init_val; - u8 new_val; - u8 mask = LIS3DH_ACC_FS_MASK | HIGH_RESOLUTION; - - switch (new_g_range) { - case LIS3DH_ACC_G_2G: - - sensitivity = SENSITIVITY_2G; - break; - case LIS3DH_ACC_G_4G: - - sensitivity = SENSITIVITY_4G; - break; - case LIS3DH_ACC_G_8G: - - sensitivity = SENSITIVITY_8G; - break; - case LIS3DH_ACC_G_16G: - - sensitivity = SENSITIVITY_16G; - break; - default: - dev_err(&acc->client->dev, "invalid g range requested: %u\n", - new_g_range); - return -EINVAL; - } - - if (atomic_read(&acc->enabled)) { - /* Set configuration register 4, which contains g range setting - * NOTE: this is a straight overwrite because this driver does - * not use any of the other configuration bits in this - * register. Should this become untrue, we will have to read - * out the value and only change the relevant bits --XX---- - * (marked by X) */ - buf[0] = CTRL_REG4; - err = lis3dh_acc_i2c_read(acc, buf, 1); - if (err < 0) - goto error; - init_val = buf[0]; - acc->resume_state[RES_CTRL_REG4] = init_val; - new_val = new_g_range | HIGH_RESOLUTION; - updated_val = ((mask & new_val) | ((~mask) & init_val)); - buf[1] = updated_val; - buf[0] = CTRL_REG4; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - goto error; - acc->resume_state[RES_CTRL_REG4] = updated_val; - acc->sensitivity = sensitivity; - } - - - return 0; -error: - dev_err(&acc->client->dev, "update g range failed 0x%x,0x%x: %d\n", - buf[0], buf[1], err); - - return err; -} - -int lis3dh_acc_update_odr(struct lis3dh_acc_data *acc, int poll_interval_ms) -{ - int err = -1; - int i; - u8 config[2]; - - /* Convert the poll interval into an output data rate configuration - * that is as low as possible. The ordering of these checks must be - * maintained due to the cascading cut off values - poll intervals are - * checked from shortest to longest. At each check, if the next lower - * ODR cannot support the current poll interval, we stop searching */ - for (i = ARRAY_SIZE(lis3dh_acc_odr_table) - 1; i >= 0; i--) { - if (lis3dh_acc_odr_table[i].cutoff_ms <= poll_interval_ms) - break; - } - config[1] = lis3dh_acc_odr_table[i].mask; - - config[1] |= LIS3DH_ACC_ENABLE_ALL_AXES; - - /* If device is currently enabled, we need to write new - * configuration out to it */ - if (atomic_read(&acc->enabled)) { - config[0] = CTRL_REG1; - err = lis3dh_acc_i2c_write(acc, config, 1); - if (err < 0) - goto error; - acc->resume_state[RES_CTRL_REG1] = config[1]; - } - - return 0; - -error: - dev_err(&acc->client->dev, "update odr failed 0x%x,0x%x: %d\n", - config[0], config[1], err); - - return err; -} - -/* */ - -static int lis3dh_acc_register_write(struct lis3dh_acc_data *acc, u8 *buf, - u8 reg_address, u8 new_value) -{ - int err = -1; - - if (atomic_read(&acc->enabled)) { - /* Sets configuration register at reg_address - * NOTE: this is a straight overwrite */ - buf[0] = reg_address; - buf[1] = new_value; - err = lis3dh_acc_i2c_write(acc, buf, 1); - if (err < 0) - return err; - } - return err; -} - -static int lis3dh_acc_register_read(struct lis3dh_acc_data *acc, u8 *buf, - u8 reg_address) -{ - - int err = -1; - buf[0] = (reg_address); - err = lis3dh_acc_i2c_read(acc, buf, 1); - return err; -} - -static int lis3dh_acc_register_update(struct lis3dh_acc_data *acc, u8 *buf, - u8 reg_address, u8 mask, u8 new_bit_values) -{ - int err = -1; - u8 init_val; - u8 updated_val; - err = lis3dh_acc_register_read(acc, buf, reg_address); - if (!(err < 0)) { - init_val = buf[1]; - updated_val = ((mask & new_bit_values) | ((~mask) & init_val)); - err = lis3dh_acc_register_write(acc, buf, reg_address, - updated_val); - } - return err; -} - -/* */ - -static int lis3dh_acc_get_acceleration_data(struct lis3dh_acc_data *acc, - int *xyz) -{ - int err = -1; - /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ - u8 acc_data[6]; - /* x,y,z hardware data */ - s16 hw_d[3] = { 0 }; - - acc_data[0] = (I2C_AUTO_INCREMENT | AXISDATA_REG); - err = lis3dh_acc_i2c_read(acc, acc_data, 6); - if (err < 0) - return err; - - hw_d[0] = (((s16) ((acc_data[1] << 8) | acc_data[0])) >> 4); - hw_d[1] = (((s16) ((acc_data[3] << 8) | acc_data[2])) >> 4); - hw_d[2] = (((s16) ((acc_data[5] << 8) | acc_data[4])) >> 4); - - hw_d[0] = hw_d[0] * acc->sensitivity; - hw_d[1] = hw_d[1] * acc->sensitivity; - hw_d[2] = hw_d[2] * acc->sensitivity; - - - xyz[0] = ((acc->pdata->negate_x) ? (-hw_d[acc->pdata->axis_map_x]) - : (hw_d[acc->pdata->axis_map_x])); - xyz[1] = ((acc->pdata->negate_y) ? (-hw_d[acc->pdata->axis_map_y]) - : (hw_d[acc->pdata->axis_map_y])); - xyz[2] = ((acc->pdata->negate_z) ? (-hw_d[acc->pdata->axis_map_z]) - : (hw_d[acc->pdata->axis_map_z])); - - #ifdef DEBUG - /* - printk(KERN_INFO "%s read x=%d, y=%d, z=%d\n", - LIS3DH_ACC_DEV_NAME, xyz[0], xyz[1], xyz[2]); - */ - #endif - return err; -} - -static void lis3dh_acc_report_values(struct lis3dh_acc_data *acc, int *xyz) -{ - input_report_abs(acc->input_dev, ABS_X, xyz[0]); - input_report_abs(acc->input_dev, ABS_Y, xyz[1]); - input_report_abs(acc->input_dev, ABS_Z, xyz[2]); - input_sync(acc->input_dev); -} - -static int lis3dh_acc_enable(struct lis3dh_acc_data *acc) -{ - int err; - - if (!atomic_cmpxchg(&acc->enabled, 0, 1)) { - err = lis3dh_acc_device_power_on(acc); - if (err < 0) { - atomic_set(&acc->enabled, 0); - return err; - } - schedule_delayed_work(&acc->input_work, msecs_to_jiffies( - acc->pdata->poll_interval)); - } - - return 0; -} - -static int lis3dh_acc_disable(struct lis3dh_acc_data *acc) -{ - if (atomic_cmpxchg(&acc->enabled, 1, 0)) { - cancel_delayed_work_sync(&acc->input_work); - lis3dh_acc_device_power_off(acc); - } - - return 0; -} - -static int lis3dh_acc_misc_open(struct inode *inode, struct file *file) -{ - int err; - err = nonseekable_open(inode, file); - if (err < 0) - return err; - - file->private_data = lis3dh_acc_misc_data; - - return 0; -} - -static int lis3dh_acc_misc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - u8 buf[4]; - u8 mask; - u8 reg_address; - u8 bit_values; - int err; - int interval; - struct lis3dh_acc_data *acc = file->private_data; - - printk(KERN_INFO "%s: %s call with cmd 0x%x and arg 0x%x\n", - LIS3DH_ACC_DEV_NAME, __func__, cmd, (unsigned int)arg); - - switch (cmd) { - case LIS3DH_ACC_IOCTL_GET_DELAY: - interval = acc->pdata->poll_interval; - if (copy_to_user(argp, &interval, sizeof(interval))) - return -EFAULT; - break; - - case LIS3DH_ACC_IOCTL_SET_DELAY: - if (copy_from_user(&interval, argp, sizeof(interval))) - return -EFAULT; - if (interval < 0 || interval > 1000) - return -EINVAL; - - acc->pdata->poll_interval = max(interval, - acc->pdata->min_interval); - err = lis3dh_acc_update_odr(acc, acc->pdata->poll_interval); - /* TODO: if update fails poll is still set */ - if (err < 0) - return err; - break; - - case LIS3DH_ACC_IOCTL_SET_ENABLE: - if (copy_from_user(&interval, argp, sizeof(interval))) - return -EFAULT; - if (interval > 1) - return -EINVAL; - if (interval) - err = lis3dh_acc_enable(acc); - else - err = lis3dh_acc_disable(acc); - return err; - break; - - case LIS3DH_ACC_IOCTL_GET_ENABLE: - interval = atomic_read(&acc->enabled); - if (copy_to_user(argp, &interval, sizeof(interval))) - return -EINVAL; - break; - - case LIS3DH_ACC_IOCTL_SET_G_RANGE: - if (copy_from_user(buf, argp, 1)) - return -EFAULT; - bit_values = buf[0]; - err = lis3dh_acc_update_g_range(acc, bit_values); - if (err < 0) - return err; - break; - -#ifdef INTERRUPT_MANAGEMENT - case LIS3DH_ACC_IOCTL_SET_CTRL_REG3: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = CTRL_REG3; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_CTRL_REG3] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_CTRL_REG3])); - break; - - case LIS3DH_ACC_IOCTL_SET_CTRL_REG6: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = CTRL_REG6; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_CTRL_REG6] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_CTRL_REG6])); - break; - - case LIS3DH_ACC_IOCTL_SET_DURATION1: - if (copy_from_user(buf, argp, 1)) - return -EFAULT; - reg_address = INT_DUR1; - mask = 0x7F; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_INT_DUR1] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_INT_DUR1])); - break; - - case LIS3DH_ACC_IOCTL_SET_THRESHOLD1: - if (copy_from_user(buf, argp, 1)) - return -EFAULT; - reg_address = INT_THS1; - mask = 0x7F; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_INT_THS1] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_INT_THS1])); - break; - - case LIS3DH_ACC_IOCTL_SET_CONFIG1: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = INT_CFG1; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_INT_CFG1] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_INT_CFG1])); - break; - - case LIS3DH_ACC_IOCTL_GET_SOURCE1: - err = lis3dh_acc_register_read(acc, buf, INT_SRC1); - if (err < 0) - return err; -#if DEBUG - printk(KERN_ALERT "INT1_SRC content: %d , 0x%x\n", - buf[0], buf[0]); -#endif - if (copy_to_user(argp, buf, 1)) - return -EINVAL; - break; - - case LIS3DH_ACC_IOCTL_SET_DURATION2: - if (copy_from_user(buf, argp, 1)) - return -EFAULT; - reg_address = INT_DUR2; - mask = 0x7F; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_INT_DUR2] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_INT_DUR2])); - break; - - case LIS3DH_ACC_IOCTL_SET_THRESHOLD2: - if (copy_from_user(buf, argp, 1)) - return -EFAULT; - reg_address = INT_THS2; - mask = 0x7F; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_INT_THS2] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_INT_THS2])); - break; - - case LIS3DH_ACC_IOCTL_SET_CONFIG2: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = INT_CFG2; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_INT_CFG2] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_INT_CFG2])); - break; - - case LIS3DH_ACC_IOCTL_GET_SOURCE2: - err = lis3dh_acc_register_read(acc, buf, INT_SRC2); - if (err < 0) - return err; -#if DEBUG - printk(KERN_ALERT "INT2_SRC content: %d , 0x%x\n", - buf[0], buf[0]); -#endif - if (copy_to_user(argp, buf, 1)) - return -EINVAL; - break; - - case LIS3DH_ACC_IOCTL_GET_TAP_SOURCE: - err = lis3dh_acc_register_read(acc, buf, TT_SRC); - if (err < 0) - return err; -#if DEBUG - printk(KERN_ALERT "TT_SRC content: %d , 0x%x\n", - buf[0], buf[0]); -#endif - if (copy_to_user(argp, buf, 1)) { - printk(KERN_ERR "%s: %s error in copy_to_user \n", - LIS3DH_ACC_DEV_NAME, __func__); - return -EINVAL; - } - break; - - case LIS3DH_ACC_IOCTL_SET_TAP_CFG: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = TT_CFG; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_TT_CFG] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_TT_CFG])); - break; - - case LIS3DH_ACC_IOCTL_SET_TAP_TLIM: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = TT_LIM; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_TT_LIM] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_TT_LIM])); - break; - - case LIS3DH_ACC_IOCTL_SET_TAP_THS: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = TT_THS; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_TT_THS] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_TT_THS])); - break; - - case LIS3DH_ACC_IOCTL_SET_TAP_TLAT: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = TT_TLAT; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_TT_TLAT] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_TT_TLAT])); - break; - - case LIS3DH_ACC_IOCTL_SET_TAP_TW: - if (copy_from_user(buf, argp, 2)) - return -EFAULT; - reg_address = TT_TW; - mask = buf[1]; - bit_values = buf[0]; - err = lis3dh_acc_register_update(acc, (u8 *) arg, reg_address, - mask, bit_values); - if (err < 0) - return err; - acc->resume_state[RES_TT_TW] = ((mask & bit_values) | - ( ~mask & acc->resume_state[RES_TT_TW])); - break; - -#endif /* INTERRUPT_MANAGEMENT */ - - default: - return -EINVAL; - } - - return 0; -} - -static const struct file_operations lis3dh_acc_misc_fops = { - .owner = THIS_MODULE, - .open = lis3dh_acc_misc_open, - .ioctl = lis3dh_acc_misc_ioctl, -}; - -static struct miscdevice lis3dh_acc_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = LIS3DH_ACC_DEV_NAME, - .fops = &lis3dh_acc_misc_fops, -}; - -static void lis3dh_acc_input_work_func(struct work_struct *work) -{ - struct lis3dh_acc_data *acc; - - int xyz[3] = { 0 }; - int err; - - acc = container_of((struct delayed_work *)work, - struct lis3dh_acc_data, input_work); - - mutex_lock(&acc->lock); - err = lis3dh_acc_get_acceleration_data(acc, xyz); - if (err < 0) - dev_err(&acc->client->dev, "get_acceleration_data failed\n"); - else - lis3dh_acc_report_values(acc, xyz); - - schedule_delayed_work(&acc->input_work, msecs_to_jiffies( - acc->pdata->poll_interval)); - mutex_unlock(&acc->lock); -} - -#ifdef LIS3DH_OPEN_ENABLE -int lis3dh_acc_input_open(struct input_dev *input) -{ - struct lis3dh_acc_data *acc = input_get_drvdata(input); - - return lis3dh_acc_enable(acc); -} - -void lis3dh_acc_input_close(struct input_dev *dev) -{ - struct lis3dh_acc_data *acc = input_get_drvdata(dev); - - lis3dh_acc_disable(acc); -} -#endif - -static int lis3dh_acc_validate_pdata(struct lis3dh_acc_data *acc) -{ - acc->pdata->poll_interval = max(acc->pdata->poll_interval, - acc->pdata->min_interval); - - if (acc->pdata->axis_map_x > 2 || acc->pdata->axis_map_y > 2 - || acc->pdata->axis_map_z > 2) { - dev_err(&acc->client->dev, "invalid axis_map value " - "x:%u y:%u z%u\n", acc->pdata->axis_map_x, - acc->pdata->axis_map_y, acc->pdata->axis_map_z); - return -EINVAL; - } - - /* Only allow 0 and 1 for negation boolean flag */ - if (acc->pdata->negate_x > 1 || acc->pdata->negate_y > 1 - || acc->pdata->negate_z > 1) { - dev_err(&acc->client->dev, "invalid negate value " - "x:%u y:%u z:%u\n", acc->pdata->negate_x, - acc->pdata->negate_y, acc->pdata->negate_z); - return -EINVAL; - } - - /* Enforce minimum polling interval */ - if (acc->pdata->poll_interval < acc->pdata->min_interval) { - dev_err(&acc->client->dev, "minimum poll interval violated\n"); - return -EINVAL; - } - - return 0; -} - -static int lis3dh_acc_input_init(struct lis3dh_acc_data *acc) -{ - int err; - - INIT_DELAYED_WORK(&acc->input_work, lis3dh_acc_input_work_func); - acc->input_dev = input_allocate_device(); - if (!acc->input_dev) { - err = -ENOMEM; - dev_err(&acc->client->dev, "input device allocate failed\n"); - goto err0; - } - -#ifdef LIS3DH_ACC_OPEN_ENABLE - acc->input_dev->open = lis3dh_acc_input_open; - acc->input_dev->close = lis3dh_acc_input_close; -#endif - - input_set_drvdata(acc->input_dev, acc); - - set_bit(EV_ABS, acc->input_dev->evbit); - /* next is used for interruptA sources data if the case */ - set_bit(ABS_MISC, acc->input_dev->absbit); - /* next is used for interruptB sources data if the case */ - set_bit(ABS_WHEEL, acc->input_dev->absbit); - - input_set_abs_params(acc->input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT); - input_set_abs_params(acc->input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT); - input_set_abs_params(acc->input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT); - /* next is used for interruptA sources data if the case */ - input_set_abs_params(acc->input_dev, ABS_MISC, INT_MIN, INT_MAX, 0, 0); - /* next is used for interruptB sources data if the case */ - input_set_abs_params(acc->input_dev, ABS_WHEEL, INT_MIN, INT_MAX, 0, 0); - - acc->input_dev->name = "accelerometer"; - - err = input_register_device(acc->input_dev); - if (err) { - dev_err(&acc->client->dev, - "unable to register input polled device %s\n", - acc->input_dev->name); - goto err1; - } - - return 0; - -err1: - input_free_device(acc->input_dev); -err0: - return err; -} - -static void lis3dh_acc_input_cleanup(struct lis3dh_acc_data *acc) -{ - input_unregister_device(acc->input_dev); - input_free_device(acc->input_dev); -} - -static int lis3dh_acc_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - - struct lis3dh_acc_data *acc; - - int err = -1; - int tempvalue; - - pr_info("%s: probe start.\n", LIS3DH_ACC_DEV_NAME); - - if (client->dev.platform_data == NULL) { - dev_err(&client->dev, "platform data is NULL. exiting.\n"); - err = -ENODEV; - goto exit_check_functionality_failed; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "client not i2c capable\n"); - err = -ENODEV; - goto exit_check_functionality_failed; - } - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) { - dev_err(&client->dev, "client not smb-i2c capable:2\n"); - err = -EIO; - goto exit_check_functionality_failed; - } - - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_I2C_BLOCK)){ - dev_err(&client->dev, "client not smb-i2c capable:3\n"); - err = -EIO; - goto exit_check_functionality_failed; - } - /* - * OK. From now, we presume we have a valid client. We now create the - * client structure, even though we cannot fill it completely yet. - */ - - acc = kzalloc(sizeof(struct lis3dh_acc_data), GFP_KERNEL); - if (acc == NULL) { - err = -ENOMEM; - dev_err(&client->dev, - "failed to allocate memory for module data: " - "%d\n", err); - goto exit_alloc_data_failed; - } - - mutex_init(&acc->lock); - mutex_lock(&acc->lock); - - acc->client = client; - i2c_set_clientdata(client, acc); - - - INIT_WORK(&acc->irq1_work, lis3dh_acc_irq1_work_func); - acc->irq1_work_queue = create_singlethread_workqueue("lis3dh_acc_wq1"); - if (!acc->irq1_work_queue) { - err = -ENOMEM; - dev_err(&client->dev, "cannot create work queue1: %d\n", err); - goto err_mutexunlockfreedata; - } - - INIT_WORK(&acc->irq2_work, lis3dh_acc_irq2_work_func); - acc->irq2_work_queue = create_singlethread_workqueue("lis3dh_acc_wq2"); - if (!acc->irq2_work_queue) { - err = -ENOMEM; - dev_err(&client->dev, "cannot create work queue2: %d\n", err); - goto err_destoyworkqueue1; - } - - - - if (i2c_smbus_read_byte(client) < 0) { - printk(KERN_ERR "i2c_smbus_read_byte error!!\n"); - goto err_destoyworkqueue2; - } else { - printk(KERN_INFO "%s Device detected!\n", LIS3DH_ACC_DEV_NAME); - } - - /* read chip id */ - - tempvalue = i2c_smbus_read_word_data(client, WHO_AM_I); - if ((tempvalue & 0x00FF) == WHOAMI_LIS3DH_ACC) { - printk(KERN_INFO "%s I2C driver registered!\n", - LIS3DH_ACC_DEV_NAME); - } else { - acc->client = NULL; - printk(KERN_INFO "I2C driver not registered!" - " Device unknown\n"); - goto err_destoyworkqueue2; - } - - acc->pdata = kmalloc(sizeof(*acc->pdata), GFP_KERNEL); - if (acc->pdata == NULL) { - err = -ENOMEM; - dev_err(&client->dev, - "failed to allocate memory for pdata: %d\n", - err); - goto err_destoyworkqueue2; - } - - memcpy(acc->pdata, client->dev.platform_data, sizeof(*acc->pdata)); - - err = lis3dh_acc_validate_pdata(acc); - if (err < 0) { - dev_err(&client->dev, "failed to validate platform data\n"); - goto exit_kfree_pdata; - } - - i2c_set_clientdata(client, acc); - - - if (acc->pdata->init) { - err = acc->pdata->init(); - if (err < 0) { - dev_err(&client->dev, "init failed: %d\n", err); - goto err2; - } - } - - memset(acc->resume_state, 0, ARRAY_SIZE(acc->resume_state)); - - acc->irq1 = gpio_to_irq(acc->pdata->gpio_int1); - printk(KERN_INFO "%s: %s has set irq1 to irq: %d mapped on gpio:%d\n", - LIS3DH_ACC_DEV_NAME, __func__, acc->irq1, - acc->pdata->gpio_int1); - acc->irq2 = gpio_to_irq(acc->pdata->gpio_int2); - printk(KERN_INFO "%s: %s has set irq2 to irq: %d mapped on gpio:%d\n", - LIS3DH_ACC_DEV_NAME, __func__, acc->irq2, - acc->pdata->gpio_int2); - - - - - acc->resume_state[RES_CTRL_REG1] = LIS3DH_ACC_ENABLE_ALL_AXES; - acc->resume_state[RES_CTRL_REG2] = 0x00; - acc->resume_state[RES_CTRL_REG3] = 0x00; - acc->resume_state[RES_CTRL_REG4] = 0x00; - acc->resume_state[RES_CTRL_REG5] = 0x00; - acc->resume_state[RES_CTRL_REG6] = 0x00; - - acc->resume_state[RES_TEMP_CFG_REG] = 0x00; - acc->resume_state[RES_FIFO_CTRL_REG] = 0x00; - acc->resume_state[RES_INT_CFG1] = 0x00; - acc->resume_state[RES_INT_THS1] = 0x00; - acc->resume_state[RES_INT_DUR1] = 0x00; - acc->resume_state[RES_INT_CFG2] = 0x00; - acc->resume_state[RES_INT_THS2] = 0x00; - acc->resume_state[RES_INT_DUR2] = 0x00; - - acc->resume_state[RES_TT_CFG] = 0x00; - acc->resume_state[RES_TT_THS] = 0x00; - acc->resume_state[RES_TT_LIM] = 0x00; - acc->resume_state[RES_TT_TLAT] = 0x00; - acc->resume_state[RES_TT_TW] = 0x00; - - err = lis3dh_acc_device_power_on(acc); - if (err < 0) { - dev_err(&client->dev, "power on failed: %d\n", err); - goto err2; - } - - atomic_set(&acc->enabled, 1); - - err = lis3dh_acc_update_g_range(acc, acc->pdata->g_range); - if (err < 0) { - dev_err(&client->dev, "update_g_range failed\n"); - goto err_power_off; - } - - err = lis3dh_acc_update_odr(acc, acc->pdata->poll_interval); - if (err < 0) { - dev_err(&client->dev, "update_odr failed\n"); - goto err_power_off; - } - - err = lis3dh_acc_input_init(acc); - if (err < 0) { - dev_err(&client->dev, "input init failed\n"); - goto err_power_off; - } - lis3dh_acc_misc_data = acc; - - err = misc_register(&lis3dh_acc_misc_device); - if (err < 0) { - dev_err(&client->dev, - "misc LIS3DH_ACC_DEV_NAME register failed\n"); - goto err_input_cleanup; - } - - lis3dh_acc_device_power_off(acc); - - /* As default, do not report information */ - atomic_set(&acc->enabled, 0); - - err = request_irq(acc->irq1, lis3dh_acc_isr1, IRQF_TRIGGER_RISING, - "lis3dh_acc_irq1", acc); - if (err < 0) { - dev_err(&client->dev, "request irq1 failed: %d\n", err); - goto err_misc_dereg; - } - disable_irq_nosync(acc->irq1); - - err = request_irq(acc->irq2, lis3dh_acc_isr2, IRQF_TRIGGER_RISING, - "lis3dh_acc_irq2", acc); - if (err < 0) { - dev_err(&client->dev, "request irq2 failed: %d\n", err); - goto err_free_irq1; - } - disable_irq_nosync(acc->irq2); - - mutex_unlock(&acc->lock); - - dev_info(&client->dev, "%s: probed\n", LIS3DH_ACC_DEV_NAME); - - return 0; - -err_free_irq1: - free_irq(acc->irq1, acc); -err_misc_dereg: - misc_deregister(&lis3dh_acc_misc_device); -err_input_cleanup: - lis3dh_acc_input_cleanup(acc); -err_power_off: - lis3dh_acc_device_power_off(acc); -err2: - if (acc->pdata->exit) - acc->pdata->exit(); -exit_kfree_pdata: - kfree(acc->pdata); -err_destoyworkqueue2: - destroy_workqueue(acc->irq2_work_queue); -err_destoyworkqueue1: - destroy_workqueue(acc->irq1_work_queue); -err_mutexunlockfreedata: - mutex_unlock(&acc->lock); - kfree(acc); -exit_alloc_data_failed: -exit_check_functionality_failed: - printk(KERN_ERR "%s: Driver Init failed\n", LIS3DH_ACC_DEV_NAME); - return err; -} - -static int __devexit lis3dh_acc_remove(struct i2c_client *client) -{ - /* TODO: revisit ordering here once _probe order is finalized */ - struct lis3dh_acc_data *acc = i2c_get_clientdata(client); - - free_irq(acc->irq1, acc); - free_irq(acc->irq2, acc); - gpio_free(acc->pdata->gpio_int1); - gpio_free(acc->pdata->gpio_int2); - destroy_workqueue(acc->irq1_work_queue); - destroy_workqueue(acc->irq2_work_queue); - - misc_deregister(&lis3dh_acc_misc_device); - lis3dh_acc_input_cleanup(acc); - lis3dh_acc_device_power_off(acc); - if (acc->pdata->exit) - acc->pdata->exit(); - kfree(acc->pdata); - kfree(acc); - - return 0; -} - -static int lis3dh_acc_resume(struct i2c_client *client) -{ - struct lis3dh_acc_data *acc = i2c_get_clientdata(client); - - if (acc->on_before_suspend) - return lis3dh_acc_enable(acc); - return 0; -} - -static int lis3dh_acc_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct lis3dh_acc_data *acc = i2c_get_clientdata(client); - - acc->on_before_suspend = atomic_read(&acc->enabled); - return lis3dh_acc_disable(acc); -} - -static const struct i2c_device_id lis3dh_acc_id[] - = { { LIS3DH_ACC_DEV_NAME, 0 }, { }, }; - -MODULE_DEVICE_TABLE(i2c, lis3dh_acc_id); - -static struct i2c_driver lis3dh_acc_driver = { - .driver = { - .name = LIS3DH_ACC_DEV_NAME, - }, - .probe = lis3dh_acc_probe, - .remove = __devexit_p(lis3dh_acc_remove), - .resume = lis3dh_acc_resume, - .suspend = lis3dh_acc_suspend, - .id_table = lis3dh_acc_id, -}; - -static int __init lis3dh_acc_init(void) -{ - printk(KERN_INFO "%s accelerometer driver: init\n", - LIS3DH_ACC_DEV_NAME); - return i2c_add_driver(&lis3dh_acc_driver); -} - -static void __exit lis3dh_acc_exit(void) -{ - #if DEBUG - printk(KERN_INFO "%s accelerometer driver exit\n", LIS3DH_ACC_DEV_NAME); - #endif - i2c_del_driver(&lis3dh_acc_driver); - return; -} - -module_init(lis3dh_acc_init); -module_exit(lis3dh_acc_exit); - -MODULE_DESCRIPTION("lis3dh accelerometer misc driver"); -MODULE_AUTHOR("STMicroelectronics"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/input/gsensor/lis3dh_acc_misc.h b/drivers/input/gsensor/lis3dh_acc_misc.h deleted file mode 100755 index 17b3c0fc225c..000000000000 --- a/drivers/input/gsensor/lis3dh_acc_misc.h +++ /dev/null @@ -1,137 +0,0 @@ - -/******************** (C) COPYRIGHT 2010 STMicroelectronics ******************** -* -* File Name : lis3dh_misc.h -* Authors : MH - C&I BU - Application Team -* : Carmine Iascone (carmine.iascone@st.com) -* : Matteo Dameno (matteo.dameno@st.com) -* Version : V 1.0.5 -* Date : 26/08/2010 -* -******************************************************************************** -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -* THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES -* OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE -* PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -* -* THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS. -* -*******************************************************************************/ -/******************************************************************************* -Version History. - -Revision 1-0-0 05/11/2009 -First Release -Revision 1-0-1 26/01/2010 -Linux K&R Compliant Release -Revision 1-0-5 16/08/2010 -Interrupt Management - -*******************************************************************************/ - -#ifndef __LIS3DH_H__ -#define __LIS3DH_H__ - -#include /* For IOCTL macros */ -#include - -#define SAD0L 0x00 -#define SAD0H 0x01 -#define LIS3DH_ACC_I2C_SADROOT 0x0C -#define LIS3DH_ACC_I2C_SAD_L ((LIS3DH_ACC_I2C_SADROOT<<1)|SAD0L) -#define LIS3DH_ACC_I2C_SAD_H ((LIS3DH_ACC_I2C_SADROOT<<1)|SAD0H) -#define LIS3DH_ACC_DEV_NAME "lis3dh_acc_misc" - - -#define LIS3DH_ACC_IOCTL_BASE 77 -/** The following define the IOCTL command values via the ioctl macros */ -#define LIS3DH_ACC_IOCTL_SET_DELAY _IOW(LIS3DH_ACC_IOCTL_BASE, 0, int) -#define LIS3DH_ACC_IOCTL_GET_DELAY _IOR(LIS3DH_ACC_IOCTL_BASE, 1, int) -#define LIS3DH_ACC_IOCTL_SET_ENABLE _IOW(LIS3DH_ACC_IOCTL_BASE, 2, int) -#define LIS3DH_ACC_IOCTL_GET_ENABLE _IOR(LIS3DH_ACC_IOCTL_BASE, 3, int) -#define LIS3DH_ACC_IOCTL_SET_FULLSCALE _IOW(LIS3DH_ACC_IOCTL_BASE, 4, int) -#define LIS3DH_ACC_IOCTL_SET_G_RANGE LIS3DH_ACC_IOCTL_SET_FULLSCALE - -#define LIS3DH_ACC_IOCTL_SET_CTRL_REG3 _IOW(LIS3DH_ACC_IOCTL_BASE, 6, int) -#define LIS3DH_ACC_IOCTL_SET_CTRL_REG6 _IOW(LIS3DH_ACC_IOCTL_BASE, 7, int) -#define LIS3DH_ACC_IOCTL_SET_DURATION1 _IOW(LIS3DH_ACC_IOCTL_BASE, 8, int) -#define LIS3DH_ACC_IOCTL_SET_THRESHOLD1 _IOW(LIS3DH_ACC_IOCTL_BASE, 9, int) -#define LIS3DH_ACC_IOCTL_SET_CONFIG1 _IOW(LIS3DH_ACC_IOCTL_BASE, 10, int) - -#define LIS3DH_ACC_IOCTL_SET_DURATION2 _IOW(LIS3DH_ACC_IOCTL_BASE, 11, int) -#define LIS3DH_ACC_IOCTL_SET_THRESHOLD2 _IOW(LIS3DH_ACC_IOCTL_BASE, 12, int) -#define LIS3DH_ACC_IOCTL_SET_CONFIG2 _IOW(LIS3DH_ACC_IOCTL_BASE, 13, int) - -#define LIS3DH_ACC_IOCTL_GET_SOURCE1 _IOW(LIS3DH_ACC_IOCTL_BASE, 14, int) -#define LIS3DH_ACC_IOCTL_GET_SOURCE2 _IOW(LIS3DH_ACC_IOCTL_BASE, 15, int) - -#define LIS3DH_ACC_IOCTL_GET_TAP_SOURCE _IOW(LIS3DH_ACC_IOCTL_BASE, 16, int) - -#define LIS3DH_ACC_IOCTL_SET_TAP_TW _IOW(LIS3DH_ACC_IOCTL_BASE, 17, int) -#define LIS3DH_ACC_IOCTL_SET_TAP_CFG _IOW(LIS3DH_ACC_IOCTL_BASE, 18, int) -#define LIS3DH_ACC_IOCTL_SET_TAP_TLIM _IOW(LIS3DH_ACC_IOCTL_BASE, 19, int) -#define LIS3DH_ACC_IOCTL_SET_TAP_THS _IOW(LIS3DH_ACC_IOCTL_BASE, 20, int) -#define LIS3DH_ACC_IOCTL_SET_TAP_TLAT _IOW(LIS3DH_ACC_IOCTL_BASE, 21, int) - - - - -/************************************************/ -/* Accelerometer defines section */ -/************************************************/ - -/* Accelerometer Sensor Full Scale */ -#define LIS3DH_ACC_FS_MASK 0x30 -#define LIS3DH_ACC_G_2G 0x00 -#define LIS3DH_ACC_G_4G 0x10 -#define LIS3DH_ACC_G_8G 0x20 -#define LIS3DH_ACC_G_16G 0x30 - - -/* Accelerometer Sensor Operating Mode */ -#define LIS3DH_ACC_ENABLE 0x01 -#define LIS3DH_ACC_DISABLE 0x00 - - - - - - -#ifdef __KERNEL__ -struct lis3dh_acc_platform_data { - int poll_interval; - int min_interval; - - u8 g_range; - - u8 axis_map_x; - u8 axis_map_y; - u8 axis_map_z; - - u8 negate_x; - u8 negate_y; - u8 negate_z; - - int (*init)(void); - void (*exit)(void); - int (*power_on)(void); - int (*power_off)(void); - - int gpio_int1; - int gpio_int2; - -}; -#endif /* __KERNEL__ */ - -#endif /* __LIS3DH_H__ */ - - - diff --git a/drivers/input/gsensor/mma7660.c b/drivers/input/gsensor/mma7660.c deleted file mode 100644 index bf6c734802bd..000000000000 --- a/drivers/input/gsensor/mma7660.c +++ /dev/null @@ -1,639 +0,0 @@ -/* drivers/i2c/chips/mma7660.c - mma7660 compass driver - * - * Copyright (C) 2007-2008 HTC Corporation. - * Author: Hou-Kun Chen - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_ANDROID_POWER -#include -#endif - -//#define RK28_PRINT -//#include -#if 0 -#define rk28printk(x...) printk(x) -#else -#define rk28printk(x...) -#endif -static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id *id); - -#define MMA7660_SPEED 200 * 1000 - -/* Addresses to scan -- protected by sense_data_mutex */ -//static char sense_data[RBUFF_SIZE + 1]; -static struct i2c_client *this_client; -static struct miscdevice mma7660_device; - -static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq); - -#ifdef CONFIG_ANDROID_POWER -static android_early_suspend_t mma7660_early_suspend; -#endif -static int revision = -1; -/* AKM HW info */ -static ssize_t gsensor_vendor_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - - sprintf(buf, "%#x\n", revision); - ret = strlen(buf) + 1; - - return ret; -} - -static DEVICE_ATTR(vendor, 0444, gsensor_vendor_show, NULL); - -static struct kobject *android_gsensor_kobj; - -static int gsensor_sysfs_init(void) -{ - int ret ; - - android_gsensor_kobj = kobject_create_and_add("android_gsensor", NULL); - if (android_gsensor_kobj == NULL) { - rk28printk(KERN_ERR - "MMA7660 gsensor_sysfs_init:"\ - "subsystem_register failed\n"); - ret = -ENOMEM; - goto err; - } - - ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr); - if (ret) { - rk28printk(KERN_ERR - "MMA7660 gsensor_sysfs_init:"\ - "sysfs_create_group failed\n"); - goto err4; - } - - return 0 ; -err4: - kobject_del(android_gsensor_kobj); -err: - return ret ; -} - -static int mma7660_rx_data(struct i2c_client *client, char *rxData, int length) -{ - int ret = 0; - char reg = rxData[0]; - ret = i2c_master_reg8_recv(client, reg, rxData, length, MMA7660_SPEED); - return (ret > 0)? 0 : ret; -} - -static int mma7660_tx_data(struct i2c_client *client, char *txData, int length) -{ - int ret = 0; - char reg = txData[0]; - ret = i2c_master_reg8_send(client, reg, &txData[1], length-1, MMA7660_SPEED); - return (ret > 0)? 0 : ret; -} - -static int mma7660_set_rate(struct i2c_client *client, char rate) -{ - char buffer[2]; - int ret = 0; - - if (rate > 128) - return -EINVAL; - rk28printk("[ZWP]%s,rate = %d\n",__FUNCTION__,rate); - //因为增加了滤波功能,即每RawDataLength次才上报一次,所以提升gsensor两个档级 - if(rate > 2) - rate -= 2; - rk28printk("[ZWP]%s,new rate = %d\n",__FUNCTION__,rate); - -/* - for (i = 0; i < 7; i++) { - if (rate & (0x1 << i)) - break; - } - - - buffer[0] = MMA7660_REG_SR; - buffer[1] = 0xf8 | (0x07 & (~i)); -*/ - buffer[0] = MMA7660_REG_SR; - buffer[1] = 0xf8 | (0x07 & rate); - - ret = mma7660_tx_data(client, &(buffer[0]), 2); - ret = mma7660_rx_data(client, &(buffer[0]), 1); - - return ret; -} - -static int mma7660_start_dev(struct i2c_client *client, char rate) -{ - char buffer[MMA7660_REG_LEN]; - int ret = 0; - - buffer[0] = MMA7660_REG_INTSU; - buffer[1] = 0x10; //0x10; modify by zhao - ret = mma7660_tx_data(client, &buffer[0], 2); - ret = mma7660_rx_data(client, &buffer[0], 1); - - ret = mma7660_set_rate(client, rate); - - buffer[0] = MMA7660_REG_MODE; - buffer[1] = 0x01; - ret = mma7660_tx_data(client, &buffer[0], 2); - ret = mma7660_rx_data(client, &buffer[0], 1); - - enable_irq(client->irq); - rk28printk("\n----------------------------mma7660_start------------------------\n"); - - return ret; -} - -static int mma7660_start(struct i2c_client *client, char rate) -{ - struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); - - if (mma7660->status == MMA7660_OPEN) { - return 0; - } - mma7660->status = MMA7660_OPEN; - return mma7660_start_dev(client, rate); -} - -static int mma7660_close_dev(struct i2c_client *client) -{ - char buffer[2]; - - disable_irq_nosync(client->irq); - - buffer[0] = MMA7660_REG_MODE; - buffer[1] = 0x00; - - return mma7660_tx_data(client, buffer, 2); -} - -static int mma7660_close(struct i2c_client *client) -{ - struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); - - mma7660->status = MMA7660_CLOSE; - - return mma7660_close_dev(client); -} - -static int mma7660_reset_rate(struct i2c_client *client, char rate) -{ - int ret = 0; - - rk28printk("\n----------------------------mma7660_reset_rate------------------------\n"); - - ret = mma7660_close_dev(client); - ret = mma7660_start_dev(client, rate); - - return ret ; -} - -static inline int mma7660_convert_to_int(char value) -{ - int result; - - if (value < MMA7660_BOUNDARY) { - result = value * MMA7660_GRAVITY_STEP; - } else { - result = ~(((~value & 0x3f) + 1)* MMA7660_GRAVITY_STEP) + 1; - } - - return result; -} - -static void mma7660_report_value(struct i2c_client *client, struct mma7660_axis *axis) -{ - struct mma7660_data *mma7660 = i2c_get_clientdata(client); - //struct mma7660_axis *axis = (struct mma7660_axis *)rbuf; - - /* Report acceleration sensor information */ - input_report_abs(mma7660->input_dev, ABS_X, axis->x); - input_report_abs(mma7660->input_dev, ABS_Y, axis->y); - input_report_abs(mma7660->input_dev, ABS_Z, axis->z); - input_sync(mma7660->input_dev); - rk28printk("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z); -} - -#define RawDataLength 4 -int RawDataNum; -int Xaverage, Yaverage, Zaverage; - -static int mma7660_get_data(struct i2c_client *client) -{ - char buffer[3]; - int ret; - struct mma7660_axis axis; - //struct rk2818_gs_platform_data *pdata = client->dev.platform_data; - do { - memset(buffer, 0, 3); - buffer[0] = MMA7660_REG_X_OUT; - ret = mma7660_rx_data(client, &buffer[0], 3); - if (ret < 0) - return ret; - } while ((buffer[0] & 0x40) || (buffer[1] & 0x40) || (buffer[2] & 0x40)); - - axis.x = mma7660_convert_to_int(buffer[MMA7660_REG_X_OUT]); - axis.y = -mma7660_convert_to_int(buffer[MMA7660_REG_Y_OUT]); - axis.z = -mma7660_convert_to_int(buffer[MMA7660_REG_Z_OUT]); -/* - if(pdata->swap_xy) - { - axis.y = -axis.y; - swap(axis.x,axis.y); - } -*/ - //计算RawDataLength次值的平均值 - Xaverage += axis.x; - Yaverage += axis.y; - Zaverage += axis.z; - rk28printk( "%s: ------------------mma7660_GetData axis = %d %d %d,average=%d %d %d--------------\n", - __func__, axis.x, axis.y, axis.z,Xaverage,Yaverage,Zaverage); - - if((++RawDataNum)>=RawDataLength){ - RawDataNum = 0; - axis.x = Xaverage/RawDataLength; - axis.y = Yaverage/RawDataLength; - axis.z = Zaverage/RawDataLength; - mma7660_report_value(client, &axis); - Xaverage = Yaverage = Zaverage = 0; - } -#if 0 - // rk28printk( "%s: ------------------mma7660_GetData axis = %d %d %d--------------\n", - // __func__, axis.x, axis.y, axis.z); - - //memcpy(sense_data, &axis, sizeof(axis)); - mma7660_report_value(client, &axis); - //atomic_set(&data_ready, 0); - //wake_up(&data_ready_wq); -#endif - return 0; -} - -/* -static int mma7660_trans_buff(char *rbuf, int size) -{ - //wait_event_interruptible_timeout(data_ready_wq, - // atomic_read(&data_ready), 1000); - wait_event_interruptible(data_ready_wq, - atomic_read(&data_ready)); - - atomic_set(&data_ready, 0); - memcpy(rbuf, &sense_data[0], size); - - return 0; -} -*/ - -static int mma7660_open(struct inode *inode, struct file *file) -{ - return 0;//nonseekable_open(inode, file); -} - -static int mma7660_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static long mma7660_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - - void __user *argp = (void __user *)arg; - char msg[RBUFF_SIZE + 1]; - int ret = -1; - char rate; - struct i2c_client *client = container_of(mma7660_device.parent, struct i2c_client, dev); - - switch (cmd) { - case ECS_IOCTL_APP_SET_RATE: - if (copy_from_user(&rate, argp, sizeof(rate))) - return -EFAULT; - break; - default: - break; - } - - switch (cmd) { - case ECS_IOCTL_START: - ret = mma7660_start(client, MMA7660_RATE_32); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_CLOSE: - ret = mma7660_close(client); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_APP_SET_RATE: - ret = mma7660_reset_rate(client, rate); - if (ret < 0) - return ret; - break; - /* - case ECS_IOCTL_GETDATA: - ret = mma7660_trans_buff(msg, RBUFF_SIZE); - if (ret < 0) - return ret; - break; - */ - default: - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_GETDATA: - if (copy_to_user(argp, &msg, sizeof(msg))) - return -EFAULT; - break; - default: - break; - } - - return 0; -} - -static void mma7660_work_func(struct work_struct *work) -{ - struct mma7660_data *mma7660 = container_of(work, struct mma7660_data, work); - struct i2c_client *client = mma7660->client; - - if (mma7660_get_data(client) < 0) - rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n"); - - enable_irq(client->irq); -} - -static void mma7660_delaywork_func(struct work_struct *work) -{ - struct delayed_work *delaywork = container_of(work, struct delayed_work, work); - struct mma7660_data *mma7660 = container_of(delaywork, struct mma7660_data, delaywork); - struct i2c_client *client = mma7660->client; - - if (mma7660_get_data(client) < 0) - rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n"); - - enable_irq(client->irq); -} - -static irqreturn_t mma7660_interrupt(int irq, void *dev_id) -{ - struct mma7660_data *mma7660 = (struct mma7660_data *)dev_id; - - disable_irq_nosync(irq); - schedule_delayed_work(&mma7660->delaywork, msecs_to_jiffies(30)); - - return IRQ_HANDLED; -} - -static struct file_operations mma7660_fops = { - .owner = THIS_MODULE, - .open = mma7660_open, - .release = mma7660_release, - .unlocked_ioctl = mma7660_ioctl, -}; - -static struct miscdevice mma7660_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "mma8452_daemon",//"mma7660_daemon", - .fops = &mma7660_fops, -}; - -static int mma7660_remove(struct i2c_client *client) -{ - struct mma7660_data *mma7660 = i2c_get_clientdata(client); - - misc_deregister(&mma7660_device); - input_unregister_device(mma7660->input_dev); - input_free_device(mma7660->input_dev); - free_irq(client->irq, mma7660); - kfree(mma7660); -#ifdef CONFIG_ANDROID_POWER - android_unregister_early_suspend(&mma7660_early_suspend); -#endif - this_client = NULL; - return 0; -} - -#ifdef CONFIG_ANDROID_POWER -static int mma7660_suspend(android_early_suspend_t *h) -{ - struct i2c_client *client = container_of(mma7660_device.parent, struct i2c_client, dev); - rk28printk("Gsensor mma7760 enter suspend\n"); - return mma7660_close_dev(client); -} - -static int mma7660_resume(android_early_suspend_t *h) -{ - struct i2c_client *client = container_of(mma7660_device.parent, struct i2c_client, dev); - struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); - rk28printk("Gsensor mma7760 resume!!\n"); - return mma7660_start_dev(mma7660->curr_tate); -} -#else -static int mma7660_suspend(struct i2c_client *client, pm_message_t mesg) -{ - rk28printk("Gsensor mma7760 enter 2 level suspend\n"); - return mma7660_close_dev(client); -} -static int mma7660_resume(struct i2c_client *client) -{ - struct mma7660_data *mma7660 = (struct mma7660_data *)i2c_get_clientdata(client); - rk28printk("Gsensor mma7760 2 level resume!!\n"); - return mma7660_start_dev(client, mma7660->curr_tate); -} -#endif - -static const struct i2c_device_id mma7660_id[] = { - {"gs_mma7660", 0}, - { } -}; - -static struct i2c_driver mma7660_driver = { - .driver = { - .name = "gs_mma7660", - }, - .id_table = mma7660_id, - .probe = mma7660_probe, - .remove = __devexit_p(mma7660_remove), -#ifndef CONFIG_ANDROID_POWER - .suspend = &mma7660_suspend, - .resume = &mma7660_resume, -#endif -}; - - -static int mma7660_init_client(struct i2c_client *client) -{ - struct mma7660_data *mma7660; - int ret; - mma7660 = i2c_get_clientdata(client); - rk28printk("gpio_to_irq(%d) is %d\n",client->irq,gpio_to_irq(client->irq)); - if ( !gpio_is_valid(client->irq)) { - rk28printk("+++++++++++gpio_is_invalid\n"); - return -EINVAL; - } - ret = gpio_request(client->irq, "mma7660_int"); - if (ret) { - rk28printk( "failed to request mma7990_trig GPIO%d\n",gpio_to_irq(client->irq)); - return ret; - } - ret = gpio_direction_input(client->irq); - if (ret) { - rk28printk("failed to set mma7990_trig GPIO gpio input\n"); - return ret; - } - gpio_pull_updown(client->irq, GPIOPullUp); - client->irq = gpio_to_irq(client->irq); - ret = request_irq(client->irq, mma7660_interrupt, IRQF_TRIGGER_LOW, client->dev.driver->name, mma7660); - rk28printk("request irq is %d,ret is 0x%x\n",client->irq,ret); - if (ret ) { - rk28printk(KERN_ERR "mma7660_init_client: request irq failed,ret is %d\n",ret); - return ret; - } - disable_irq(client->irq); - init_waitqueue_head(&data_ready_wq); - - return 0; -} - -static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct mma7660_data *mma7660; - int err; - - Xaverage = Yaverage = Zaverage = RawDataNum = 0; - - mma7660 = kzalloc(sizeof(struct mma7660_data), GFP_KERNEL); - if (!mma7660) { - rk28printk("[mma7660]:alloc data failed.\n"); - err = -ENOMEM; - goto exit_alloc_data_failed; - } - - INIT_WORK(&mma7660->work, mma7660_work_func); - INIT_DELAYED_WORK(&mma7660->delaywork, mma7660_delaywork_func); - - mma7660->client = client; - //mma7660->swap_xy = - i2c_set_clientdata(client, mma7660); - - this_client = client; - - err = mma7660_init_client(client); - if (err < 0) { - rk28printk(KERN_ERR - "mma7660_probe: mma7660_init_client failed\n"); - goto exit_request_gpio_irq_failed; - } - - mma7660->input_dev = input_allocate_device(); - if (!mma7660->input_dev) { - err = -ENOMEM; - rk28printk(KERN_ERR - "mma7660_probe: Failed to allocate input device\n"); - goto exit_input_allocate_device_failed; - } - - set_bit(EV_ABS, mma7660->input_dev->evbit); - - /* x-axis acceleration */ - input_set_abs_params(mma7660->input_dev, ABS_X, -MMA7660_RANGE, MMA7660_RANGE, 0, 0); - /* y-axis acceleration */ - input_set_abs_params(mma7660->input_dev, ABS_Y, -MMA7660_RANGE, MMA7660_RANGE, 0, 0); - /* z-axis acceleration */ - input_set_abs_params(mma7660->input_dev, ABS_Z, -MMA7660_RANGE, MMA7660_RANGE, 0, 0); - - mma7660->input_dev->name = "compass"; - mma7660->input_dev->dev.parent = &client->dev; - - err = input_register_device(mma7660->input_dev); - if (err < 0) { - rk28printk(KERN_ERR - "mma7660_probe: Unable to register input device: %s\n", - mma7660->input_dev->name); - goto exit_input_register_device_failed; - } - - mma7660_device.parent = &client->dev; - err = misc_register(&mma7660_device); - if (err < 0) { - rk28printk(KERN_ERR - "mma7660_probe: mmad_device register failed\n"); - goto exit_misc_device_register_mma7660_device_failed; - } - - err = gsensor_sysfs_init(); - if (err < 0) { - rk28printk(KERN_ERR - "mma7660_probe: gsensor sysfs init failed\n"); - goto exit_gsensor_sysfs_init_failed; - } - -#ifdef CONFIG_ANDROID_POWER - mma7660_early_suspend.suspend = mma7660_suspend; - mma7660_early_suspend.resume = mma7660_resume; - mma7660_early_suspend.level = 0x2; - android_register_early_suspend(&mma7660_early_suspend); -#endif - rk28printk(KERN_INFO "mma7660 probe ok\n"); - mma7660->status = -1; -#if 0 - mma7660_start(client, MMA7660_RATE_32); -#endif - return 0; - -exit_gsensor_sysfs_init_failed: - misc_deregister(&mma7660_device); -exit_misc_device_register_mma7660_device_failed: - input_unregister_device(mma7660->input_dev); -exit_input_register_device_failed: - input_free_device(mma7660->input_dev); -exit_input_allocate_device_failed: - free_irq(client->irq, mma7660); -exit_request_gpio_irq_failed: - kfree(mma7660); -exit_alloc_data_failed: - ; - return err; -} - - -static int __init mma7660_i2c_init(void) -{ - return i2c_add_driver(&mma7660_driver); -} - -static void __exit mma7660_i2c_exit(void) -{ - i2c_del_driver(&mma7660_driver); -} - -module_init(mma7660_i2c_init); -module_exit(mma7660_i2c_exit); - - - diff --git a/drivers/input/gsensor/mma8452.c b/drivers/input/gsensor/mma8452.c deleted file mode 100755 index 58bbe2b6048c..000000000000 --- a/drivers/input/gsensor/mma8452.c +++ /dev/null @@ -1,833 +0,0 @@ -/* drivers/i2c/chips/mma8452.c - mma8452 compass driver - * - * Copyright (C) 2007-2008 HTC Corporation. - * Author: Hou-Kun Chen - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if 0 -#define mmaprintk(x...) printk(x) -#else -#define mmaprintk(x...) -#endif - -#if 0 -#define mmaprintkd(x...) printk(x) -#else -#define mmaprintkd(x...) -#endif - -#if 0 -#define mmaprintkf(x...) printk(x) -#else -#define mmaprintkf(x...) -#endif - -static int mma8452_probe(struct i2c_client *client, const struct i2c_device_id *id); - -#define MMA8452_SPEED 200 * 1000 -#define MMA8451_DEVID 0x1a -#define MMA8452_DEVID 0x2a -#define MMA8453_DEVID 0x3a -/* Addresses to scan -- protected by sense_data_mutex */ -//static char sense_data[RBUFF_SIZE + 1]; -static struct i2c_client *this_client; -static struct miscdevice mma8452_device; - -static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq); - -static int revision = -1; -static const char* vendor = "Freescale Semiconductor"; -static char devid; - - -typedef char status_t; -/*status*/ -#define MMA8452_OPEN 1 -#define MMA8452_CLOSE 0 - -struct mma8452_data { - status_t status; - char curr_tate; - struct input_dev *input_dev; - struct i2c_client *client; - struct work_struct work; - struct delayed_work delaywork; /*report second event*/ - - struct mma8452_axis sense_data; - struct mutex sense_data_mutex; - atomic_t data_ready; - wait_queue_head_t data_ready_wq; - - int start_count; - struct mutex operation_mutex; -}; - -/* AKM HW info */ -static ssize_t gsensor_vendor_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - - // sprintf(buf, "%#x\n", revision); - sprintf(buf, "%s.\n", vendor); - ret = strlen(buf) + 1; - - return ret; -} - -static DEVICE_ATTR(vendor, 0444, gsensor_vendor_show, NULL); - -static struct kobject *android_gsensor_kobj; - -static int gsensor_sysfs_init(void) -{ - int ret ; - - android_gsensor_kobj = kobject_create_and_add("android_gsensor", NULL); - if (android_gsensor_kobj == NULL) { - mmaprintk(KERN_ERR - "MMA8452 gsensor_sysfs_init:"\ - "subsystem_register failed\n"); - ret = -ENOMEM; - goto err; - } - - ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr); // "vendor" - if (ret) { - mmaprintk(KERN_ERR - "MMA8452 gsensor_sysfs_init:"\ - "sysfs_create_group failed\n"); - goto err4; - } - - return 0 ; -err4: - kobject_del(android_gsensor_kobj); -err: - return ret ; -} - -static int mma8452_rx_data(struct i2c_client *client, char *rxData, int length) -{ - int ret = 0; - char reg = rxData[0]; - ret = i2c_master_reg8_recv(client, reg, rxData, length, MMA8452_SPEED); - return (ret > 0)? 0 : ret; -} - -static int mma8452_tx_data(struct i2c_client *client, char *txData, int length) -{ - int ret = 0; - char reg = txData[0]; - ret = i2c_master_reg8_send(client, reg, &txData[1], length-1, MMA8452_SPEED); - return (ret > 0)? 0 : ret; -} - -static char mma845x_read_reg(struct i2c_client *client,int addr) -{ - char tmp; - int ret = 0; - - tmp = addr; -// ret = mma8452_tx_data(client, &tmp, 1); - ret = mma8452_rx_data(client, &tmp, 1); - return tmp; -} - -static int mma845x_write_reg(struct i2c_client *client,int addr,int value) -{ - char buffer[3]; - int ret = 0; - - buffer[0] = addr; - buffer[1] = value; - ret = mma8452_tx_data(client, &buffer[0], 2); - return ret; -} - - -static char mma8452_get_devid(struct i2c_client *client) -{ - printk("mma8452 devid:%x\n",mma845x_read_reg(client,MMA8452_REG_WHO_AM_I)); - return mma845x_read_reg(client,MMA8452_REG_WHO_AM_I); -} - -static int mma845x_active(struct i2c_client *client,int enable) -{ - int tmp; - int ret = 0; - - tmp = mma845x_read_reg(client,MMA8452_REG_CTRL_REG1); - if(enable) - tmp |=ACTIVE_MASK; - else - tmp &=~ACTIVE_MASK; - mmaprintkd("mma845x_active %s (0x%x)\n",enable?"active":"standby",tmp); - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG1,tmp); - return ret; -} - -static int mma8452_start_test(struct i2c_client *client) -{ - int ret = 0; - int tmp; - - mmaprintkf("-------------------------mma8452 start test------------------------\n"); - - /* standby */ - mma845x_active(client,0); - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - - /* disable FIFO FMODE = 0*/ - ret = mma845x_write_reg(client,MMA8452_REG_F_SETUP,0); - mmaprintkd("mma8452 MMA8452_REG_F_SETUP:%x\n",mma845x_read_reg(client,MMA8452_REG_F_SETUP)); - - /* set full scale range to 2g */ - ret = mma845x_write_reg(client,MMA8452_REG_XYZ_DATA_CFG,0); - mmaprintkd("mma8452 MMA8452_REG_XYZ_DATA_CFG:%x\n",mma845x_read_reg(client,MMA8452_REG_XYZ_DATA_CFG)); - - /* set bus 8bit/14bit(FREAD = 1,FMODE = 0) ,data rate*/ - tmp = (MMA8452_RATE_12P5<< MMA8452_RATE_SHIFT) | FREAD_MASK; - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG1,tmp); - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG1:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG1)); - - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG3,5); - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG3:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG3)); - - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG4,1); - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG4:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG4)); - - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG5,1); - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG5:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG5)); - - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - mma845x_active(client,1); - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - - enable_irq(client->irq); - msleep(50); - - return ret; -} - -static int mma8452_start_dev(struct i2c_client *client, char rate) -{ - int ret = 0; - int tmp; - struct mma8452_data *mma8452 = (struct mma8452_data *)i2c_get_clientdata(client); // mma8452_data 定义在 mma8452.h 中. - - mmaprintkf("-------------------------mma8452 start ------------------------\n"); - /* standby */ - mma845x_active(client,0); - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - - /* disable FIFO FMODE = 0*/ - ret = mma845x_write_reg(client,MMA8452_REG_F_SETUP,0); - mmaprintkd("mma8452 MMA8452_REG_F_SETUP:%x\n",mma845x_read_reg(client,MMA8452_REG_F_SETUP)); - - /* set full scale range to 2g */ - ret = mma845x_write_reg(client,MMA8452_REG_XYZ_DATA_CFG,0); - mmaprintkd("mma8452 MMA8452_REG_XYZ_DATA_CFG:%x\n",mma845x_read_reg(client,MMA8452_REG_XYZ_DATA_CFG)); - - /* set bus 8bit/14bit(FREAD = 1,FMODE = 0) ,data rate*/ - tmp = (rate<< MMA8452_RATE_SHIFT) | FREAD_MASK; - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG1,tmp); - mma8452->curr_tate = rate; - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG1:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG1)); - - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG3,5); - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG3:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG3)); - - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG4,1); - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG4:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG4)); - - ret = mma845x_write_reg(client,MMA8452_REG_CTRL_REG5,1); - mmaprintkd("mma8452 MMA8452_REG_CTRL_REG5:%x\n",mma845x_read_reg(client,MMA8452_REG_CTRL_REG5)); - - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - mma845x_active(client,1); - mmaprintkd("mma8452 MMA8452_REG_SYSMOD:%x\n",mma845x_read_reg(client,MMA8452_REG_SYSMOD)); - - enable_irq(client->irq); - return ret; - -} - -static int mma8452_start(struct i2c_client *client, char rate) -{ - struct mma8452_data *mma8452 = (struct mma8452_data *)i2c_get_clientdata(client); - - mmaprintkf("%s::enter\n",__FUNCTION__); - if (mma8452->status == MMA8452_OPEN) { - return 0; - } - mma8452->status = MMA8452_OPEN; - return mma8452_start_dev(client, rate); -} - -static int mma8452_close_dev(struct i2c_client *client) -{ - disable_irq_nosync(client->irq); - return mma845x_active(client,0); -} - -static int mma8452_close(struct i2c_client *client) -{ - struct mma8452_data *mma8452 = (struct mma8452_data *)i2c_get_clientdata(client); - mmaprintkf("%s::enter\n",__FUNCTION__); - mma8452->status = MMA8452_CLOSE; - - return mma8452_close_dev(client); -} - -static int mma8452_reset_rate(struct i2c_client *client, char rate) -{ - int ret = 0; - - mmaprintkf("\n----------------------------mma8452_reset_rate------------------------\n"); - - ret = mma8452_close_dev(client); - ret = mma8452_start_dev(client, rate); - - return ret ; -} - -static inline int mma8452_convert_to_int(const char high_byte, const char low_byte) -{ - s64 result; -/* enabled only if FREAD MODE */ -/* - if (high_byte < MMA8452_BOUNDARY) { - result = high_byte * MMA8452_GRAVITY_STEP; - } else { - result = ~(((~high_byte&0x7f) + 1) * MMA8452_GRAVITY_STEP) + 1; - } -*/ - switch (devid) { - - case MMA8451_DEVID: - result = ((int)high_byte << (MMA8451_PRECISION-8)) - | ((int)low_byte >> (16-MMA8451_PRECISION)); - if (result < MMA8451_BOUNDARY) - result = result* MMA8451_GRAVITY_STEP; - else - result = ~( ((~result & (0x7fff>>(16-MMA8451_PRECISION)) ) + 1) - * MMA8451_GRAVITY_STEP) + 1; - break; - - case MMA8452_DEVID: - result = ((int)high_byte << (MMA8452_PRECISION-8)) - | ((int)low_byte >> (16-MMA8452_PRECISION)); - if (result < MMA8452_BOUNDARY) - result = result* MMA8452_GRAVITY_STEP; - else - result = ~( ((~result & (0x7fff>>(16-MMA8452_PRECISION)) ) + 1) - * MMA8452_GRAVITY_STEP) + 1; - break; - - case MMA8453_DEVID: - result = ((int)high_byte << (MMA8453_PRECISION-8)) - | ((int)low_byte >> (16-MMA8453_PRECISION)); - if (result < MMA8453_BOUNDARY) - result = result* MMA8453_GRAVITY_STEP; - else - result = ~( ((~result & (0x7fff>>(16-MMA8453_PRECISION)) ) + 1) - * MMA8453_GRAVITY_STEP) + 1; - break; - - default: - mmaprintk(KERN_ERR - "mma8452_convert_to_int: devid wasn't set correctly\n"); - return -EFAULT; - } - - return (int)result; -} - -static void mma8452_report_value(struct i2c_client *client, struct mma8452_axis *axis) -{ - struct mma8452_data *mma8452 = i2c_get_clientdata(client); - //struct mma8452_axis *axis = (struct mma8452_axis *)rbuf; - - /* Report acceleration sensor information */ - input_report_abs(mma8452->input_dev, ABS_X, axis->x); - input_report_abs(mma8452->input_dev, ABS_Y, axis->y); - input_report_abs(mma8452->input_dev, ABS_Z, axis->z); - input_sync(mma8452->input_dev); - mmaprintkd("Gsensor x==%d y==%d z==%d\n",axis->x,axis->y,axis->z); -} - -/** 在 底半部执行, 具体获取 g sensor 数据. */ -static int mma8452_get_data(struct i2c_client *client) -{ - struct mma8452_data* mma8452 = i2c_get_clientdata(client); - int ret; - int x,y,z; - struct mma8452_axis axis; - struct gsensor_platform_data *pdata = pdata = client->dev.platform_data; - -/* enabled only if FREAD MODE */ -/* - char buffer[3]; - do { - memset(buffer, 0, 3); - buffer[0] = MMA8452_REG_X_OUT_MSB; - ret = mma8452_rx_data(client, &buffer[0], 3); - if (ret < 0) - return ret; - } while (0); - - x = mma8452_convert_to_int(buffer[0],0); - y = mma8452_convert_to_int(buffer[1],0); - z = mma8452_convert_to_int(buffer[2],0); -*/ - char buffer[6]; - do { - memset(buffer, 0, 6); - buffer[0] = MMA8452_REG_X_OUT_MSB; - ret = mma8452_rx_data(client, &buffer[0], 6); - if (ret < 0) - return ret; - } while (0); - - x = mma8452_convert_to_int(buffer[0],buffer[1]); - y = mma8452_convert_to_int(buffer[2],buffer[3]); - z = mma8452_convert_to_int(buffer[4],buffer[5]); - - if (pdata->swap_xyz) { - 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; - } - else { - axis.x = x; - axis.y = y; - axis.z = z; - } - - if(pdata->swap_xy) - { - axis.x = -axis.x; - swap(axis.x,axis.y); - } - - mmaprintkd( "%s: ------------------mma8452_GetData axis = %d %d %d--------------\n", - __func__, axis.x, axis.y, axis.z); - - //memcpy(sense_data, &axis, sizeof(axis)); - mma8452_report_value(client, &axis); - //atomic_set(&data_ready, 0); - //wake_up(&data_ready_wq); - - /* 互斥地缓存数据. */ - mutex_lock(&(mma8452->sense_data_mutex) ); - mma8452->sense_data = axis; - mutex_unlock(&(mma8452->sense_data_mutex) ); - - /* 置位 data_ready */ - atomic_set(&(mma8452->data_ready), 1); - /* 唤醒 data_ready 等待队列头. */ - wake_up(&(mma8452->data_ready_wq) ); - - return 0; -} - -/* -static int mma8452_trans_buff(char *rbuf, int size) -{ - //wait_event_interruptible_timeout(data_ready_wq, - // atomic_read(&data_ready), 1000); - wait_event_interruptible(data_ready_wq, - atomic_read(&data_ready)); - - atomic_set(&data_ready, 0); - memcpy(rbuf, &sense_data[0], size); - - return 0; -} -*/ - -static int mma8452_get_cached_data(struct i2c_client* client, struct mma8452_axis* sense_data) -{ - struct mma8452_data* this = (struct mma8452_data *)i2c_get_clientdata(client); - - wait_event_interruptible_timeout(this->data_ready_wq, - atomic_read(&(this->data_ready) ), - msecs_to_jiffies(1000) ); - if ( 0 == atomic_read(&(this->data_ready) ) ) { - printk("waiting 'data_ready_wq' timed out."); - return -1; - } - mutex_lock(&(this->sense_data_mutex) ); - *sense_data = this->sense_data; - mutex_unlock(&(this->sense_data_mutex) ); - return 0; -} - -static int mma8452_open(struct inode *inode, struct file *file) -{ - return 0;//nonseekable_open(inode, file); -} - -static int mma8452_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static long mma8452_ioctl( struct file *file, unsigned int cmd,unsigned long arg) -{ - - void __user *argp = (void __user *)arg; - // char msg[RBUFF_SIZE + 1]; - struct mma8452_axis sense_data = {0}; - int ret = -1; - char rate; - struct i2c_client *client = container_of(mma8452_device.parent, struct i2c_client, dev); - struct mma8452_data* this = (struct mma8452_data *)i2c_get_clientdata(client); /* 设备数据实例的指针. */ - - switch (cmd) { - case MMA_IOCTL_APP_SET_RATE: - if (copy_from_user(&rate, argp, sizeof(rate))) - return -EFAULT; - break; - default: - break; - } - - switch (cmd) { - case MMA_IOCTL_START: - mutex_lock(&(this->operation_mutex) ); - mmaprintkd("to perform 'MMA_IOCTL_START', former 'start_count' is %d.", this->start_count); - (this->start_count)++; - if ( 1 == this->start_count ) { - atomic_set(&(this->data_ready), 0); - if ( (ret = mma8452_start(client, MMA8452_RATE_12P5) ) < 0 ) { - mutex_unlock(&(this->operation_mutex) ); - return ret; - } - } - mutex_unlock(&(this->operation_mutex) ); - mmaprintkd("finish 'MMA_IOCTL_START', ret = %d.", ret); - return 0; - - case MMA_IOCTL_CLOSE: - mutex_lock(&(this->operation_mutex) ); - mmaprintkd("to perform 'MMA_IOCTL_CLOSE', former 'start_count' is %d, PID : %d", this->start_count, get_current()->pid); - if ( 0 == (--(this->start_count) ) ) { - atomic_set(&(this->data_ready), 0); - if ( (ret = mma8452_close(client) ) < 0 ) { - mutex_unlock(&(this->operation_mutex) ); - return ret; - } - } - mutex_unlock(&(this->operation_mutex) ); - return 0; - - case MMA_IOCTL_APP_SET_RATE: - ret = mma8452_reset_rate(client, rate); - if (ret < 0) - return ret; - break; - case MMA_IOCTL_GETDATA: - // ret = mma8452_trans_buff(msg, RBUFF_SIZE); - if ( (ret = mma8452_get_cached_data(client, &sense_data) ) < 0 ) { - printk("failed to get cached sense data, ret = %d.", ret); - return ret; - } - break; - default: - return -ENOTTY; - } - - switch (cmd) { - case MMA_IOCTL_GETDATA: - /* - if (copy_to_user(argp, &msg, sizeof(msg))) - return -EFAULT; - */ - if ( copy_to_user(argp, &sense_data, sizeof(sense_data) ) ) { - printk("failed to copy sense data to user space."); - return -EFAULT; - } - break; - default: - break; - } - - return 0; -} - -static void mma8452_work_func(struct work_struct *work) -{ - struct mma8452_data *mma8452 = container_of(work, struct mma8452_data, work); - struct i2c_client *client = mma8452->client; - - if (mma8452_get_data(client) < 0) - mmaprintkd(KERN_ERR "MMA8452 mma_work_func: Get data failed\n"); - - enable_irq(client->irq); -} - -static void mma8452_delaywork_func(struct work_struct *work) -{ - struct delayed_work *delaywork = container_of(work, struct delayed_work, work); - struct mma8452_data *mma8452 = container_of(delaywork, struct mma8452_data, delaywork); - struct i2c_client *client = mma8452->client; - - if (mma8452_get_data(client) < 0) - printk(KERN_ERR "MMA8452 mma_work_func: Get data failed\n"); - mmaprintkd("%s :int src:0x%02x\n",__FUNCTION__,mma845x_read_reg(mma8452->client,MMA8452_REG_INTSRC)); - enable_irq(client->irq); -} - -static irqreturn_t mma8452_interrupt(int irq, void *dev_id) -{ - struct mma8452_data *mma8452 = (struct mma8452_data *)dev_id; - - disable_irq_nosync(irq); - schedule_delayed_work(&mma8452->delaywork, msecs_to_jiffies(30)); - mmaprintkf("%s :enter\n",__FUNCTION__); - return IRQ_HANDLED; -} - -static struct file_operations mma8452_fops = { - .owner = THIS_MODULE, - .open = mma8452_open, - .release = mma8452_release, - .unlocked_ioctl = mma8452_ioctl, -}; - -static struct miscdevice mma8452_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "mma8452_daemon",//"mma8452_daemon", - .fops = &mma8452_fops, -}; - -static int mma8452_remove(struct i2c_client *client) -{ - struct mma8452_data *mma8452 = i2c_get_clientdata(client); - - misc_deregister(&mma8452_device); - input_unregister_device(mma8452->input_dev); - input_free_device(mma8452->input_dev); - free_irq(client->irq, mma8452); - kfree(mma8452); - this_client = NULL; - return 0; -} - -static const struct i2c_device_id mma8452_id[] = { - {"gs_mma8452", 0}, - { } -}; - -static struct i2c_driver mma8452_driver = { - .driver = { - .name = "gs_mma8452", - }, - .id_table = mma8452_id, - .probe = mma8452_probe, - .remove = __devexit_p(mma8452_remove), -}; - - -static int mma8452_init_client(struct i2c_client *client) -{ - struct mma8452_data *mma8452; - int ret,irq; - mma8452 = i2c_get_clientdata(client); - mmaprintk("gpio_to_irq(%d) is %d\n",client->irq,gpio_to_irq(client->irq)); - if ( !gpio_is_valid(client->irq)) { - mmaprintk("+++++++++++gpio_is_invalid\n"); - return -EINVAL; - } - ret = gpio_request(client->irq, "mma8452_int"); - if (ret) { - mmaprintk( "failed to request mma7990_trig GPIO%d\n",gpio_to_irq(client->irq)); - return ret; - } - ret = gpio_direction_input(client->irq); - if (ret) { - mmaprintk("failed to set mma7990_trig GPIO gpio input\n"); - gpio_free(client->irq); - return ret; - } - gpio_pull_updown(client->irq, GPIOPullUp); - irq = gpio_to_irq(client->irq); - ret = request_irq(irq, mma8452_interrupt, IRQF_TRIGGER_LOW, client->dev.driver->name, mma8452); - mmaprintk("request irq is %d,ret is 0x%x\n",irq,ret); - if (ret ) { - gpio_free(client->irq); - mmaprintk(KERN_ERR "mma8452_init_client: request irq failed,ret is %d\n",ret); - return ret; - } - client->irq = irq; - disable_irq(client->irq); - init_waitqueue_head(&data_ready_wq); - - return 0; -} - -static int mma8452_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct mma8452_data *mma8452; - struct gsensor_platform_data *pdata = pdata = client->dev.platform_data; - int err; - - mmaprintkf("%s enter\n",__FUNCTION__); - - mma8452 = kzalloc(sizeof(struct mma8452_data), GFP_KERNEL); - if (!mma8452) { - mmaprintk("[mma8452]:alloc data failed.\n"); - err = -ENOMEM; - goto exit_alloc_data_failed; - } - - INIT_WORK(&mma8452->work, mma8452_work_func); - INIT_DELAYED_WORK(&mma8452->delaywork, mma8452_delaywork_func); - - memset(&(mma8452->sense_data), 0, sizeof(struct mma8452_axis) ); - mutex_init(&(mma8452->sense_data_mutex) ); - - atomic_set(&(mma8452->data_ready), 0); - init_waitqueue_head(&(mma8452->data_ready_wq) ); - - mma8452->start_count = 0; - mutex_init(&(mma8452->operation_mutex) ); - - mma8452->status = MMA8452_CLOSE; - - mma8452->client = client; - i2c_set_clientdata(client, mma8452); - - this_client = client; - - devid = mma8452_get_devid(this_client); - if ((MMA8452_DEVID != devid) - && (MMA8451_DEVID != devid) - && (MMA8453_DEVID != devid)) { - pr_info("mma8452: invalid devid\n"); - goto exit_invalid_devid; - } - - err = mma8452_init_client(client); - if (err < 0) { - mmaprintk(KERN_ERR - "mma8452_probe: mma8452_init_client failed\n"); - goto exit_request_gpio_irq_failed; - } - - mma8452->input_dev = input_allocate_device(); - if (!mma8452->input_dev) { - err = -ENOMEM; - mmaprintk(KERN_ERR - "mma8452_probe: Failed to allocate input device\n"); - goto exit_input_allocate_device_failed; - } - - set_bit(EV_ABS, mma8452->input_dev->evbit); - - /* x-axis acceleration */ - input_set_abs_params(mma8452->input_dev, ABS_X, -MMA845X_RANGE, MMA845X_RANGE, 0, 0); //2g full scale range - /* y-axis acceleration */ - input_set_abs_params(mma8452->input_dev, ABS_Y, -MMA845X_RANGE, MMA845X_RANGE, 0, 0); //2g full scale range - /* z-axis acceleration */ - input_set_abs_params(mma8452->input_dev, ABS_Z, -MMA845X_RANGE, MMA845X_RANGE, 0, 0); //2g full scale range - - // mma8452->input_dev->name = "compass"; - mma8452->input_dev->name = "gsensor"; - mma8452->input_dev->dev.parent = &client->dev; - - err = input_register_device(mma8452->input_dev); - if (err < 0) { - mmaprintk(KERN_ERR - "mma8452_probe: Unable to register input device: %s\n", - mma8452->input_dev->name); - goto exit_input_register_device_failed; - } - - mma8452_device.parent = &client->dev; - err = misc_register(&mma8452_device); - if (err < 0) { - mmaprintk(KERN_ERR - "mma8452_probe: mmad_device register failed\n"); - goto exit_misc_device_register_mma8452_device_failed; - } - - err = gsensor_sysfs_init(); - if (err < 0) { - mmaprintk(KERN_ERR - "mma8452_probe: gsensor sysfs init failed\n"); - goto exit_gsensor_sysfs_init_failed; - } - - printk(KERN_INFO "mma8452 probe ok\n"); -#if 0 -// mma8452_start_test(this_client); - mma8452_start(client, MMA8452_RATE_12P5); -#endif - return 0; - -exit_gsensor_sysfs_init_failed: - misc_deregister(&mma8452_device); -exit_misc_device_register_mma8452_device_failed: - input_unregister_device(mma8452->input_dev); -exit_input_register_device_failed: - input_free_device(mma8452->input_dev); -exit_input_allocate_device_failed: - free_irq(client->irq, mma8452); -exit_request_gpio_irq_failed: - cancel_delayed_work_sync(&mma8452->delaywork); - cancel_work_sync(&mma8452->work); -exit_invalid_devid: - kfree(mma8452); -exit_alloc_data_failed: - ; - mmaprintk("%s error\n",__FUNCTION__); - return -1; -} - - -static int __init mma8452_i2c_init(void) -{ - return i2c_add_driver(&mma8452_driver); -} - -static void __exit mma8452_i2c_exit(void) -{ - i2c_del_driver(&mma8452_driver); -} - -module_init(mma8452_i2c_init); -module_exit(mma8452_i2c_exit); -