summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Jain <ajain@motorola.com>2014-02-28 14:27:44 -0600
committerJames Wylder <jwylder@motorola.com>2014-03-05 17:47:29 -0600
commit784d7e49932e090b3c611ea063a88106425eab92 (patch)
tree2c330b573a65b76f71bad45382342025ff004be2
parentfb57b8a6b411647a35e380f23e1786ac6af72aff (diff)
downloadolio-linux-3.10-784d7e49932e090b3c611ea063a88106425eab92.tar.xz
olio-linux-3.10-784d7e49932e090b3c611ea063a88106425eab92.zip
IKXCLOCK-353: Enable Always on Touch
-rw-r--r--drivers/input/touchscreen/atmxt.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/drivers/input/touchscreen/atmxt.c b/drivers/input/touchscreen/atmxt.c
index b8382bbd500..7ae9ef86c9a 100644
--- a/drivers/input/touchscreen/atmxt.c
+++ b/drivers/input/touchscreen/atmxt.c
@@ -104,6 +104,7 @@ static void atmxt_active_handler(struct atmxt_driver_data *dd);
static int atmxt_process_message(struct atmxt_driver_data *dd,
uint8_t *msg, uint8_t size);
static void atmxt_report_touches(struct atmxt_driver_data *dd);
+static void atmxt_report_powerevent(struct atmxt_driver_data *dd);
static void atmxt_release_touches(struct atmxt_driver_data *dd);
static int atmxt_message_handler6(struct atmxt_driver_data *dd,
uint8_t *msg, uint8_t size);
@@ -371,6 +372,10 @@ static int atmxt_suspend(struct i2c_client *client, pm_message_t message)
atmxt_set_ic_state(dd, ATMXT_IC_SLEEP);
}
break;
+ case ATMXT_IC_SLEEP:
+ pr_info("%s: current IC state is %s already", __func__,
+ atmxt_ic_state_string[ic_state]);
+ break;
default:
printk(KERN_ERR "%s: Driver %s, IC %s suspend.\n",
__func__, atmxt_driver_state_string[drv_state],
@@ -1045,6 +1050,11 @@ static int atmxt_register_inputs(struct atmxt_driver_data *dd,
input_set_events_per_packet(dd->in_dev,
ATMXT_MAX_TOUCHES * (ARRAY_SIZE(dd->rdat->axis) + 1));
+ /* Always on Touch requires that this driver be able to
+ send KEY_POWER to wakeup the system */
+ set_bit(EV_KEY, dd->in_dev->evbit);
+ set_bit(KEY_POWER, dd->in_dev->keybit);
+
err = input_register_device(dd->in_dev);
if (err < 0) {
printk(KERN_ERR "%s: Failed to register input device.\n",
@@ -2343,7 +2353,10 @@ static void atmxt_active_handler(struct atmxt_driver_data *dd)
}
if (dd->status & (1 << ATMXT_REPORT_TOUCHES)) {
- atmxt_report_touches(dd);
+ if (atmxt_get_ic_state(dd) == ATMXT_IC_SLEEP)
+ atmxt_report_powerevent(dd);
+ else
+ atmxt_report_touches(dd);
dd->status = dd->status & ~(1 << ATMXT_REPORT_TOUCHES);
}
@@ -2401,6 +2414,17 @@ static int atmxt_process_message(struct atmxt_driver_data *dd,
return err;
}
+static void atmxt_report_powerevent(struct atmxt_driver_data *dd)
+{
+ pr_err("%s:\n", __func__);
+ /* power key press */
+ input_report_key(dd->in_dev, KEY_POWER, 1);
+ input_sync(dd->in_dev);
+ /* power key release */
+ input_report_key(dd->in_dev, KEY_POWER, 0);
+ input_sync(dd->in_dev);
+}
+
static void atmxt_report_touches(struct atmxt_driver_data *dd)
{
int i = 0;
@@ -3180,6 +3204,66 @@ static ssize_t atmxt_debug_drv_stat_show(struct device *dev,
}
static DEVICE_ATTR(drv_stat, S_IRUGO, atmxt_debug_drv_stat_show, NULL);
+
+static ssize_t atmxt_drv_interactivemode_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ unsigned long value = 0;
+ struct atmxt_driver_data *dd = dev_get_drvdata(dev);
+ int err;
+ uint8_t sleep_cmd[2] = {0xFE, 0xFE};
+
+ err = kstrtoul(buf, 10, &value);
+ if (err < 0) {
+ pr_err("%s: Failed to convert value.\n", __func__);
+ return err;
+ }
+
+ mutex_lock(dd->mutex);
+
+ if (value == 1) {
+ /* interactive mode, lets bump up rate*/
+ err = atmxt_i2c_write(dd,
+ dd->addr->pwr[0], dd->addr->pwr[1],
+ &(dd->data->pwr[0]), 2);
+ if (err < 0) {
+ pr_err("%s: i2c write failed\n", __func__);
+ goto error;
+ }
+ atmxt_set_ic_state(dd, ATMXT_IC_ACTIVE);
+ err = size;
+ } else if (value == 0) {
+ /* Non interactive mode, lets lower scan rate*/
+ err = atmxt_i2c_write(dd,
+ dd->addr->pwr[0], dd->addr->pwr[1],
+ &(sleep_cmd[0]), 2);
+
+ if (err < 0) {
+ pr_err("%s: i2c write failed\n", __func__);
+ goto error;
+ }
+ atmxt_set_ic_state(dd, ATMXT_IC_SLEEP);
+ err = size;
+ } else {
+ err = -EINVAL;
+ }
+
+error:
+ mutex_unlock(dd->mutex);
+ return err;
+}
+static ssize_t atmxt_drv_interactivemode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct atmxt_driver_data *dd = dev_get_drvdata(dev);
+ int ic_state = atmxt_get_ic_state(dd);
+ return snprintf(buf, PAGE_SIZE, "%s",
+ (ic_state == ATMXT_IC_ACTIVE ? "1" : "0"));
+}
+static DEVICE_ATTR(interactivemode, S_IRUGO | S_IWGRP | S_IWOTH,
+ atmxt_drv_interactivemode_show,
+ atmxt_drv_interactivemode_store);
+
#ifdef CONFIG_TOUCHSCREEN_DEBUG
static ssize_t atmxt_debug_drv_tdat_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -3756,6 +3840,13 @@ static int atmxt_create_sysfs_files(struct atmxt_driver_data *dd)
err = check;
}
+ check = device_create_file(&(dd->client->dev),
+ &dev_attr_interactivemode);
+ if (check < 0) {
+ pr_err("%s: Failed to create ic_ver.\n", __func__);
+ err = check;
+ }
+
return err;
}
@@ -3782,5 +3873,6 @@ static void atmxt_remove_sysfs_files(struct atmxt_driver_data *dd)
device_remove_file(&(dd->client->dev), &dev_attr_ic_grpoffset);
#endif
device_remove_file(&(dd->client->dev), &dev_attr_ic_ver);
+ device_remove_file(&(dd->client->dev), &dev_attr_interactivemode);
return;
}