From 1bfe9d02e8b72b2df1bbb493c912fd50a2f144fa Mon Sep 17 00:00:00 2001 From: kfx Date: Mon, 31 Dec 2012 17:12:24 +0800 Subject: [PATCH] rk3168: ds1006h: update touchscreen(ct363) --- arch/arm/mach-rk30/board-rk3168-ds1006h.c | 2 +- drivers/input/touchscreen/ct36x/core.c | 2 +- drivers/input/touchscreen/ct36x/ct363.c | 225 ++++++++++++++++ drivers/input/touchscreen/ct36x/ct365.c | 255 ------------------- drivers/input/touchscreen/ct36x/ct36x_priv.h | 5 +- drivers/input/touchscreen/ct36x/ct36x_ts.c | 24 +- 6 files changed, 248 insertions(+), 265 deletions(-) create mode 100644 drivers/input/touchscreen/ct36x/ct363.c delete mode 100644 drivers/input/touchscreen/ct36x/ct365.c diff --git a/arch/arm/mach-rk30/board-rk3168-ds1006h.c b/arch/arm/mach-rk30/board-rk3168-ds1006h.c index 0a2e5bf7406d..2ca3a37cc85d 100644 --- a/arch/arm/mach-rk30/board-rk3168-ds1006h.c +++ b/arch/arm/mach-rk30/board-rk3168-ds1006h.c @@ -102,7 +102,7 @@ struct rk29_keys_platform_data rk29_keys_pdata = { #if defined(CONFIG_CT36X_TS) -#define TOUCH_MODEL 365 +#define TOUCH_MODEL 363 #define TOUCH_MAX_X 1280 #define TOUCH_MAX_y 800 #define TOUCH_RESET_PIN RK30_PIN0_PB6 diff --git a/drivers/input/touchscreen/ct36x/core.c b/drivers/input/touchscreen/ct36x/core.c index 43ba5a3287de..fe7ef5974f6a 100644 --- a/drivers/input/touchscreen/ct36x/core.c +++ b/drivers/input/touchscreen/ct36x/core.c @@ -315,8 +315,8 @@ int ct36x_chip_go_bootloader(struct ct36x_data *ts) // Write source data ret = ct36x_chip_wr_firmware(ts); - dev_err(ts->dev, "CT36X chip: Failed to write firmware\n"); if(ret < 0){ + dev_err(ts->dev, "CT36X chip: Failed to write firmware\n"); return ret; } return 0; diff --git a/drivers/input/touchscreen/ct36x/ct363.c b/drivers/input/touchscreen/ct36x/ct363.c new file mode 100644 index 000000000000..f29d708ccdb9 --- /dev/null +++ b/drivers/input/touchscreen/ct36x/ct363.c @@ -0,0 +1,225 @@ +#define CT363_POINT_NUM 10 + +struct ct363_finger_data { + unsigned char xhi; // X coordinate Hi + unsigned char yhi; // Y coordinate Hi + unsigned char ylo : 4; // Y coordinate Lo + unsigned char xlo : 4; // X coordinate Lo + unsigned char status : 3; // Action information, 1: Down; 2: Move; 3: Up + unsigned char id : 5; // ID information, from 1 to CFG_MAX_POINT_NUM + unsigned char area; // Touch area + unsigned char pressure; // Touch Pressure +}; + + +struct ct363_priv{ + int press; + int release; + int x, y; + union{ + struct ct363_finger_data pts[CT363_POINT_NUM]; + char buf[CT363_POINT_NUM * sizeof(struct ct363_finger_data)]; + }; +}; + +static int ct363_init_hw(struct ct36x_data *ts) +{ + int ret = 0; + + ret = gpio_request(ts->rst_io.gpio, "ct363_rst"); + if(ret < 0){ + dev_err(ts->dev, "Failed to request rst gpio\n"); + return ret; + } + + ret = gpio_request(ts->irq_io.gpio, "ct363_irq"); + if(ret < 0){ + gpio_free(ts->rst_io.gpio); + dev_err(ts->dev, "Failed to request irq gpio\n"); + return ret; + } + gpio_direction_input(ts->irq_io.gpio); + gpio_pull_updown(ts->irq_io.gpio, 1); + + gpio_direction_output(ts->rst_io.gpio, ts->rst_io.active_low); + + return 0; +} +static void ct363_deinit_hw(struct ct36x_data *ts) +{ + gpio_free(ts->rst_io.gpio); + gpio_free(ts->irq_io.gpio); +} + +static void ct363_reset_hw(struct ct36x_data *ts) +{ + gpio_direction_output(ts->rst_io.gpio, ts->rst_io.active_low); + msleep(50); + gpio_set_value(ts->rst_io.gpio, !ts->rst_io.active_low); + msleep(50); + gpio_set_value(ts->rst_io.gpio, ts->rst_io.active_low); + msleep(500); +} + +static int ct363_init(struct ct36x_data *ts) +{ + int ret = 0, fwchksum, binchksum, updcnt = 5; + struct ct363_priv *ct363 = NULL; + + ret = ct363_init_hw(ts); + if(ret < 0) + return ret; + + /* Hardware reset */ + ct363_reset_hw(ts); + // Get binary Checksum + binchksum = ct36x_chip_get_binchksum(); + ct36x_dbg(ts, "CT363 init: binchksum = %d\n", binchksum); + + ret = ct36x_chip_get_fwchksum(ts); + if(ret < 0){ + dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n"); + return ret; + } + fwchksum = ret; + ct36x_dbg(ts, "CT363 init: fwchksum = %d\n", fwchksum); + while(binchksum != fwchksum && updcnt--) { + /* Update Firmware */ + ret = ct36x_chip_go_bootloader(ts); + if(ret < 0){ + dev_err(ts->dev, "CT36X chip: Failed to go bootloader\n"); + return ret; + } + /* Hardware reset */ + ct363_reset_hw(ts); + + ret = ct36x_chip_get_fwchksum(ts); + if(ret < 0){ + dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n"); + return ret; + } + fwchksum = ret; + ct36x_dbg(ts, "CT363 update FW: fwchksum = %d\n", fwchksum); + } + if(binchksum != fwchksum){ + dev_err(ts->dev, "Fail to update FW\n"); + return -ENODEV; + } + + /* Hardware reset */ + ct363_reset_hw(ts); + msleep(5); + + ts->point_num = CT363_POINT_NUM; + + ct363 = kzalloc(sizeof(struct ct363_priv), GFP_KERNEL); + if(!ct363){ + dev_err(ts->dev, "No memory for ct36x"); + return -ENOMEM; + } + ts->priv = ct363; + + return 0; +} + +static void ct363_deinit(struct ct36x_data *ts) +{ + struct ct363_priv *ct363 = ts->priv; + + ct363_deinit_hw(ts); + kfree(ct363); + ts->priv = NULL; + + return; +} + +static int ct363_suspend(struct ct36x_data *ts) +{ + int ret = 0; + + ret = ct36x_chip_go_sleep(ts); + + if(ret < 0) + dev_warn(ts->dev, "CT363 chip: failed to go to sleep\n"); + return ret; +} + +static int ct363_resume(struct ct36x_data *ts) +{ + int i; + + /* Hardware reset */ + ct363_reset_hw(ts); + msleep(3); + + for(i = 0; i < ts->point_num; i++){ + input_mt_slot(ts->input, i); + input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); + } + input_sync(ts->input); + + return 0; +} + +static void ct363_report(struct ct36x_data *ts) +{ + int i, ret = 0; + int sync = 0, x, y; + int len = sizeof(struct ct363_finger_data) * ts->point_num; + struct ct363_priv *ct363 = ts->priv; + + ret = ct36x_read(ts, ct363->buf, len); + if(ret < 0){ + dev_warn(ts->dev, "Failed to read finger data\n"); + return; + } + + + ct363->press = 0; + for(i = 0; i < ts->point_num; i++){ + if((ct363->pts[i].xhi != 0xFF && ct363->pts[i].yhi != 0xFF) && + (ct363->pts[i].status == 1 || ct363->pts[i].status == 2)){ + x = (ct363->pts[i].xhi<<4)|(ct363->pts[i].xlo&0xF); + y = (ct363->pts[i].yhi<<4)|(ct363->pts[i].ylo&0xF); + ct363->x = ts->orientation[0] * x + ts->orientation[1] * y; + ct363->y = ts->orientation[2] * x + ts->orientation[3] * y; + if(ct363->x < 0) + ct363->x = ts->x_max - ct363->x; + if(ct363->y < 0) + ct363->y = ts->y_max - ct363->y; + + input_mt_slot(ts->input, ct363->pts[i].id - 1); + input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); + input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 1); + input_report_abs(ts->input, ABS_MT_POSITION_X, x); + input_report_abs(ts->input, ABS_MT_POSITION_Y, y); + input_report_abs(ts->input, ABS_MT_PRESSURE, ct363->pts[i].pressure); + ct36x_dbg(ts, "CT363 report value: x: %d, y:%d\n", ct363->x, ct363->y); + + sync = 1; + ct363->press |= 0x01 << (ct363->pts[i].id - 1); + } + } + ct363->release &= ct363->release ^ ct363->press; + for(i = 0; i < ts->point_num; i++){ + if ( ct363->release & (0x01<input, i); + input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); + ct36x_dbg(ts, "CT363 release\n"); + sync = 1; + } + } + ct363->release = ct363->press; + + if(sync) + input_sync(ts->input); + + return; +} +struct ct36x_ops ct363_ops = { + .init = ct363_init, + .deinit = ct363_deinit, + .suspend = ct363_suspend, + .resume = ct363_resume, + .report = ct363_report, +}; diff --git a/drivers/input/touchscreen/ct36x/ct365.c b/drivers/input/touchscreen/ct36x/ct365.c deleted file mode 100644 index fb8406039d12..000000000000 --- a/drivers/input/touchscreen/ct36x/ct365.c +++ /dev/null @@ -1,255 +0,0 @@ -#define CT365_POINT_NUM 10 - -struct ct365_finger_data { - unsigned char status : 4; // Action information, 1: Down; 2: Move; 3: Up - unsigned char id : 4; // ID information, from 1 to CFG_MAX_POINT_NUM - unsigned char xhi; // X coordinate Hi - unsigned char yhi; // Y coordinate Hi - unsigned char ylo : 4; // Y coordinate Lo - unsigned char xlo : 4; // X coordinate Lo - unsigned char area; // Touch area - unsigned char pressure; // Touch Pressure -}; - - -struct ct365_priv{ - int press; - int release; - int x, y; - union{ - struct ct365_finger_data pts[CT365_POINT_NUM]; - char buf[CT365_POINT_NUM * sizeof(struct ct365_finger_data)]; - }; -}; - -static int ct365_init_hw(struct ct36x_data *ts) -{ - int ret = 0; - - ret = gpio_request(ts->rst_io.gpio, "ct365_rst"); - if(ret < 0){ - dev_err(ts->dev, "Failed to request rst gpio\n"); - return ret; - } - - ret = gpio_request(ts->irq_io.gpio, "ct365_irq"); - if(ret < 0){ - gpio_free(ts->rst_io.gpio); - dev_err(ts->dev, "Failed to request irq gpio\n"); - return ret; - } - gpio_direction_input(ts->irq_io.gpio); - gpio_pull_updown(ts->irq_io.gpio, 1); - - gpio_direction_output(ts->rst_io.gpio, ts->rst_io.active_low); - - return 0; -} -static void ct365_deinit_hw(struct ct36x_data *ts) -{ - gpio_free(ts->rst_io.gpio); - gpio_free(ts->irq_io.gpio); -} - -static void ct365_reset_hw(struct ct36x_data *ts) -{ - gpio_direction_output(ts->rst_io.gpio, ts->rst_io.active_low); - msleep(50); - gpio_set_value(ts->rst_io.gpio, !ts->rst_io.active_low); - msleep(50); - gpio_set_value(ts->rst_io.gpio, ts->rst_io.active_low); - msleep(500); -} - -static int ct365_init(struct ct36x_data *ts) -{ - int ret = 0, fwchksum, binchksum, updcnt = 5; - struct ct365_priv *ct365 = NULL; - - ret = ct365_init_hw(ts); - if(ret < 0) - return ret; - - /* Hardware reset */ - ct365_reset_hw(ts); - // Get binary Checksum - binchksum = ct36x_chip_get_binchksum(); - ct36x_dbg(ts, "CT365 init: binchksum = %d\n", binchksum); - - ret = ct36x_chip_get_fwchksum(ts); - if(ret < 0){ - dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n"); - return ret; - } - fwchksum = ret; - ct36x_dbg(ts, "CT365 init: fwchksum = %d\n", fwchksum); - - while(binchksum != fwchksum && updcnt--) { - /* Update Firmware */ - ret = ct36x_chip_go_bootloader(ts); - if(ret < 0){ - dev_err(ts->dev, "CT36X chip: Failed to go bootloader\n"); - return ret; - } - /* Hardware reset */ - ct365_reset_hw(ts); - - ret = ct36x_chip_get_fwchksum(ts); - if(ret < 0){ - dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n"); - return ret; - } - fwchksum = ret; - ct36x_dbg(ts, "CT365 update FW: fwchksum = %d\n", fwchksum); - } - if(binchksum != fwchksum){ - dev_err(ts->dev, "Fail to update FW\n"); - return -ENODEV; - } - - /* Hardware reset */ - ct365_reset_hw(ts); - - ret = ct36x_chip_set_idle(ts); - if(ret < 0){ - dev_err(ts->dev, "CT365 init: Failed to set idle\n"); - return ret; - } - - msleep(5); - - ts->point_num = CT365_POINT_NUM; - - ct365 = kzalloc(sizeof(struct ct365_priv), GFP_KERNEL); - if(!ct365){ - dev_err(ts->dev, "No memory for ct36x"); - return -ENOMEM; - } - - return 0; -} - -static void ct365_deinit(struct ct36x_data *ts) -{ - struct ct365_priv *ct365 = ts->priv; - - ct365_deinit_hw(ts); - kfree(ct365); - ts->priv = NULL; - - return; -} - -static int ct365_suspend(struct ct36x_data *ts) -{ - int ret = 0; - char buf[3]; - - buf[0] = 0xFF; - buf[1] = 0x8F; - buf[2] = 0xFF; - ret = ct36x_write(ts, buf, 3); - if(ret < 0) - dev_warn(ts->dev, "CT365 suspend: i2c write(0xff, 0x8f, 0xff) error\n"); - msleep(3); - - buf[0] = 0x00; - buf[1] = 0xAF; - ret = ct36x_write(ts, buf, 2); - if(ret < 0) - dev_warn(ts->dev, "CT365 suspend: i2c write(0x00, 0xaf) error\n"); - msleep(3); - - return ret; -} - -static int ct365_resume(struct ct36x_data *ts) -{ - int i, ret = 0; - char buf[2]; - - /* Hardware reset */ - ct365_reset_hw(ts); - - buf[0] = 0x00; - buf[1] = 0x5A; - ret = ct36x_update_write(ts, 0x7F, buf, 2); - if(ret < 0) - dev_warn(ts->dev, "CT365 resume: i2c update write(0x00, 0xaf) error\n"); - msleep(3); - - for(i = 0; i < ts->point_num; i++){ - input_mt_slot(ts->input, i); - input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); - } - input_sync(ts->input); - - return 0; -} - -static void ct365_report(struct ct36x_data *ts) -{ - int i, ret = 0; - int sync = 0, x, y; - int len = sizeof(struct ct365_finger_data) * ts->point_num; - struct ct365_priv *ct365 = ts->priv; - - ret = ct36x_read(ts, ct365->buf, len); - if(ret < 0){ - dev_warn(ts->dev, "Failed to read finger data\n"); - return; - } - - ct36x_dbg(ts, "Read fingers data:\n"); - - ct365->press = 0; - for(i = 0; i < ts->point_num; i++){ - ct36x_dbg(ts, "pst[%d]: id: %d, status: %d, area: %d, pressure: %d\n" - "xhi: %d, xlo:%d, yhi: %d, ylo: %d\n", - i, ct365->pts[i].id, ct365->pts[i].status, ct365->pts[i].area, ct365->pts[i].pressure, - ct365->pts[i].xhi, ct365->pts[i].ylo, ct365->pts[i].yhi, ct365->pts[i].ylo); - - if((ct365->pts[i].xhi != 0xFF && ct365->pts[i].yhi != 0xFF) && - (ct365->pts[i].status == 1 || ct365->pts[i].status == 2)){ - x = (ct365->pts[i].xhi<<4)|(ct365->pts[i].xlo&0xF); - y = (ct365->pts[i].yhi<<4)|(ct365->pts[i].ylo&0xF); - ct365->x = ts->orientation[0] * x + ts->orientation[1] * y; - ct365->y = ts->orientation[2] * x + ts->orientation[3] * y; - if(ct365->x < 0) - ct365->x = ts->x_max - ct365->x; - if(ct365->y < 0) - ct365->y = ts->y_max - ct365->y; - - input_mt_slot(ts->input, ct365->pts[i].id - 1); - input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); - input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 1); - input_report_abs(ts->input, ABS_MT_POSITION_X, x); - input_report_abs(ts->input, ABS_MT_POSITION_Y, y); - input_report_abs(ts->input, ABS_MT_PRESSURE, ct365->pts[i].pressure); - - sync = 1; - ct365->press |= 0x01 << (ct365->pts[i].id - 1); - } - } - ct365->release &= ct365->release ^ ct365->press; - for(i = 0; i < ts->point_num; i++){ - if ( ct365->release & (0x01<input, i); - input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); - sync = 1; - } - } - ct365->release = ct365->press; - - if(sync) - input_sync(ts->input); - - return; -} -struct ct36x_ops ct365_ops = { - .init = ct365_init, - .deinit = ct365_deinit, - .suspend = ct365_suspend, - .resume = ct365_resume, - .report = ct365_report, -}; diff --git a/drivers/input/touchscreen/ct36x/ct36x_priv.h b/drivers/input/touchscreen/ct36x/ct36x_priv.h index 5640eb36fa2f..4f4cd8b95107 100644 --- a/drivers/input/touchscreen/ct36x/ct36x_priv.h +++ b/drivers/input/touchscreen/ct36x/ct36x_priv.h @@ -22,14 +22,14 @@ #include #include -#if 1 +#if 0 #define ct36x_dbg(ts, format, arg...) \ dev_printk(KERN_INFO , ts->dev , format , ## arg) #else #define ct36x_dbg(ts, format, arg...) #endif -#define CT36X_I2C_RATE (100 * 1000) +#define CT36X_I2C_RATE (200 * 1000) struct ct36x_data; struct ct36x_ops{ @@ -96,6 +96,7 @@ static inline int ct36x_update_write(struct ct36x_data *ts, unsigned short addr, return ret; } int ct36x_chip_set_idle(struct ct36x_data *ts); +int ct36x_chip_go_sleep(struct ct36x_data *ts); int ct36x_chip_get_binchksum(void); int ct36x_chip_get_fwchksum(struct ct36x_data *ts); int ct36x_chip_go_bootloader(struct ct36x_data *ts); diff --git a/drivers/input/touchscreen/ct36x/ct36x_ts.c b/drivers/input/touchscreen/ct36x/ct36x_ts.c index b57eda4db4d3..752370fbc51f 100644 --- a/drivers/input/touchscreen/ct36x/ct36x_ts.c +++ b/drivers/input/touchscreen/ct36x/ct36x_ts.c @@ -2,13 +2,13 @@ #include "core.c" #include "ct360.c" -#include "ct365.c" +#include "ct363.c" int inline ct36x_set_ops(struct ct36x_data *ts, int model) { switch(model){ case 360: ts->ops = &ct360_ops; break; - case 365: ts->ops = &ct365_ops; break; + case 363: ts->ops = &ct363_ops; break; default: return -EINVAL; }; @@ -40,8 +40,13 @@ module_param(irq, int, 0644); static int rst = -1; module_param(rst, int, 0644); +static int orientation[4] = {1, 0, 1, 0}; +module_param_array(orientation, int, NULL, 0644); + static int ct36x_check_param(void) { + int i; + if(en != 1) return -EINVAL; if(model < 0) @@ -52,6 +57,10 @@ static int ct36x_check_param(void) return -EINVAL; if(x_max <= 0 || y_max <= 0) return -EINVAL; + for(i = 0; i < 4; i++){ + if(orientation[i] != 0 && orientation[i] != 1 && orientation[i] != -1) + return -EINVAL; + } return 0; } @@ -66,12 +75,15 @@ static struct i2c_board_info __initdata ct36x_info = { static int ct36x_add_client(void) { + int i; struct port_config ct36x_rst, ct36x_irq; ct36x_pdata.model = model; ct36x_pdata.x_max = x_max; ct36x_pdata.y_max = y_max; + for(i = 0; i < 4; i++) + ct36x_pdata.orientation = orientation[i]; ct36x_rst = get_port_config(rst); ct36x_pdata.rst_io.gpio = ct36x_rst.gpio; ct36x_pdata.rst_io.active_low = ct36x_rst.io.active_low; @@ -86,15 +98,15 @@ static int ct36x_add_client(void) } #endif -static irqreturn_t ct36x_irq(int irq, void *data) +static irqreturn_t ct36x_irq_handler(int irq, void *data) { struct ct36x_data *ts = data; - disable_irq_nosync(ts->irq); + //disable_irq(ts->irq); if(ts->ops->report) ts->ops->report(ts); - enable_irq(ts->irq); + //enable_irq(ts->irq); return IRQ_HANDLED; } @@ -204,7 +216,7 @@ static int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id register_early_suspend(&ts->early_suspend); #endif ts->irq = gpio_to_irq(ts->irq_io.gpio); - ret = request_threaded_irq(ts->irq, NULL, ct36x_irq, IRQF_ONESHOT, CT36X_NAME, ts); + ret = request_threaded_irq(ts->irq, NULL, ct36x_irq_handler, IRQF_ONESHOT, CT36X_NAME, ts); if(ret < 0){ dev_err(ts->dev, "Failed to request threaded irq\n"); goto err_request_threaded_irq; -- 2.34.1