diff options
Diffstat (limited to 'drivers/input')
| -rwxr-xr-x | drivers/input/touchscreen/Kconfig | 12 | ||||
| -rwxr-xr-x | drivers/input/touchscreen/Makefile | 1 | ||||
| -rw-r--r-- | drivers/input/touchscreen/elan_ts.c | 387 | ||||
| -rwxr-xr-x | drivers/input/touchscreen/max11801_ts.c | 283 |
4 files changed, 621 insertions, 62 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index bf8d1797589c..bf002d471b1f 100755 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -187,6 +187,18 @@ config TOUCHSCREEN_EGALAX To compile this driver as a module, choose M here: the module will be called egalax_ts. +config TOUCHSCREEN_ELAN + tristate "ELAN touchscreen input driver" + depends on I2C + help + Say Y here if you have an I2C ELAN touchscreen + attached. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called elan-touch. + config TOUCHSCREEN_FUJITSU tristate "Fujitsu serial touchscreen" select SERIO diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index f61dfe88bc62..28ac2d2c81bd 100755 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -66,3 +66,4 @@ obj-$(CONFIG_TOUCHSCREEN_P1003) += p1003_ts.o obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o +obj-$(CONFIG_TOUCHSCREEN_ELAN) += elan_ts.o diff --git a/drivers/input/touchscreen/elan_ts.c b/drivers/input/touchscreen/elan_ts.c new file mode 100644 index 000000000000..7edd87d6cd1b --- /dev/null +++ b/drivers/input/touchscreen/elan_ts.c @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2007-2008 HTC Corporation. + * + * This driver is adapted from elan8232_i2c.c written by Shan-Fu Chiou + * <sfchiou@gmail.com> and Jay Tu <jay_tu@htc.com>. + * This driver is also adapted from the ELAN Touch Screen driver + * written by Stanley Zeng <stanley.zeng@emc.com.tw> + * + * 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 <linux/input.h> +#include <linux/device.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/jiffies.h> +#include <linux/interrupt.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/hrtimer.h> +#include <linux/gpio.h> + +static const char ELAN_TS_NAME[] = "elan-touch"; + +#define ELAN_TS_X_MAX 1088 +#define ELAN_TS_Y_MAX 768 +#define ELAN_USER_X_MAX 800 +#define ELAN_USER_Y_MAX 600 +#define IDX_PACKET_SIZE 8 + +enum { + hello_packet = 0x55, + idx_coordinate_packet = 0x5a, +}; + +enum { + idx_finger_state = 7, +}; + +static struct workqueue_struct *elan_wq; + +static struct elan_data { + int intr_gpio; + int use_irq; + struct hrtimer timer; + struct work_struct work; + struct i2c_client *client; + struct input_dev *input; + wait_queue_head_t wait; +} elan_touch_data; + +/*--------------------------------------------------------------*/ +static int elan_touch_detect_int_level(void) +{ + unsigned v; + v = gpio_get_value(elan_touch_data.intr_gpio); + + return v; +} + +static int __elan_touch_poll(struct i2c_client *client) +{ + int status = 0, retry = 20; + + do { + status = elan_touch_detect_int_level(); + retry--; + mdelay(20); + } while (status == 1 && retry > 0); + + return (status == 0 ? 0 : -ETIMEDOUT); +} + +static int elan_touch_poll(struct i2c_client *client) +{ + return __elan_touch_poll(client); +} + +static int __hello_packet_handler(struct i2c_client *client) +{ + int rc; + uint8_t buf_recv[4] = { 0 }; + + rc = elan_touch_poll(client); + + if (rc < 0) { + return -EINVAL; + } + + rc = i2c_master_recv(client, buf_recv, 4); + + if (rc != 4) { + return rc; + } else { + int i; + printk("hello packet: [0x%02x 0x%02x 0x%02x 0x%02x]\n", + buf_recv[0], buf_recv[1], buf_recv[2], buf_recv[3]); + + for (i = 0; i < 4; i++) + if (buf_recv[i] != hello_packet) + return -EINVAL; + } + + return 0; +} + +static inline int elan_touch_parse_xy(uint8_t *data, uint16_t *x, + uint16_t *y) +{ + *x = (data[0] & 0xf0); + *x <<= 4; + *x |= data[1]; + if (*x >= ELAN_TS_X_MAX) + *x = ELAN_TS_X_MAX; + *x = ((((ELAN_TS_X_MAX - + *x) * 1000) / ELAN_TS_X_MAX) * ELAN_USER_X_MAX) / 1000; + + *y = (data[0] & 0x0f); + *y <<= 8; + *y |= data[2]; + if (*y >= ELAN_TS_Y_MAX) + *y = ELAN_TS_Y_MAX; + *y = ((((ELAN_TS_Y_MAX - + *y) * 1000) / ELAN_TS_Y_MAX) * ELAN_USER_Y_MAX) / 1000; + + return 0; +} + +/* __elan_touch_init -- hand shaking with touch panel + * + * 1.recv hello packet + */ +static int __elan_touch_init(struct i2c_client *client) +{ + int rc; + rc = __hello_packet_handler(client); + if (rc < 0) + goto hand_shake_failed; + +hand_shake_failed: + return rc; +} + +static int elan_touch_recv_data(struct i2c_client *client, uint8_t * buf) +{ + int rc, bytes_to_recv = IDX_PACKET_SIZE; + + if (buf == NULL) + return -EINVAL; + + memset(buf, 0, bytes_to_recv); + rc = i2c_master_recv(client, buf, bytes_to_recv); + if (rc != bytes_to_recv) { + return -EINVAL; + } + + return rc; +} + +static void elan_touch_report_data(struct i2c_client *client, uint8_t * buf) +{ + switch (buf[0]) { + case idx_coordinate_packet: + { + uint16_t x1, x2, y1, y2; + uint8_t finger_stat; + + finger_stat = (buf[idx_finger_state] & 0x06) >> 1; + + if (finger_stat == 0) { + input_report_key(elan_touch_data.input, BTN_TOUCH, 0); + input_report_key(elan_touch_data.input, BTN_2, 0); + } else if (finger_stat == 1) { + elan_touch_parse_xy(&buf[1], &x1, &y1); + input_report_abs(elan_touch_data.input, ABS_X, x1); + input_report_abs(elan_touch_data.input, ABS_Y, y1); + input_report_key(elan_touch_data.input, BTN_TOUCH, 1); + input_report_key(elan_touch_data.input, BTN_2, 0); + } else if (finger_stat == 2) { + elan_touch_parse_xy(&buf[1], &x1, &y1); + input_report_abs(elan_touch_data.input, ABS_X, x1); + input_report_abs(elan_touch_data.input, ABS_Y, y1); + input_report_key(elan_touch_data.input, BTN_TOUCH, 1); + elan_touch_parse_xy(&buf[4], &x2, &y2); + input_report_abs(elan_touch_data.input, ABS_HAT0X, x2); + input_report_abs(elan_touch_data.input, ABS_HAT0Y, y2); + input_report_key(elan_touch_data.input, BTN_2, 1); + } + input_sync(elan_touch_data.input); + break; + } + + default: + break; + } +} + +static void elan_touch_work_func(struct work_struct *work) +{ + int rc; + uint8_t buf[IDX_PACKET_SIZE] = { 0 }; + struct i2c_client *client = elan_touch_data.client; + + if (elan_touch_detect_int_level()) + return; + + rc = elan_touch_recv_data(client, buf); + if (rc < 0) + return; + + elan_touch_report_data(client, buf); +} + +static irqreturn_t elan_touch_ts_interrupt(int irq, void *dev_id) +{ + queue_work(elan_wq, &elan_touch_data.work); + + return IRQ_HANDLED; +} + +static enum hrtimer_restart elan_touch_timer_func(struct hrtimer *timer) +{ + queue_work(elan_wq, &elan_touch_data.work); + hrtimer_start(&elan_touch_data.timer, ktime_set(0, 12500000), + HRTIMER_MODE_REL); + + return HRTIMER_NORESTART; +} + +static int elan_touch_register_interrupt(struct i2c_client *client) +{ + int err = 0; + + if (client->irq) { + elan_touch_data.use_irq = 1; + err = + request_irq(client->irq, elan_touch_ts_interrupt, + IRQF_TRIGGER_FALLING, ELAN_TS_NAME, + &elan_touch_data); + + if (err < 0) { + printk("%s(%s): Can't allocate irq %d\n", __FILE__, + __func__, client->irq); + elan_touch_data.use_irq = 0; + } + } + + if (!elan_touch_data.use_irq) { + hrtimer_init(&elan_touch_data.timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + elan_touch_data.timer.function = elan_touch_timer_func; + hrtimer_start(&elan_touch_data.timer, ktime_set(1, 0), + HRTIMER_MODE_REL); + } + + printk("elan ts starts in %s mode.\n", + elan_touch_data.use_irq == 1 ? "interrupt" : "polling"); + + return 0; +} + +static int elan_touch_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err = 0; + + elan_wq = create_singlethread_workqueue("elan_wq"); + if (!elan_wq) { + err = -ENOMEM; + goto fail; + } + + elan_touch_data.client = client; + strlcpy(client->name, ELAN_TS_NAME, I2C_NAME_SIZE); + + INIT_WORK(&elan_touch_data.work, elan_touch_work_func); + + elan_touch_data.intr_gpio = irq_to_gpio(client->irq); + pr_debug("irq_to_gpio irq %d, gpio %d\n", client->irq, + elan_touch_data.intr_gpio); + + elan_touch_data.input = input_allocate_device(); + if (elan_touch_data.input == NULL) { + err = -ENOMEM; + goto fail; + } + + err = __elan_touch_init(client); + if (err < 0) { + printk("elan - Read Hello Packet Failed\n"); + goto fail; + } + + elan_touch_data.input->name = ELAN_TS_NAME; + elan_touch_data.input->id.bustype = BUS_I2C; + + set_bit(EV_SYN, elan_touch_data.input->evbit); + + set_bit(EV_KEY, elan_touch_data.input->evbit); + set_bit(BTN_TOUCH, elan_touch_data.input->keybit); + set_bit(BTN_2, elan_touch_data.input->keybit); + + set_bit(EV_ABS, elan_touch_data.input->evbit); + set_bit(ABS_X, elan_touch_data.input->absbit); + set_bit(ABS_Y, elan_touch_data.input->absbit); + set_bit(ABS_HAT0X, elan_touch_data.input->absbit); + set_bit(ABS_HAT0Y, elan_touch_data.input->absbit); + + input_set_abs_params(elan_touch_data.input, ABS_X, 0, ELAN_USER_X_MAX, + 0, 0); + input_set_abs_params(elan_touch_data.input, ABS_Y, 0, ELAN_USER_Y_MAX, + 0, 0); + input_set_abs_params(elan_touch_data.input, ABS_HAT0X, 0, + ELAN_USER_X_MAX, 0, 0); + input_set_abs_params(elan_touch_data.input, ABS_HAT0Y, 0, + ELAN_USER_Y_MAX, 0, 0); + + err = input_register_device(elan_touch_data.input); + if (err < 0) { + goto fail; + } + + elan_touch_register_interrupt(elan_touch_data.client); + + return 0; + +fail: + input_free_device(elan_touch_data.input); + if (elan_wq) + destroy_workqueue(elan_wq); + return err; +} + +static int elan_touch_remove(struct i2c_client *client) +{ + if (elan_wq) + destroy_workqueue(elan_wq); + + input_unregister_device(elan_touch_data.input); + + if (elan_touch_data.use_irq) + free_irq(client->irq, client); + else + hrtimer_cancel(&elan_touch_data.timer); + return 0; +} + +/* -------------------------------------------------------------------- */ +static const struct i2c_device_id elan_touch_id[] = { + {"elan-touch", 0}, + {} +}; + +static struct i2c_driver elan_touch_driver = { + .probe = elan_touch_probe, + .remove = elan_touch_remove, + .id_table = elan_touch_id, + .driver = { + .name = "elan-touch", + .owner = THIS_MODULE, + }, +}; + +static int __init elan_touch_init(void) +{ + return i2c_add_driver(&elan_touch_driver); +} + +static void __exit elan_touch_exit(void) +{ + i2c_del_driver(&elan_touch_driver); +} + +module_init(elan_touch_init); +module_exit(elan_touch_exit); + +MODULE_AUTHOR("Stanley Zeng <stanley.zeng@emc.com.tw>"); +MODULE_DESCRIPTION("ELAN Touch Screen driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c index ca88d6823a98..48ee3600a03b 100755 --- a/drivers/input/touchscreen/max11801_ts.c +++ b/drivers/input/touchscreen/max11801_ts.c @@ -2,7 +2,7 @@ * Driver for MAXI MAX11801 - A Resistive touch screen controller with * i2c interface * - * Copyright (C) 2011 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. * Author: Zhang Jiejing <jiejing.zhang@freescale.com> * * Based on mcs5000_ts.c @@ -38,6 +38,8 @@ #include <linux/input.h> #include <linux/slab.h> #include <linux/bitops.h> +#include <linux/delay.h> + /* Register Address define */ #define GENERNAL_STATUS_REG 0x00 @@ -53,13 +55,32 @@ #define AUX_MESURE_CONF_REG 0x0a #define OP_MODE_CONF_REG 0x0b +#define Panel_Setup_X (0x69 << 1) +#define Panel_Setup_Y (0x6b << 1) + +#define XY_combined_measurement (0x70 << 1) +#define X_measurement (0x78 << 1) +#define Y_measurement (0x7a << 1) +#define AUX_measurement (0x76 << 1) + /* FIFO is found only in max11800 and max11801 */ #define FIFO_RD_CMD (0x50 << 1) #define MAX11801_FIFO_INT (1 << 2) #define MAX11801_FIFO_OVERFLOW (1 << 3) +#define MAX11801_EDGE_INT (1 << 1) + +#define FIFO_RD_X_MSB (0x52 << 1) +#define FIFO_RD_X_LSB (0x53 << 1) +#define FIFO_RD_Y_MSB (0x54 << 1) +#define FIFO_RD_Y_LSB (0x55 << 1) +#define FIFO_RD_AUX_MSB (0x5a << 1) +#define FIFO_RD_AUX_LSB (0x5b << 1) #define XY_BUFSIZE 4 #define XY_BUF_OFFSET 4 +#define X_BUFSIZE 2 +#define Y_BUFSIZE 2 +#define AUX_BUFSIZE 2 #define MAX11801_MAX_X 0xfff #define MAX11801_MAX_Y 0xfff @@ -83,6 +104,54 @@ struct max11801_data { struct i2c_client *client; struct input_dev *input_dev; }; +struct i2c_client *max11801_client; +unsigned int max11801_workmode; + +static int max11801_dcm_write_command(struct i2c_client *client, int command) +{ + return i2c_smbus_write_byte(client, command); +} + +static u32 max11801_dcm_sample_aux(struct i2c_client *client) +{ + u8 temp_buf; + u8 aux_buf[AUX_BUFSIZE]; + int ret; + int aux = 0; + u32 sample_data = 0; + /* AUX_measurement*/ + max11801_dcm_write_command(client, AUX_measurement); + mdelay(5); + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_AUX_MSB, + 1, &temp_buf); + aux_buf[0] = temp_buf; + if (ret < 1) + printk(KERN_DEBUG "FIFO_RD_AUX_MSB read fails\n"); + mdelay(5); + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_AUX_LSB, + 1, &temp_buf); + aux_buf[1] = temp_buf; + if (ret < 1) + printk(KERN_DEBUG "FIFO_RD_AUX_LSB read fails\n"); + aux = (aux_buf[0] << 4) + + (aux_buf[1] >> 4); + /* + voltage = (9170*aux)/7371; + voltage is (26.2*3150*aux)/(16.2*0xFFF) + V(aux)=3150*sample/0xFFF,V(battery)=212*V(aux)/81 + sample_data = (14840*aux)/7371-1541; + */ + sample_data = (14840*aux)/7371; + return sample_data; +} + +u32 max11801_read_adc(void) +{ + u32 adc_data; + adc_data = max11801_dcm_sample_aux(max11801_client); + return adc_data; +} +EXPORT_SYMBOL_GPL(max11801_read_adc); static u8 read_register(struct i2c_client *client, int addr) { @@ -109,76 +178,166 @@ static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id) struct i2c_client *client = data->client; int status, i, ret; u8 buf[XY_BUFSIZE]; + u8 x_buf[X_BUFSIZE]; + u8 y_buf[Y_BUFSIZE]; + u8 temp_buf[1]; int x = -1; int y = -1; status = read_register(data->client, GENERNAL_STATUS_REG); - - if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) { - status = read_register(data->client, GENERNAL_STATUS_REG); - - ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD, - XY_BUFSIZE, buf); - - /* - * We should get 4 bytes buffer that contains X,Y - * and event tag - */ - if (ret < XY_BUFSIZE) - goto out; - - for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) { - if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG) - x = (buf[i] << XY_BUF_OFFSET) + - (buf[i + 1] >> XY_BUF_OFFSET); - else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG) - y = (buf[i] << XY_BUF_OFFSET) + - (buf[i + 1] >> XY_BUF_OFFSET); - } - - if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK)) - goto out; - - switch (buf[1] & EVENT_TAG_MASK) { - case EVENT_INIT: - /* fall through */ - case EVENT_MIDDLE: - calibration_pointer(&x, &y); - input_report_abs(data->input_dev, ABS_X, x); - input_report_abs(data->input_dev, ABS_Y, y); - input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1); - input_sync(data->input_dev); - break; - - case EVENT_RELEASE: - input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0); - input_sync(data->input_dev); - break; - - case EVENT_FIFO_END: - break; - } - } + if (max11801_workmode == 0) { + if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) { + status = read_register(data->client, GENERNAL_STATUS_REG); + + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD, + XY_BUFSIZE, buf); + + /* + * We should get 4 bytes buffer that contains X,Y + * and event tag + */ + if (ret < XY_BUFSIZE) + goto out; + + for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) { + if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG) + x = (buf[i] << XY_BUF_OFFSET) + + (buf[i + 1] >> XY_BUF_OFFSET); + else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG) + y = (buf[i] << XY_BUF_OFFSET) + + (buf[i + 1] >> XY_BUF_OFFSET); + } + + if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK)) + goto out; + + switch (buf[1] & EVENT_TAG_MASK) { + case EVENT_INIT: + /* fall through */ + case EVENT_MIDDLE: + calibration_pointer(&x, &y); + input_report_abs(data->input_dev, ABS_X, x); + input_report_abs(data->input_dev, ABS_Y, y); + input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1); + input_sync(data->input_dev); + break; + + case EVENT_RELEASE: + input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0); + input_sync(data->input_dev); + break; + + case EVENT_FIFO_END: + break; + } + } out: - return IRQ_HANDLED; +return IRQ_HANDLED; + } + else if (max11801_workmode == 1) { + if (status & (MAX11801_EDGE_INT)) { + status = read_register(data->client, GENERNAL_STATUS_REG); + + /* X = panel setup*/ + max11801_dcm_write_command(client, Panel_Setup_X); + /* X_measurement*/ + max11801_dcm_write_command(client, X_measurement); + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_X_MSB, + 1, temp_buf); + x_buf[0] = temp_buf[0]; + if (ret < 1) + goto out2; + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_X_LSB, + 1, temp_buf); + x_buf[1] = temp_buf[0]; + if (ret < 1) + goto out2; + /* Y = panel setup*/ + max11801_dcm_write_command(client, Panel_Setup_Y); + /* Y_measurement*/ + max11801_dcm_write_command(client, Y_measurement); + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_Y_MSB, + 1, temp_buf); + y_buf[0] = temp_buf[0]; + if (ret < 1) + goto out2; + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_Y_LSB, + 1, temp_buf); + y_buf[1] = temp_buf[0]; + if (ret < 1) + goto out2; + + if ((x_buf[1] & MEASURE_TAG_MASK) == MEASURE_X_TAG) + x = (x_buf[0] << XY_BUF_OFFSET) + + (x_buf[1] >> XY_BUF_OFFSET); + if ((y_buf[1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG) + y = (y_buf[0] << XY_BUF_OFFSET) + + (y_buf[1] >> XY_BUF_OFFSET); + + if ((x_buf[1] & EVENT_TAG_MASK) != (y_buf[1] & EVENT_TAG_MASK)) + goto out2; + + switch (x_buf[1] & EVENT_TAG_MASK) { + case EVENT_INIT: + /* fall through */ + case EVENT_MIDDLE: + calibration_pointer(&x, &y); + input_report_abs(data->input_dev, ABS_X, x); + input_report_abs(data->input_dev, ABS_Y, y); + input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1); + input_sync(data->input_dev); + break; + + case EVENT_RELEASE: + input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0); + input_sync(data->input_dev); + break; + + case EVENT_FIFO_END: + break; + } + } + } +out2: +return IRQ_HANDLED; } static void __devinit max11801_ts_phy_init(struct max11801_data *data) { struct i2c_client *client = data->client; - - /* Average X,Y, take 16 samples, average eight media sample */ - max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff); - /* X,Y panel setup time set to 20us */ - max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11); - /* Rough pullup time (2uS), Fine pullup time (10us) */ - max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10); - /* Auto mode init period = 5ms , scan period = 5ms*/ - max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa); - /* Aperture X,Y set to +- 4LSB */ - max11801_write_reg(client, APERTURE_CONF_REG, 0x33); - /* Enable Power, enable Automode, enable Aperture, enable Average X,Y */ - max11801_write_reg(client, OP_MODE_CONF_REG, 0x36); + max11801_client = client; + if (max11801_workmode == 0) { + /* Average X,Y, take 16 samples, average eight media sample */ + max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff); + /* X,Y panel setup time set to 20us */ + max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11); + /* Rough pullup time (2uS), Fine pullup time (10us) */ + max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10); + /* Auto mode init period = 5ms , scan period = 5ms*/ + max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa); + /* Aperture X,Y set to +- 4LSB */ + max11801_write_reg(client, APERTURE_CONF_REG, 0x33); + /* Enable Power, enable Automode, enable Aperture, enable Average X,Y */ + max11801_write_reg(client, OP_MODE_CONF_REG, 0x36); + } + if (max11801_workmode == 1) { + /* Average X,Y, take 16 samples, average eight media sample */ + max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff); + /* X,Y panel setup time set to 20us */ + max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11); + /* Rough pullup time (2uS), Fine pullup time (10us) */ + max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10); + /* Auto mode init period = 5ms , scan period = 5ms*/ + max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa); + /* Aperture X,Y set to +- 4LSB */ + max11801_write_reg(client, APERTURE_CONF_REG, 0x33); + /* Enable Power, enable Direct conversion mode , enable Aperture, enable Average X,Y */ + max11801_write_reg(client, OP_MODE_CONF_REG, 0x16); + /* Delay initial=1ms, Sampling time 2us ,Averaging sample depth 2 samples, Resolution 12bit */ + max11801_write_reg(client, AUX_MESURE_CONF_REG, 0x76); + /* Use edge interrupt with direct conversion mode */ + max11801_write_reg(client, GENERNAL_CONF_REG, 0xf3); + } } static int __devinit max11801_ts_probe(struct i2c_client *client, @@ -195,7 +354,7 @@ static int __devinit max11801_ts_probe(struct i2c_client *client, error = -ENOMEM; goto err_free_mem; } - + max11801_workmode = *(int *)(client->dev).platform_data; data->client = client; data->input_dev = input_dev; |
