aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorjt1134 <jt1134@gmail.com>2012-11-04 20:15:55 -0600
committerjt1134 <jt1134@gmail.com>2012-11-04 21:02:25 -0600
commit4645b5af63093e42c9aee645c6bf2de6cf8686c6 (patch)
tree1363cb501c2a0bcd2196d890701a730dcdb5ea89 /drivers/input
parentdabec1aad7b62ded1831757e4096a2deba03f6a8 (diff)
downloadkernel_samsung_aries-4645b5af63093e42c9aee645c6bf2de6cf8686c6.zip
kernel_samsung_aries-4645b5af63093e42c9aee645c6bf2de6cf8686c6.tar.gz
kernel_samsung_aries-4645b5af63093e42c9aee645c6bf2de6cf8686c6.tar.bz2
fascinatemtd: driver cleanup
- fascinatemtd has no FFC, remove s5ka3dx driver - remove device-specific light and accel drivers (fascinate is the only device using kr3dh anyways) - also remove unneeded s5k4ecgx include Change-Id: Ic0f6984b60146141e85aad0a2c16fcd5026d144b
Diffstat (limited to 'drivers/input')
-rwxr-xr-xdrivers/input/misc/Makefile7
-rwxr-xr-xdrivers/input/misc/gp2a.c6
-rwxr-xr-xdrivers/input/misc/gp2a_atlas.c736
-rwxr-xr-xdrivers/input/misc/kr3dh.c13
-rw-r--r--drivers/input/misc/kr3dh_cdma.c676
5 files changed, 11 insertions, 1427 deletions
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index e4aa0c7..2fcff8a 100755
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -20,15 +20,8 @@ obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o
obj-$(CONFIG_INPUT_BMA023) += bma023.o
obj-$(CONFIG_INPUT_YAS529) += yas529.o
-
-ifeq ($(CONFIG_SAMSUNG_FASCINATE),y)
-obj-$(CONFIG_INPUT_KR3DH) += kr3dh_cdma.o
-obj-$(CONFIG_OPTICAL_GP2A) += gp2a_atlas.o
-else
obj-$(CONFIG_INPUT_KR3DH) += kr3dh.o
obj-$(CONFIG_OPTICAL_GP2A) += gp2a.o
-endif
-
obj-$(CONFIG_INPUT_ORIENTATION) += orientation.o
obj-$(CONFIG_INPUT_YAMAHA) += yamaha.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
diff --git a/drivers/input/misc/gp2a.c b/drivers/input/misc/gp2a.c
index 8bd70db..4ea7cde 100755
--- a/drivers/input/misc/gp2a.c
+++ b/drivers/input/misc/gp2a.c
@@ -382,7 +382,6 @@ static int gp2a_setup_irq(struct gp2a_data *gp2a)
return rc;
}
-#ifndef CONFIG_SAMSUNG_FASCINATE
rc = gpio_direction_input(pdata->p_out);
if (rc < 0) {
pr_err("%s: failed to set gpio %d as input (%d)\n",
@@ -391,9 +390,6 @@ static int gp2a_setup_irq(struct gp2a_data *gp2a)
}
irq = gpio_to_irq(pdata->p_out);
-#else
- irq = pdata->p_irq;
-#endif
rc = request_threaded_irq(irq, NULL,
gp2a_irq_handler,
@@ -419,9 +415,7 @@ static int gp2a_setup_irq(struct gp2a_data *gp2a)
goto done;
err_request_irq:
-#ifndef CONFIG_SAMSUNG_FASCINATE
err_gpio_direction_input:
-#endif
gpio_free(pdata->p_out);
done:
return rc;
diff --git a/drivers/input/misc/gp2a_atlas.c b/drivers/input/misc/gp2a_atlas.c
deleted file mode 100755
index 1f65428..0000000
--- a/drivers/input/misc/gp2a_atlas.c
+++ /dev/null
@@ -1,736 +0,0 @@
-/* linux/driver/input/misc/gp2a.c
- * Copyright (C) 2010 Samsung Electronics. All rights reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/i2c.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/miscdevice.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/wakelock.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/workqueue.h>
-#include <linux/uaccess.h>
-#include <linux/gp2a.h>
-
-
-/* Note about power vs enable/disable:
- * The chip has two functions, proximity and ambient light sensing.
- * There is no separate power enablement to the two functions (unlike
- * the Capella CM3602/3623).
- * This module implements two drivers: /dev/proximity and /dev/light.
- * When either driver is enabled (via sysfs attributes), we give power
- * to the chip. When both are disabled, we remove power from the chip.
- * In suspend, we remove power if light is disabled but not if proximity is
- * enabled (proximity is allowed to wakeup from suspend).
- *
- * There are no ioctls for either driver interfaces. Output is via
- * input device framework and control via sysfs attributes.
- */
-
-
-#define gp2a_dbgmsg(str, args...) pr_debug("%s: " str, __func__, ##args)
-
-
-#define ADC_BUFFER_NUM 6
-
-/* ADDSEL is LOW */
-#define REGS_PROX 0x0 /* Read Only */
-#define REGS_GAIN 0x1 /* Write Only */
-#define REGS_HYS 0x2 /* Write Only */
-#define REGS_CYCLE 0x3 /* Write Only */
-#define REGS_OPMOD 0x4 /* Write Only */
-
-/* sensor type */
-#define LIGHT 0
-#define PROXIMITY 1
-#define ALL 2
-
-static u8 reg_defaults[5] = {
- 0x00, /* PROX: read only register */
- 0x08, /* GAIN: large LED drive level */
- 0x40, /* HYS: receiver sensitivity */
- 0x04, /* CYCLE: */
- 0x01, /* OPMOD: normal operating mode */
-};
-
-struct gp2a_data;
-
-enum {
- LIGHT_ENABLED = BIT(0),
- PROXIMITY_ENABLED = BIT(1),
-};
-
-/* driver data */
-struct gp2a_data {
- struct input_dev *proximity_input_dev;
- struct input_dev *light_input_dev;
- struct gp2a_platform_data *pdata;
- struct i2c_client *i2c_client;
- struct class *lightsensor_class;
- struct device *switch_cmd_dev;
- int irq;
- struct work_struct work_light;
- struct hrtimer timer;
- ktime_t light_poll_delay;
- int adc_value_buf[ADC_BUFFER_NUM];
- int adc_index_count;
- bool adc_buf_initialized;
- bool on;
- u8 power_state;
- struct mutex power_lock;
- struct wake_lock prx_wake_lock;
- struct workqueue_struct *wq;
- char val_state;
-};
-
-int gp2a_i2c_write(struct gp2a_data *gp2a, u8 reg, u8 *val)
-{
- int err = 0;
- struct i2c_msg msg[1];
- unsigned char data[2];
- int retry = 10;
- struct i2c_client *client = gp2a->i2c_client;
-
- if ((client == NULL) || (!client->adapter))
- return -ENODEV;
-
- while (retry--) {
- data[0] = reg;
- data[1] = *val;
-
- msg->addr = client->addr;
- msg->flags = 0; /* write */
- msg->len = 2;
- msg->buf = data;
-
- err = i2c_transfer(client->adapter, msg, 1);
-
- if (err >= 0)
- return 0;
- }
- return err;
-}
-
-static void gp2a_light_enable(struct gp2a_data *gp2a)
-{
- gp2a_dbgmsg("starting poll timer, delay %lldns\n",
- ktime_to_ns(gp2a->light_poll_delay));
- hrtimer_start(&gp2a->timer, gp2a->light_poll_delay, HRTIMER_MODE_REL);
-}
-
-static void gp2a_light_disable(struct gp2a_data *gp2a)
-{
- gp2a_dbgmsg("cancelling poll timer\n");
- hrtimer_cancel(&gp2a->timer);
- cancel_work_sync(&gp2a->work_light);
-}
-
-static ssize_t poll_delay_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct gp2a_data *gp2a = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", ktime_to_ns(gp2a->light_poll_delay));
-}
-
-
-static ssize_t poll_delay_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- struct gp2a_data *gp2a = dev_get_drvdata(dev);
- int64_t new_delay;
- int err;
-
- err = strict_strtoll(buf, 10, &new_delay);
- if (err < 0)
- return err;
-
- gp2a_dbgmsg("new delay = %lldns, old delay = %lldns\n",
- new_delay, ktime_to_ns(gp2a->light_poll_delay));
- mutex_lock(&gp2a->power_lock);
- if (new_delay != ktime_to_ns(gp2a->light_poll_delay)) {
- gp2a->light_poll_delay = ns_to_ktime(new_delay);
- if (gp2a->power_state & LIGHT_ENABLED) {
- gp2a_light_disable(gp2a);
- gp2a_light_enable(gp2a);
- }
- }
- mutex_unlock(&gp2a->power_lock);
-
- return size;
-}
-
-static ssize_t light_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct gp2a_data *gp2a = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n",
- (gp2a->power_state & LIGHT_ENABLED) ? 1 : 0);
-}
-
-static ssize_t proximity_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct gp2a_data *gp2a = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n",
- (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0);
-}
-
-static ssize_t light_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- struct gp2a_data *gp2a = dev_get_drvdata(dev);
- bool new_value;
-
- if (sysfs_streq(buf, "1"))
- new_value = true;
- else if (sysfs_streq(buf, "0"))
- new_value = false;
- else {
- pr_err("%s: invalid value %d\n", __func__, *buf);
- return -EINVAL;
- }
-
- mutex_lock(&gp2a->power_lock);
- gp2a_dbgmsg("new_value = %d, old state = %d\n",
- new_value, (gp2a->power_state & LIGHT_ENABLED) ? 1 : 0);
- if (new_value && !(gp2a->power_state & LIGHT_ENABLED)) {
- if (!gp2a->power_state)
- gp2a->pdata->power(true);
- gp2a->power_state |= LIGHT_ENABLED;
- gp2a_light_enable(gp2a);
- } else if (!new_value && (gp2a->power_state & LIGHT_ENABLED)) {
- gp2a_light_disable(gp2a);
- gp2a->power_state &= ~LIGHT_ENABLED;
- if (!gp2a->power_state)
- gp2a->pdata->power(false);
- }
- mutex_unlock(&gp2a->power_lock);
- return size;
-}
-
-static ssize_t proximity_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- struct gp2a_data *gp2a = dev_get_drvdata(dev);
- bool new_value;
-
- if (sysfs_streq(buf, "1"))
- new_value = true;
- else if (sysfs_streq(buf, "0"))
- new_value = false;
- else {
- pr_err("%s: invalid value %d\n", __func__, *buf);
- return -EINVAL;
- }
-
- mutex_lock(&gp2a->power_lock);
- gp2a_dbgmsg("new_value = %d, old state = %d\n",
- new_value, (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0);
- if (new_value && !(gp2a->power_state & PROXIMITY_ENABLED)) {
- if (!gp2a->power_state)
- gp2a->pdata->power(true);
- gp2a->power_state |= PROXIMITY_ENABLED;
- enable_irq(gp2a->irq);
- enable_irq_wake(gp2a->irq);
- gp2a_i2c_write(gp2a, REGS_GAIN, &reg_defaults[1]);
- gp2a_i2c_write(gp2a, REGS_HYS, &reg_defaults[2]);
- gp2a_i2c_write(gp2a, REGS_CYCLE, &reg_defaults[3]);
- gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[4]);
- } else if (!new_value && (gp2a->power_state & PROXIMITY_ENABLED)) {
- disable_irq_wake(gp2a->irq);
- disable_irq(gp2a->irq);
- gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[0]);
- gp2a->power_state &= ~PROXIMITY_ENABLED;
- if (!gp2a->power_state)
- gp2a->pdata->power(false);
- }
- mutex_unlock(&gp2a->power_lock);
- return size;
-}
-
-static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- poll_delay_show, poll_delay_store);
-
-static struct device_attribute dev_attr_light_enable =
- __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
- light_enable_show, light_enable_store);
-
-static struct device_attribute dev_attr_proximity_enable =
- __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
- proximity_enable_show, proximity_enable_store);
-
-static struct attribute *light_sysfs_attrs[] = {
- &dev_attr_light_enable.attr,
- &dev_attr_poll_delay.attr,
- NULL
-};
-
-static struct attribute_group light_attribute_group = {
- .attrs = light_sysfs_attrs,
-};
-
-static struct attribute *proximity_sysfs_attrs[] = {
- &dev_attr_proximity_enable.attr,
- NULL
-};
-
-static struct attribute_group proximity_attribute_group = {
- .attrs = proximity_sysfs_attrs,
-};
-
-static int lightsensor_get_adcvalue(struct gp2a_data *gp2a)
-{
- int i = 0;
- int j = 0;
- unsigned int adc_total = 0;
- int adc_avr_value;
- unsigned int adc_index = 0;
- unsigned int adc_max = 0;
- unsigned int adc_min = 0;
- int value = 0;
-
- /* get ADC */
- value = gp2a->pdata->light_adc_value();
-
- adc_index = (gp2a->adc_index_count++) % ADC_BUFFER_NUM;
-
- /*ADC buffer initialize (light sensor off ---> light sensor on) */
- if (!gp2a->adc_buf_initialized) {
- gp2a->adc_buf_initialized = true;
- for (j = 0; j < ADC_BUFFER_NUM; j++)
- gp2a->adc_value_buf[j] = value;
- } else
- gp2a->adc_value_buf[adc_index] = value;
-
- adc_max = gp2a->adc_value_buf[0];
- adc_min = gp2a->adc_value_buf[0];
-
- for (i = 0; i < ADC_BUFFER_NUM; i++) {
- adc_total += gp2a->adc_value_buf[i];
-
- if (adc_max < gp2a->adc_value_buf[i])
- adc_max = gp2a->adc_value_buf[i];
-
- if (adc_min > gp2a->adc_value_buf[i])
- adc_min = gp2a->adc_value_buf[i];
- }
- adc_avr_value = (adc_total-(adc_max+adc_min))/(ADC_BUFFER_NUM-2);
-
- if (gp2a->adc_index_count == ADC_BUFFER_NUM-1)
- gp2a->adc_index_count = 0;
-
- return adc_avr_value;
-}
-
-static void gp2a_work_func_light(struct work_struct *work)
-{
- struct gp2a_data *gp2a = container_of(work, struct gp2a_data,
- work_light);
- int adc = lightsensor_get_adcvalue(gp2a);
- input_report_abs(gp2a->light_input_dev, ABS_MISC, adc);
- input_sync(gp2a->light_input_dev);
-}
-
-/* This function is for light sensor. It operates every a few seconds.
- * It asks for work to be done on a thread because i2c needs a thread
- * context (slow and blocking) and then reschedules the timer to run again.
- */
-static enum hrtimer_restart gp2a_timer_func(struct hrtimer *timer)
-{
- struct gp2a_data *gp2a = container_of(timer, struct gp2a_data, timer);
- queue_work(gp2a->wq, &gp2a->work_light);
- hrtimer_forward_now(&gp2a->timer, gp2a->light_poll_delay);
- return HRTIMER_RESTART;
-}
-
-/* interrupt happened due to transition/change of near/far proximity state */
-irqreturn_t gp2a_irq_handler(int irq, void *data)
-{
- struct gp2a_data *ip = data;
- u8 setting;
- int val = gpio_get_value(ip->pdata->p_out);
- if (val < 0) {
- pr_err("%s: gpio_get_value error %d\n", __func__, val);
- return IRQ_HANDLED;
- }
-
- if (val != ip->val_state) {
- if (val)
- setting = 0x40;
- else
- setting = 0x20;
- gp2a_i2c_write(ip, REGS_HYS, &setting);
- }
-
- ip->val_state = val;
- pr_err("gp2a: proximity val = %d\n", val);
-
- /* 0 is close, 1 is far */
- input_report_abs(ip->proximity_input_dev, ABS_DISTANCE, val);
- input_sync(ip->proximity_input_dev);
- wake_lock_timeout(&ip->prx_wake_lock, 3*HZ);
-
- return IRQ_HANDLED;
-}
-
-static int gp2a_setup_irq(struct gp2a_data *gp2a)
-{
- int rc = -EIO;
- struct gp2a_platform_data *pdata = gp2a->pdata;
- int irq;
-
- gp2a_dbgmsg("start\n");
-
- rc = gpio_request(pdata->p_out, "gpio_proximity_out");
- if (rc < 0) {
- pr_err("%s: gpio %d request failed (%d)\n",
- __func__, pdata->p_out, rc);
- return rc;
- }
-
-#ifndef CONFIG_SAMSUNG_FASCINATE
- rc = gpio_direction_input(pdata->p_out);
- if (rc < 0) {
- pr_err("%s: failed to set gpio %d as input (%d)\n",
- __func__, pdata->p_out, rc);
- goto err_gpio_direction_input;
- }
-
- irq = gpio_to_irq(pdata->p_out);
-#else
- irq = pdata->p_irq;
-#endif
-
- rc = request_threaded_irq(irq, NULL,
- gp2a_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "proximity_int",
- gp2a);
- if (rc < 0) {
- pr_err("%s: request_irq(%d) failed for gpio %d (%d)\n",
- __func__, irq,
- pdata->p_out, rc);
- goto err_request_irq;
- }
-
- /* start with interrupts disabled */
- disable_irq(irq);
- gp2a->irq = irq;
-
- gp2a_dbgmsg("success\n");
-
- goto done;
-
-err_request_irq:
-err_gpio_direction_input:
- gpio_free(pdata->p_out);
-done:
- return rc;
-}
-
-static ssize_t lightsensor_file_state_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct gp2a_data *gp2a = dev_get_drvdata(dev);
- int adc = 0;
-
- adc = lightsensor_get_adcvalue(gp2a);
- return sprintf(buf, "%d\n", adc);
-}
-
-static DEVICE_ATTR(lightsensor_file_state, 0644, lightsensor_file_state_show,
- NULL);
-
-static const struct file_operations light_fops = {
- .owner = THIS_MODULE,
-};
-
-static struct miscdevice light_device = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "light",
- .fops = &light_fops,
-};
-
-static int gp2a_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int ret = -ENODEV;
- struct input_dev *input_dev;
- struct gp2a_data *gp2a;
- struct gp2a_platform_data *pdata = client->dev.platform_data;
-
- if (!pdata) {
- pr_err("%s: missing pdata!\n", __func__);
- return ret;
- }
- if (!pdata->power || !pdata->light_adc_value) {
- pr_err("%s: incomplete pdata!\n", __func__);
- return ret;
- }
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- pr_err("%s: i2c functionality check failed!\n", __func__);
- return ret;
- }
-
- gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
- if (!gp2a) {
- pr_err("%s: failed to alloc memory for module data\n",
- __func__);
- return -ENOMEM;
- }
-
- gp2a->pdata = pdata;
- gp2a->i2c_client = client;
- i2c_set_clientdata(client, gp2a);
-
- /* wake lock init */
- wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
- "prx_wake_lock");
- mutex_init(&gp2a->power_lock);
-
- ret = gp2a_setup_irq(gp2a);
- if (ret) {
- pr_err("%s: could not setup irq\n", __func__);
- goto err_setup_irq;
- }
-
- /* allocate proximity input_device */
- input_dev = input_allocate_device();
- if (!input_dev) {
- pr_err("%s: could not allocate input device\n", __func__);
- goto err_input_allocate_device_proximity;
- }
- gp2a->proximity_input_dev = input_dev;
- input_set_drvdata(input_dev, gp2a);
- input_dev->name = "proximity";
- input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
- input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
-
- gp2a_dbgmsg("registering proximity input device\n");
- ret = input_register_device(input_dev);
- if (ret < 0) {
- pr_err("%s: could not register input device\n", __func__);
- input_free_device(input_dev);
- goto err_input_register_device_proximity;
- }
- ret = sysfs_create_group(&input_dev->dev.kobj,
- &proximity_attribute_group);
- if (ret) {
- pr_err("%s: could not create sysfs group\n", __func__);
- goto err_sysfs_create_group_proximity;
- }
-
- /* hrtimer settings. we poll for light values using a timer. */
- hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- gp2a->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
- gp2a->timer.function = gp2a_timer_func;
-
- /* the timer just fires off a work queue request. we need a thread
- to read the i2c (can be slow and blocking). */
- gp2a->wq = create_singlethread_workqueue("gp2a_wq");
- if (!gp2a->wq) {
- ret = -ENOMEM;
- pr_err("%s: could not create workqueue\n", __func__);
- goto err_create_workqueue;
- }
- /* this is the thread function we run on the work queue */
- INIT_WORK(&gp2a->work_light, gp2a_work_func_light);
-
- /* allocate lightsensor-level input_device */
- input_dev = input_allocate_device();
- if (!input_dev) {
- pr_err("%s: could not allocate input device\n", __func__);
- ret = -ENOMEM;
- goto err_input_allocate_device_light;
- }
- input_set_drvdata(input_dev, gp2a);
- input_dev->name = "lightsensor-level";
- input_set_capability(input_dev, EV_ABS, ABS_MISC);
- input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
-
- gp2a_dbgmsg("registering lightsensor-level input device\n");
- ret = input_register_device(input_dev);
- if (ret < 0) {
- pr_err("%s: could not register input device\n", __func__);
- input_free_device(input_dev);
- goto err_input_register_device_light;
- }
- gp2a->light_input_dev = input_dev;
- ret = sysfs_create_group(&input_dev->dev.kobj,
- &light_attribute_group);
- if (ret) {
- pr_err("%s: could not create sysfs group\n", __func__);
- goto err_sysfs_create_group_light;
- }
-
- /* set sysfs for light sensor */
-
- ret = misc_register(&light_device);
- if (ret)
- pr_err(KERN_ERR "misc_register failed - light\n");
-
- gp2a->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
- if (IS_ERR(gp2a->lightsensor_class))
- pr_err("Failed to create class(lightsensor)!\n");
-
- gp2a->switch_cmd_dev = device_create(gp2a->lightsensor_class,
- NULL, 0, NULL, "switch_cmd");
- if (IS_ERR(gp2a->switch_cmd_dev))
- pr_err("Failed to create device(switch_cmd_dev)!\n");
-
- if (device_create_file(gp2a->switch_cmd_dev,
- &dev_attr_lightsensor_file_state) < 0)
- pr_err("Failed to create device file(%s)!\n",
- dev_attr_lightsensor_file_state.attr.name);
-
- dev_set_drvdata(gp2a->switch_cmd_dev, gp2a);
-
-#ifdef CONFIG_ARIES_NTT
- /* set initial proximity value as 1 */
- input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
- input_sync(gp2a->proximity_input_dev);
-#else
- /* set initial proximity value as 1 */
- input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
- input_sync(gp2a->proximity_input_dev);
-#endif
- goto done;
-
- /* error, unwind it all */
-err_sysfs_create_group_light:
- input_unregister_device(gp2a->light_input_dev);
-err_input_register_device_light:
-err_input_allocate_device_light:
- destroy_workqueue(gp2a->wq);
-err_create_workqueue:
- sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
- &proximity_attribute_group);
-err_sysfs_create_group_proximity:
- input_unregister_device(gp2a->proximity_input_dev);
-err_input_register_device_proximity:
-err_input_allocate_device_proximity:
- free_irq(gp2a->irq, 0);
- gpio_free(gp2a->pdata->p_out);
-err_setup_irq:
- mutex_destroy(&gp2a->power_lock);
- wake_lock_destroy(&gp2a->prx_wake_lock);
- kfree(gp2a);
-done:
- return ret;
-}
-
-static int gp2a_suspend(struct device *dev)
-{
- /* We disable power only if proximity is disabled. If proximity
- is enabled, we leave power on because proximity is allowed
- to wake up device. We remove power without changing
- gp2a->power_state because we use that state in resume.
- */
- struct i2c_client *client = to_i2c_client(dev);
- struct gp2a_data *gp2a = i2c_get_clientdata(client);
- if (gp2a->power_state & LIGHT_ENABLED)
- gp2a_light_disable(gp2a);
- if (gp2a->power_state == LIGHT_ENABLED)
- gp2a->pdata->power(false);
- return 0;
-}
-
-static int gp2a_resume(struct device *dev)
-{
- /* Turn power back on if we were before suspend. */
- struct i2c_client *client = to_i2c_client(dev);
- struct gp2a_data *gp2a = i2c_get_clientdata(client);
- if (gp2a->power_state == LIGHT_ENABLED)
- gp2a->pdata->power(true);
- if (gp2a->power_state & LIGHT_ENABLED)
- gp2a_light_enable(gp2a);
- return 0;
-}
-
-static int gp2a_i2c_remove(struct i2c_client *client)
-{
- struct gp2a_data *gp2a = i2c_get_clientdata(client);
- sysfs_remove_group(&gp2a->light_input_dev->dev.kobj,
- &light_attribute_group);
- input_unregister_device(gp2a->light_input_dev);
- sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
- &proximity_attribute_group);
- input_unregister_device(gp2a->proximity_input_dev);
- free_irq(gp2a->irq, NULL);
- gpio_free(gp2a->pdata->p_out);
- if (gp2a->power_state) {
- if (gp2a->power_state & LIGHT_ENABLED)
- gp2a_light_disable(gp2a);
- gp2a->pdata->power(false);
- }
- destroy_workqueue(gp2a->wq);
- mutex_destroy(&gp2a->power_lock);
- wake_lock_destroy(&gp2a->prx_wake_lock);
- kfree(gp2a);
- return 0;
-}
-
-static const struct i2c_device_id gp2a_device_id[] = {
- {"gp2a", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, gp2a_device_id);
-
-static const struct dev_pm_ops gp2a_pm_ops = {
- .suspend = gp2a_suspend,
- .resume = gp2a_resume
-};
-
-static struct i2c_driver gp2a_i2c_driver = {
- .driver = {
- .name = "gp2a",
- .owner = THIS_MODULE,
- .pm = &gp2a_pm_ops
- },
- .probe = gp2a_i2c_probe,
- .remove = gp2a_i2c_remove,
- .id_table = gp2a_device_id,
-};
-
-
-static int __init gp2a_init(void)
-{
- return i2c_add_driver(&gp2a_i2c_driver);
-}
-
-static void __exit gp2a_exit(void)
-{
- i2c_del_driver(&gp2a_i2c_driver);
-}
-
-module_init(gp2a_init);
-module_exit(gp2a_exit);
-
-MODULE_AUTHOR("mjchen@sta.samsung.com");
-MODULE_DESCRIPTION("Optical Sensor driver for gp2ap002a00f");
-MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/kr3dh.c b/drivers/input/misc/kr3dh.c
index bb6555a..6299b4e 100755
--- a/drivers/input/misc/kr3dh.c
+++ b/drivers/input/misc/kr3dh.c
@@ -304,7 +304,12 @@ static int kr3dh_measure(struct kr3dh_data *kr3dh, struct acceleration *accel)
value += kr3dh_position_map[pos][i][j] * (int)raw[j];
}
/* normalisation*/
- g = (long long)value * GRAVITY_EARTH / KR3DH_RESOLUTION;
+ // here we want to report a range of -512 .. 512, corresponding to -2g .. 2g
+ // 'value' is between -32768 .. 32768, corresponding also to -2g .. 2g
+ // so .. trim off the 6 lower bits and we should be good.
+ g = value >> 6;
+
+ //g = (long long)value * GRAVITY_EARTH / KR3DH_RESOLUTION;
accel->axis[i] = g;
}
@@ -407,7 +412,8 @@ static ssize_t kr3dh_enable_store(struct device *dev,
static ssize_t kr3dh_delay_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", kr3dh_get_delay(dev));
+ /* delay is "displayed" here as ms, but we have stored it as ns */
+ return sprintf(buf, "%d\n", kr3dh_get_delay(dev) / 1000000 );
}
static ssize_t kr3dh_delay_store(struct device *dev,
@@ -415,6 +421,9 @@ static ssize_t kr3dh_delay_store(struct device *dev,
const char *buf, size_t count)
{
unsigned long delay = simple_strtoul(buf, NULL, 10);
+
+ /* delay comes in here as miliseconds, but the system wants it as nanoseconds */
+ delay *= 1000000;
kr3dh_set_delay(dev, delay);
diff --git a/drivers/input/misc/kr3dh_cdma.c b/drivers/input/misc/kr3dh_cdma.c
deleted file mode 100644
index d96f9f8..0000000
--- a/drivers/input/misc/kr3dh_cdma.c
+++ /dev/null
@@ -1,676 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/mutex.h>
-#include <linux/types.h>
-#include <linux/workqueue.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/completion.h>
-#include "kr3dh_reg.h"
-
-
-
-#define TRACE_FUNC() pr_info(KR3DH_NAME ": <trace> %s()\n", __FUNCTION__)
-
-/* The default settings when sensor is on is for all 3 axis to be enabled
- * and output data rate set to 400Hz. Output is via a ioctl read call.
-*/
-#define DEFAULT_POWER_ON_SETTING (ODR400 | ENABLE_ALL_AXES)
-#define READ_REPEAT_SHIFT 3
-#define READ_REPEAT (1 << READ_REPEAT_SHIFT)
-
-#define DEVICE_ID (0x32)
-#define KR3DH_NAME "kr3dh"
-#define KR3DH_RESOLUTION 16384 /* [count/G] */
-#define GRAVITY_EARTH 9806650
-#define ABSMIN_2G (-GRAVITY_EARTH * 2)
-#define ABSMAX_2G (GRAVITY_EARTH * 2)
-
-
-
-static const struct odr_delay {
- u8 odr; /* odr reg setting */
- s64 delay; /* odr in ns */
-}kr3dh_odr_table [] = {
- { ODR400, 2500000LL }, /* 400Hz */
- { ODR100, 10000000LL }, /* 100Hz */
- { ODR50, 20000000LL }, /* 50Hz */
- { ODR10, 100000000LL }, /* 10Hz */
- { ODR5, 200000000LL }, /* 5Hz */
- { ODR2, 500000000LL }, /* 2Hz */
- { ODR1, 1000000000LL }, /* 1Hz */
- { ODRHALF, 2000000000LL }, /* 0.5Hz */
-};
-
-#define event_delay(s) (delay_to_jiffies(((s) / (1000 * 1000))))
-#define delay_to_jiffies(d) ((d)?msecs_to_jiffies(d):1)
-#define actual_delay(d) (jiffies_to_msecs(delay_to_jiffies(d)))
-
-
-/* KR3DM acceleration data */
-struct acceleration {
- int axis[3];
-};
-
-/*
- * driver private data
- */
-struct kr3dh_data {
- atomic_t enable; /* attribute value */
- atomic_t delay; /* attribute value */
- atomic_t position; /* attribute value */
- u8 ctrl_reg1_shadow;
- struct acceleration last; /* last measured data */
- struct mutex enable_mutex;
- struct mutex data_mutex;
- struct i2c_client *client;
- struct input_dev *input;
- struct delayed_work work;
-};
-
-
-/*
- * Transformation matrix for chip mounting position
- */
-static const int kr3dh_position_map[][3][3] = {
- {{ 0, -1, 0}, { 1, 0, 0}, { 0, 0, 1}}, /* top/upper-left */
- {{ 1, 0, 0}, { 0, 1, 0}, { 0, 0, 1}}, /* top/upper-right */
- {{ 0, 1, 0}, {-1, 0, 0}, { 0, 0, 1}}, /* top/lower-right */
- {{-1, 0, 0}, { 0, -1, 0}, { 0, 0, 1}}, /* top/lower-left */
- {{ 0, 1, 0}, { 1, 0, 0}, { 0, 0, -1}}, /* bottom/upper-right */
- {{-1, 0, 0}, { 0, 1, 0}, { 0, 0, -1}}, /* bottom/upper-left */
- {{ 0, -1, 0}, {-1, 0, 0}, { 0, 0, -1}}, /* bottom/lower-left */
- {{ 1, 0, 0}, { 0, -1, 0}, { 0, 0, -1}}, /* bottom/lower-right */
-};
-
-
-
-static int kr3dh_power_down(struct kr3dh_data *kr3dh)
-{
- int res = 0;
-
- res = i2c_smbus_write_byte_data(kr3dh->client,
- CTRL_REG1, PM_OFF);
-
- res = i2c_smbus_write_byte_data(kr3dh->client,
- CTRL_REG5, 0x00);
-
- return res;
-}
-
-static int kr3dh_power_up(struct kr3dh_data *kr3dh)
-{
- int res = 0;
-
- res = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG1,
- kr3dh->ctrl_reg1_shadow);
-
- res = i2c_smbus_write_byte_data(kr3dh->client,
- CTRL_REG5, 0x03);
-
- return res;
-
-}
-
-static int kr3dh_measure(struct kr3dh_data *kr3dh, struct acceleration *accel);
-
-static int kr3dh_hw_init(struct kr3dh_data *kr3dh)
-{
- int err = 0;
-
- kr3dh->ctrl_reg1_shadow = DEFAULT_POWER_ON_SETTING;
- err = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG1,
- DEFAULT_POWER_ON_SETTING);
- if (err) {
- pr_err("kr3dh_hw_init() i2c write ctrl_reg1 failed\n");
- }
-
- /* Disables Filters */
- err = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG2,0x00);
- if (err) {
- pr_err("kr3dh_hw_init() i2c write ctrl_reg2 failed\n");
- }
-
- /* Disable Interrupts */
- err = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG3,0x00);
- if (err) {
- pr_err("kr3dh_hw_init() i2c write ctrl_reg3 failed\n");
- }
-
- /* Non Continous mode, Little Endian, 2G Range */
- err = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG4,0x80);
- if (err) {
- pr_err("kr3dh_hw_init() i2c write ctrl_reg4 failed\n");
- }
-
- /* Sleep to Wake: TurnON */
- err = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG5,0x03);
- if (err) {
- pr_err("kr3dh_hw_init() i2c write ctrl_reg5 failed\n");
- }
-
- return err;
-}
-
-static int kr3dh_get_enable(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
-
- return atomic_read(&kr3dh->enable);
-
-}
-
-static void kr3dh_set_enable(struct device *dev, int enable)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
- int delay = atomic_read(&kr3dh->delay);
-
- mutex_lock(&kr3dh->enable_mutex);
-
- if (enable) { /* enable if state will be changed */
- if (!atomic_cmpxchg(&kr3dh->enable, 0, 1)) {
- kr3dh_power_up(kr3dh);
- schedule_delayed_work(&kr3dh->work,
- event_delay(delay) + 1);
- }
- } else { /* disable if state will be changed */
- if (atomic_cmpxchg(&kr3dh->enable, 1, 0)) {
- cancel_delayed_work_sync(&kr3dh->work);
- kr3dh_power_down(kr3dh);
- }
- }
- atomic_set(&kr3dh->enable, enable);
-
- mutex_unlock(&kr3dh->enable_mutex);
-
-}
-
-static int kr3dh_get_delay(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
-
- return atomic_read(&kr3dh->delay);
-}
-
-static void kr3dh_set_delay(struct device *dev, s64 delay)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
- u8 odr_value;
- int i, res = 0;
- unsigned long delay_ms = 0;
-
- /* determine optimum ODR */
- for (i = 1; (i < ARRAY_SIZE(kr3dh_odr_table)) &&
- (delay >= kr3dh_odr_table[i].delay); i++)
- ;
- odr_value = kr3dh_odr_table[i-1].odr;
- atomic_set(&kr3dh->delay, delay);
-
- mutex_lock(&kr3dh->enable_mutex);
-
- if (kr3dh_get_enable(dev)) {
- cancel_delayed_work_sync(&kr3dh->work);
- if (odr_value != (kr3dh->ctrl_reg1_shadow & ODR_MASK)) {
- u8 ctrl = (kr3dh->ctrl_reg1_shadow & ~ODR_MASK);
- ctrl |= odr_value;
- kr3dh->ctrl_reg1_shadow = ctrl;
- res = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG1, ctrl);
- printk("writing odr value 0x%x\n", odr_value);
- }
- delay_ms = delay ;
- delay_ms = delay_ms / 1000;
- delay_ms = delay_ms / 1000;
-
- schedule_delayed_work(&kr3dh->work,
- delay_to_jiffies(delay_ms) + 1);
- } else {
- kr3dh_power_up(kr3dh);
- if (odr_value != (kr3dh->ctrl_reg1_shadow & ODR_MASK)) {
- u8 ctrl = (kr3dh->ctrl_reg1_shadow & ~ODR_MASK);
- ctrl |= odr_value;
- kr3dh->ctrl_reg1_shadow = ctrl;
- res = i2c_smbus_write_byte_data(kr3dh->client, CTRL_REG1, ctrl);
- printk("writing odr value 0x%x\n", odr_value);
- }
-
- kr3dh_power_down(kr3dh);
- }
-
- mutex_unlock(&kr3dh->enable_mutex);
-}
-
-static int kr3dh_set_position(struct device *dev, int position)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
-
- return atomic_set(&kr3dh->position, position);
-
-}
-
-static int kr3dh_get_position(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
-
- return atomic_read(&kr3dh->position);
-
-}
-int kr3dh_i2c_byte_read(struct i2c_client *client, u8 command)
-{
- union i2c_smbus_data data;
- int status;
-
- status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_READ, command,
- I2C_SMBUS_BYTE_DATA, &data);
- if (status < 0) {
- pr_err("I2C read error: acceleration not read\n");
- }
- return (status < 0) ? status : data.byte;
-}
-
-static int kr3dh_measure(struct kr3dh_data *kr3dh, struct acceleration *accel)
-{
- int i =0;
- int j = 0;
- int value;
- int pos = (int)atomic_read(&kr3dh->position);
- unsigned char buf[6] = {0};
- short int raw[3] = {0};
- long long g;
-
- for (i = 0; i < 6; i++) {
- buf[i] = kr3dh_i2c_byte_read(kr3dh->client, AXISDATA_REG + i);
- }
- for (i = 0; i < 3; i++) {
- raw[i] = (unsigned short)(buf[i*2+1]<<8) + (unsigned short)buf[i*2];
- }
- for (i = 0; i < 3; i++) {
- value = 0;
- for (j = 0; j < 3; j++) {
- value += kr3dh_position_map[pos][i][j] * (int)raw[j];
- }
- /* normalisation*/
- // here we want to report a range of -512 .. 512, corresponding to -2g .. 2g
- // 'value' is between -32768 .. 32768, corresponding also to -2g .. 2g
- // so .. trim off the 6 lower bits and we should be good.
- g = value >> 6;
-
- //g = (long long)value * GRAVITY_EARTH / KR3DH_RESOLUTION;
- accel->axis[i] = g;
- }
-
- return 0;
-}
-
-static void kr3dh_work_func(struct work_struct *work)
-{
- struct kr3dh_data *kr3dh = container_of((struct delayed_work *)work,
- struct kr3dh_data, work);
- struct acceleration accel;
- unsigned long delay = event_delay(atomic_read(&kr3dh->delay));
-
- kr3dh_measure(kr3dh, &accel);
-
- input_report_rel(kr3dh->input, REL_X, accel.axis[0]);
- input_report_rel(kr3dh->input, REL_Y, accel.axis[1]);
- input_report_rel(kr3dh->input, REL_Z, accel.axis[2]);
- input_sync(kr3dh->input);
-
- mutex_lock(&kr3dh->data_mutex);
- kr3dh->last = accel;
- mutex_unlock(&kr3dh->data_mutex);
-
- schedule_delayed_work(&kr3dh->work, delay);
-
-}
-
-/*
- * Input device interface
- */
-static int kr3dh_input_init(struct i2c_client *client, struct kr3dh_data *kr3dh)
-{
- struct input_dev *dev;
- int err;
-
- dev = input_allocate_device();
- if (!dev) {
- return -ENOMEM;
- }
- dev->name = "accelerometer_sensor";
- dev->id.bustype = BUS_I2C;
-
- /* X */
- input_set_capability(dev, EV_REL, REL_X);
- input_set_abs_params(dev, REL_X, ABSMIN_2G, ABSMAX_2G, 0, 0);
- /* Y */
- input_set_capability(dev, EV_REL, REL_Y);
- input_set_abs_params(dev, REL_Y, ABSMIN_2G, ABSMAX_2G, 0, 0);
- /* Z */
- input_set_capability(dev, EV_REL, REL_Z);
- input_set_abs_params(dev, REL_Z, ABSMIN_2G, ABSMAX_2G, 0, 0);
- input_set_drvdata(dev, kr3dh);
- dev->dev.parent = &client->dev;
-
- err = input_register_device(dev);
- if (err < 0) {
- input_free_device(dev);
- return err;
- }
- kr3dh->input = dev;
-
- return 0;
-
-}
-
-static void kr3dh_input_fini(struct kr3dh_data *kr3dh)
-{
- struct input_dev *dev = kr3dh->input;
-
- input_unregister_device(dev);
- input_free_device(dev);
-
-}
-
-/*
- * sysfs device attributes
- */
-
-static ssize_t kr3dh_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", kr3dh_get_enable(dev));
-}
-
-static ssize_t kr3dh_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned long enable = simple_strtoul(buf, NULL, 10);
-
- if ((enable == 0) || (enable == 1)) {
- kr3dh_set_enable(dev, enable);
- }
-
- return count;
-
-}
-
-static ssize_t kr3dh_delay_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- /* delay is "displayed" here as ms, but we have stored it as ns */
- return sprintf(buf, "%d\n", kr3dh_get_delay(dev) / 1000000 );
-}
-
-static ssize_t kr3dh_delay_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned long delay = simple_strtoul(buf, NULL, 10);
-
- /* delay comes in here as miliseconds, but the system wants it as nanoseconds */
- delay *= 1000000;
-
- kr3dh_set_delay(dev, delay);
-
- return count;
-}
-
-static ssize_t kr3dh_position_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", kr3dh_get_position(dev));
-}
-
-static ssize_t kr3dh_position_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned long position;
-
- position = simple_strtoul(buf, NULL,10);
- if ((position >= 0) && (position <= 7)) {
- kr3dh_set_position(dev, position);
- }
-
- return count;
-}
-
-static ssize_t kr3dh_wake_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct input_dev *input = to_input_dev(dev);
- static atomic_t serial = ATOMIC_INIT(0);
-
- input_report_abs(input, ABS_MISC, atomic_inc_return(&serial));
-
- return count;
-
-}
-
-static ssize_t kr3dh_data_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct input_dev *input = to_input_dev(dev);
- struct kr3dh_data *kr3dh = input_get_drvdata(input);
- struct acceleration accel;
-
- mutex_lock(&kr3dh->data_mutex);
- accel = kr3dh->last;
- mutex_unlock(&kr3dh->data_mutex);
-
- return sprintf(buf, "%d %d %d\n", accel.axis[0], accel.axis[1], accel.axis[2]);
-}
-
-static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP,
- kr3dh_enable_show, kr3dh_enable_store);
-static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP,
- kr3dh_delay_show, kr3dh_delay_store);
-static DEVICE_ATTR(position, S_IRUGO|S_IWUSR,
- kr3dh_position_show, kr3dh_position_store);
-static DEVICE_ATTR(wake, S_IWUSR|S_IWGRP,
- NULL, kr3dh_wake_store);
-static DEVICE_ATTR(data, S_IRUGO,
- kr3dh_data_show, NULL);
-
-static struct attribute *kr3dh_attributes[] = {
- &dev_attr_enable.attr,
- &dev_attr_delay.attr,
- &dev_attr_position.attr,
- &dev_attr_wake.attr,
- &dev_attr_data.attr,
- NULL
-};
-
-static struct attribute_group kr3dh_attribute_group = {
- .attrs = kr3dh_attributes
-};
-
-
-static int kr3dh_detect(struct i2c_client *client, struct i2c_board_info *info)
-{
- int ret = 0;
- int err = 0;
- /* read chip id */
- ret = i2c_smbus_read_byte_data(client, WHO_AM_I);
-
- printk("KR3DH: DEVICE_ID -> %x\n", ret);
- if (ret != DEVICE_ID) {
- if (ret < 0) {
- pr_err("%s: i2c for reading chip id failed\n",
- __func__);
- err = ret;
- } else {
- pr_err("%s : Device identification failed\n",
- __func__);
- err = -ENODEV;
- }
- }
- return err;
-}
-
-static int kr3dh_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct kr3dh_data *kr3dh;
- int err;
-
- /* setup private data */
- kr3dh = kzalloc(sizeof(struct kr3dh_data), GFP_KERNEL);
- if (!kr3dh) {
- err = -ENOMEM;
- goto error_0;
- }
- mutex_init(&kr3dh->enable_mutex);
- mutex_init(&kr3dh->data_mutex);
-
- /* setup i2c client */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
- I2C_FUNC_SMBUS_READ_BYTE_DATA))
- {
- err = -ENODEV;
- goto error_1;
- }
- i2c_set_clientdata(client, kr3dh);
- kr3dh->client = client;
-
- /* detect and init hardware */
- if ((err = kr3dh_detect(client, NULL))) {
- goto error_1;
- }
- dev_info(&client->dev, "%s found\n", id->name);
-
- kr3dh_hw_init(kr3dh);
- kr3dh_set_delay(&client->dev, 20000000LL);
- kr3dh_set_position(&client->dev, 2);
-
- /* setup driver interfaces */
- INIT_DELAYED_WORK(&kr3dh->work, kr3dh_work_func);
-
- err = kr3dh_input_init(client, kr3dh);
- if (err < 0) {
- goto error_1;
- }
-
- err = sysfs_create_group(&kr3dh->input->dev.kobj, &kr3dh_attribute_group);
- if (err < 0) {
- goto error_2;
- }
-
- return 0;
-
-error_2:
- kr3dh_input_fini(kr3dh);
-error_1:
- kfree(kr3dh);
-error_0:
- return err;
-
-
-
-}
-
-static int kr3dh_remove(struct i2c_client *client)
-{
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
-
- kr3dh_set_enable(&client->dev, 0);
-
- sysfs_remove_group(&kr3dh->input->dev.kobj, &kr3dh_attribute_group);
- kr3dh_input_fini(kr3dh);
- kfree(kr3dh);
-
- return 0;
-}
-
-static int kr3dh_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
-
- TRACE_FUNC();
-
- mutex_lock(&kr3dh->enable_mutex);
-
- if (kr3dh_get_enable(&client->dev)) {
- cancel_delayed_work_sync(&kr3dh->work);
- kr3dh_power_down(kr3dh);
- }
- mutex_unlock(&kr3dh->enable_mutex);
-
- return 0;
-}
-
-static int kr3dh_resume(struct i2c_client *client)
-{
- struct kr3dh_data *kr3dh = i2c_get_clientdata(client);
- int delay = atomic_read(&kr3dh->delay);
-
- TRACE_FUNC();
-
- kr3dh_hw_init(kr3dh);
- kr3dh_set_delay(&client->dev, delay);
-
- mutex_lock(&kr3dh->enable_mutex);
-
- if (kr3dh_get_enable(&client->dev)) {
- kr3dh_power_up(kr3dh);
- schedule_delayed_work(&kr3dh->work,
- event_delay(delay) + 1);
- }
- mutex_unlock(&kr3dh->enable_mutex);
- return 0;
-}
-
-static const struct i2c_device_id kr3dh_id[] = {
- {KR3DH_NAME, 0},
- {},
-};
-
-MODULE_DEVICE_TABLE(i2c, kr3dh_id);
-
-struct i2c_driver kr3dh_driver ={
- .driver = {
- .name = "kr3dh",
- .owner = THIS_MODULE,
- },
- .probe = kr3dh_probe,
- .remove = kr3dh_remove,
- .suspend = kr3dh_suspend,
- .resume = kr3dh_resume,
- .id_table = kr3dh_id,
-};
-
-/*
- * Module init and exit
- */
-static int __init kr3dh_init(void)
-{
- return i2c_add_driver(&kr3dh_driver);
-}
-module_init(kr3dh_init);
-
-static void __exit kr3dh_exit(void)
-{
- i2c_del_driver(&kr3dh_driver);
-}
-module_exit(kr3dh_exit);
-
-MODULE_AUTHOR("Samsung");
-MODULE_DESCRIPTION("KR3DH 3 axis accelerometer driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("1.0.0");
-