aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/synaptics_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/synaptics_sysfs.c')
-rw-r--r--drivers/input/touchscreen/synaptics_sysfs.c463
1 files changed, 460 insertions, 3 deletions
diff --git a/drivers/input/touchscreen/synaptics_sysfs.c b/drivers/input/touchscreen/synaptics_sysfs.c
index 510bc98..840a362 100644
--- a/drivers/input/touchscreen/synaptics_sysfs.c
+++ b/drivers/input/touchscreen/synaptics_sysfs.c
@@ -18,6 +18,10 @@
#include <linux/synaptics_s7301.h>
#include "synaptics_sysfs.h"
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+struct device *synaptics_with_gpio_led_device;
+#endif
+
const char *sec_sysfs_cmd_list[] = {
"fw_update",
"get_fw_ver_bin",
@@ -50,7 +54,11 @@ static int synaptics_ts_load_fw(struct synaptics_drv_data *data)
old_fs = get_fs();
set_fs(KERNEL_DS);
+#if defined(CONFIG_MACH_KONA)
+ fp = filp_open(SYNAPTICS_FW2, O_RDONLY, S_IRUSR);
+#else
fp = filp_open(SYNAPTICS_FW, O_RDONLY, S_IRUSR);
+#endif
if (IS_ERR(fp)) {
printk(KERN_ERR "[TSP] failed to open %s.\n", SYNAPTICS_FW);
error = -ENOENT;
@@ -63,8 +71,14 @@ static int synaptics_ts_load_fw(struct synaptics_drv_data *data)
fw_data = kzalloc(fw_size, GFP_KERNEL);
nread = vfs_read(fp, (char __user *)fw_data,
fw_size, &fp->f_pos);
+#if defined(CONFIG_MACH_KONA)
+ printk(KERN_DEBUG "[TSP] start, file path %s, size %u Bytes\n",
+ SYNAPTICS_FW2, fw_size);
+#else
printk(KERN_DEBUG "[TSP] start, file path %s, size %u Bytes\n",
SYNAPTICS_FW, fw_size);
+#endif
+
if (nread != fw_size) {
printk(KERN_ERR
"[TSP] failed to read firmware file, nread %u Bytes\n",
@@ -142,9 +156,69 @@ static void soft_reset(struct synaptics_drv_data *data)
static void check_all_raw_cap(struct synaptics_drv_data *data)
{
- int i;
+ int i, j, k=0;
u16 temp = 0;
- u16 length = data->x_line * data->y_line * 2;
+ u16 length;
+
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ u8 escape_rx_line;
+
+ if (data->pdata->support_extend_button)
+ escape_rx_line = data->pdata->extend_button_map->nbuttons;
+ else
+ escape_rx_line = data->pdata->button_map->nbuttons;
+
+ length = data->x_line * (data->y_line + escape_rx_line) * 2;
+
+ if (NULL == data->references)
+ data->references = kzalloc(length, GFP_KERNEL);
+
+ data->refer_min = 0xffff;
+ data->refer_max = 0x0;
+
+ /* set the index */
+ set_report_index(data, 0x0000);
+
+ /* Set the GetReport bit to run the AutoScan */
+ set_report_mode(data, 0x01, 0x00);
+
+ /* read all report data */
+ synaptics_ts_read_block(data,
+ data->f54.data_base_addr + 3,
+ data->references, length);
+
+ for (i = 0; i < data->x_line; i++) {
+ for (j = 0; j < data->y_line + escape_rx_line; j++) {
+ temp = (u16)(data->references[k] |
+ (data->references[k+1] << 8));
+
+ if (k != 0 && j !=0) {
+ if (j >= data->y_line) {
+ if (data->debug) {
+ printk(KERN_DEBUG
+ "[TSP][skip] raw cap[%d] : %u\n",
+ k, temp);
+ }
+ k += 2;
+ continue;
+ }
+ }
+ if (data->debug) {
+ if (data->debug) {
+ printk(KERN_DEBUG
+ "[TSP] raw cap[%d] : %u\n",
+ k, temp);
+ }
+ }
+ if (temp < data->refer_min)
+ data->refer_min = temp;
+ if (temp > data->refer_max)
+ data->refer_max = temp;
+ k += 2;
+ }
+ }
+#else
+ length = data->x_line * data->y_line * 2;
if (NULL == data->references)
data->references = kzalloc(length, GFP_KERNEL);
@@ -179,6 +253,7 @@ static void check_all_raw_cap(struct synaptics_drv_data *data)
if (temp > data->refer_max)
data->refer_max = temp;
}
+#endif
printk(KERN_DEBUG "[TSP] min : %u, max : %u\n",
data->refer_min, data->refer_max);
}
@@ -333,6 +408,56 @@ static void check_rx_to_rx(struct synaptics_drv_data *data)
kfree(buff);
}
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+static void check_delta_cap(struct synaptics_drv_data *data)
+{
+ int i, k=0;
+ u16 temp = 0;
+ u16 length;
+ u8 escape_rx_line;
+ u8 *btn_data;
+ int start_button_data;
+
+ if (data->pdata->support_extend_button)
+ escape_rx_line = data->pdata->extend_button_map->nbuttons;
+ else
+ escape_rx_line = data->pdata->button_map->nbuttons;
+
+ length = escape_rx_line * 2;
+
+ btn_data = kzalloc(length, GFP_KERNEL);
+
+ data->refer_min = 0xffff;
+ data->refer_max = 0x0;
+
+ start_button_data = ((data->x_line * (data->y_line + escape_rx_line)) + data->y_line) * 2;
+
+ /* set the index */
+ set_report_index(data, start_button_data);
+
+ /* Set the GetReport bit to run the AutoScan */
+ set_report_mode(data, 0x01, 0x00);
+
+ /* read all report data */
+ synaptics_ts_read_block(data,
+ data->f54.data_base_addr + 3,
+ btn_data, length);
+
+ for (i = 0; i < escape_rx_line; i++) {
+ temp = (u16)(btn_data[k] | (btn_data[k+1] << 8));
+ printk(KERN_DEBUG "[TSP] index[btn:%d] data[0x%x]\n", i, temp);
+
+ if (temp > BUTTON_THRESHOLD_LIMIT)
+ data->pdata->button_pressure[i] = BUTTON_THRESHOLD_MIN;
+ else
+ data->pdata->button_pressure[i] = temp;
+ k = k + 2;
+ }
+
+ kfree(btn_data);
+}
+#endif
+
static void check_diagnostics_mode(struct synaptics_drv_data *data)
{
/* Set report mode */
@@ -355,6 +480,12 @@ static void check_diagnostics_mode(struct synaptics_drv_data *data)
check_rx_to_rx(data);
break;
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ case REPORT_TYPE_DELTA_CAP:
+ check_delta_cap(data);
+ break;
+#endif
+
default:
break;
}
@@ -427,11 +558,25 @@ static u16 get_value(struct synaptics_drv_data *data,
u32 pos_x, u32 pos_y)
{
u16 tmp = 0;
+ u8 escape_rx_line;
switch (data->cmd_report_type) {
case REPORT_TYPE_RAW_CAP:
{
- u16 position = (u16)(data->y_line * pos_x) + pos_y;
+ u16 position;
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ if (data->pdata->support_extend_button)
+ escape_rx_line =
+ data->pdata->extend_button_map->nbuttons;
+ else
+ escape_rx_line =
+ data->pdata->button_map->nbuttons;
+
+ position = (u16)((data->y_line +
+ escape_rx_line) * pos_x) + pos_y;
+#else
+ position = (u16)(data->y_line * pos_x) + pos_y;
+#endif
position *= 2;
tmp = (u16)(data->references[position] |
(data->references[position+1] << 8));
@@ -845,6 +990,297 @@ static struct attribute_group sec_sysfs_attr_group = {
.attrs = sec_sysfs_attributes,
};
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+static ssize_t sec_touchkey_sensitivity_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ printk(KERN_INFO "[TSP] do noting!\n");
+ return size;
+}
+
+static ssize_t sec_touchkey_back_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON4]);
+ else
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON2]);
+}
+
+static ssize_t sec_touchkey_menu_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON2]);
+ else
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON1]);
+}
+
+static ssize_t sec_touchkey_threshold_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d %d %d %d %d\n",
+ BUTTON5_0_THRESHOLD,
+ BUTTON5_1_THRESHOLD,
+ BUTTON5_2_THRESHOLD,
+ BUTTON5_3_THRESHOLD,
+ BUTTON5_4_THRESHOLD);
+ else
+ return sprintf(buf, "%d %d\n",
+ BUTTON2_0_THRESHOLD,
+ BUTTON2_1_THRESHOLD);
+}
+
+static ssize_t sec_touchkey_dummy_btn1_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON1]);
+ else {
+ printk(KERN_DEBUG "[TSP] dummy btn1 not supported\n");
+ return 0;
+ }
+}
+
+static ssize_t sec_touchkey_dummy_btn3_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON3]);
+ else {
+ printk(KERN_DEBUG "[TSP] dummy btn3 not supported\n");
+ return 0;
+ }
+}
+
+static ssize_t sec_touchkey_dummy_btn5_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON5]);
+ else {
+ printk(KERN_DEBUG "[TSP] dummy btn5 not supported\n");
+ return 0;
+ }
+}
+
+static ssize_t sec_touchkey_button_all_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d %d %d %d %d\n",
+ data->pdata->button_pressure[BUTTON1],
+ data->pdata->button_pressure[BUTTON2],
+ data->pdata->button_pressure[BUTTON3],
+ data->pdata->button_pressure[BUTTON4],
+ data->pdata->button_pressure[BUTTON5]);
+ else
+ return sprintf(buf, "%d %d\n",
+ data->pdata->button_pressure[BUTTON1],
+ data->pdata->button_pressure[BUTTON2]);
+}
+
+static ssize_t sec_touchkey_button_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ u8 int_status = 0;
+ u8 button_status = 0;
+
+ /* check interrupt status */
+ synaptics_ts_read_data(data,
+ data->f01.data_base_addr + 1,
+ &int_status);
+
+ /* check button status */
+ synaptics_ts_read_data(data,
+ data->f1a.data_base_addr,
+ &button_status);
+
+ return sprintf(buf, "%d %d\n",
+ int_status,
+ button_status);
+}
+
+static ssize_t sec_brightness_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int on_off;
+
+ if (sscanf(buf, "%d\n", &on_off) == 1) {
+ //printk(KERN_DEBUG "[TSPLED] touch_led_on [%d]\n", on_off);
+ data->pdata->led_control(on_off);
+ } else {
+ printk(KERN_DEBUG "[TSPLED] buffer read failed\n");
+ }
+ return size;
+}
+
+static ssize_t sec_extra_button_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ int extra_event;
+
+ if (sscanf(buf, "%d\n", &extra_event) == 1) {
+ printk(KERN_DEBUG "[TSP] extra event [%d]\n", extra_event);
+ } else {
+ printk(KERN_DEBUG "[TSP] buffer read failed\n");
+ }
+ return size;
+}
+
+static ssize_t sec_keypad_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", atomic_read(&data->keypad_enable));
+}
+
+static ssize_t sec_keypad_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+
+ unsigned int val = 0;
+ sscanf(buf, "%d", &val);
+ val = (val == 0 ? 0 : 1);
+ atomic_set(&data->keypad_enable, val);
+ if (val) {
+ set_bit(KEY_BACK, data->input->keybit);
+ set_bit(KEY_MENU, data->input->keybit);
+ set_bit(KEY_HOME, data->input->keybit);
+ } else {
+ clear_bit(KEY_BACK, data->input->keybit);
+ clear_bit(KEY_MENU, data->input->keybit);
+ clear_bit(KEY_HOME, data->input->keybit);
+ }
+ input_sync(data->input);
+
+ return count;
+}
+
+static DEVICE_ATTR(touch_sensitivity, S_IRUGO | S_IWUSR,
+ NULL, sec_touchkey_sensitivity_store);
+static DEVICE_ATTR(touchkey_back, S_IRUGO | S_IWUSR,
+ sec_touchkey_back_show, NULL);
+static DEVICE_ATTR(touchkey_menu, S_IRUGO | S_IWUSR,
+ sec_touchkey_menu_show, NULL);
+static DEVICE_ATTR(touchkey_threshold, S_IRUGO | S_IWUSR,
+ sec_touchkey_threshold_show, NULL);
+static DEVICE_ATTR(touchkey_dummy_btn1, S_IRUGO | S_IWUSR,
+ sec_touchkey_dummy_btn1_show, NULL);
+static DEVICE_ATTR(touchkey_dummy_btn3, S_IRUGO | S_IWUSR,
+ sec_touchkey_dummy_btn3_show, NULL);
+static DEVICE_ATTR(touchkey_dummy_btn5, S_IRUGO | S_IWUSR,
+ sec_touchkey_dummy_btn5_show, NULL);
+static DEVICE_ATTR(touchkey_button_all, S_IRUGO | S_IWUSR,
+ sec_touchkey_button_all_show, NULL);
+static DEVICE_ATTR(brightness, S_IRUGO | S_IWUSR,
+ NULL, sec_brightness_store);
+static DEVICE_ATTR(extra_button_event, S_IRUGO | S_IWUSR,
+ NULL, sec_extra_button_store);
+static DEVICE_ATTR(touchkey_button_status, S_IRUGO | S_IWUSR,
+ sec_touchkey_button_status_show, NULL);
+static DEVICE_ATTR(keypad_enable, S_IRUGO|S_IWUSR,
+ sec_keypad_enable_show, sec_keypad_enable_store);
+
+static struct attribute *sec_touchkey_sysfs_attributes[] = {
+ &dev_attr_touch_sensitivity.attr,
+ &dev_attr_touchkey_back.attr,
+ &dev_attr_touchkey_menu.attr,
+ &dev_attr_touchkey_threshold.attr,
+ &dev_attr_touchkey_dummy_btn1.attr,
+ &dev_attr_touchkey_dummy_btn3.attr,
+ &dev_attr_touchkey_dummy_btn5.attr,
+ &dev_attr_touchkey_button_all.attr,
+ &dev_attr_brightness.attr,
+ &dev_attr_extra_button_event.attr,
+ &dev_attr_touchkey_button_status.attr,
+ &dev_attr_keypad_enable.attr,
+ NULL,
+};
+
+static struct attribute_group sec_touchkey_sysfs_attr_group = {
+ .attrs = sec_touchkey_sysfs_attributes,
+};
+#endif
+
int set_tsp_sysfs(struct synaptics_drv_data *data)
{
int ret = 0;
@@ -861,6 +1297,23 @@ int set_tsp_sysfs(struct synaptics_drv_data *data)
pr_err("[TSP] failed to create sysfs group\n");
goto err_device_create;
}
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+ synaptics_with_gpio_led_device = device_create(sec_class,
+ NULL, 0, data, "sec_touchkey");
+ if (IS_ERR(synaptics_with_gpio_led_device)) {
+ pr_err("[TSP] failed to create device for tsp_touchkey sysfs\n");
+ ret = -ENODEV;
+ goto err_device_create;
+ }
+
+ ret = sysfs_create_group(&synaptics_with_gpio_led_device->kobj,
+ &sec_touchkey_sysfs_attr_group);
+ if (ret) {
+ pr_err("[TSP] failed to create sec_touchkey sysfs group\n");
+ goto err_device_create;
+ }
+#endif
+
return 0;
err_device_create:
@@ -877,6 +1330,10 @@ void remove_tsp_sysfs(struct synaptics_drv_data *data)
kfree(data->tx_to_gnd);
sysfs_remove_group(&data->dev->kobj, &sec_sysfs_attr_group);
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+ sysfs_remove_group(&synaptics_with_gpio_led_device->kobj,
+ &sec_touchkey_sysfs_attr_group);
+#endif
put_device(data->dev);
device_unregister(data->dev);
}