diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-cypress-touch-driver.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-cypress-touch-driver.patch | 870 |
1 files changed, 0 insertions, 870 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-cypress-touch-driver.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-cypress-touch-driver.patch deleted file mode 100644 index 2dae9ed82..000000000 --- a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-cypress-touch-driver.patch +++ /dev/null @@ -1,870 +0,0 @@ -From 03e11a278286392dc20de57a24cadbc16d9aac3a Mon Sep 17 00:00:00 2001 -From: Priya Vijayan <priya.vijayan@intel.com> -Date: Tue, 27 Apr 2010 11:23:00 -0700 -Subject: [PATCH] Touchscreen driver for Cypress panels - -This driver is from aava - -Signed-off-by: Priya Vijayan <priya.vijayan@intel.com> ---- - drivers/input/touchscreen/Kconfig | 8 + - drivers/input/touchscreen/Makefile | 1 + - drivers/input/touchscreen/cy8ctmg110_ts.c | 815 +++++++++++++++++++++++++++++ - 3 files changed, 824 insertions(+), 0 deletions(-) - create mode 100644 drivers/input/touchscreen/cy8ctmg110_ts.c - -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 6dd2674..5ecf00d 100644 ---- a/drivers/input/touchscreen/Kconfig -+++ b/drivers/input/touchscreen/Kconfig -@@ -103,6 +103,14 @@ config TOUCHSCREEN_CORGI - NOTE: this driver is deprecated, try enable SPI and generic - ADS7846-based touchscreen driver. - -+config TOUCHSCREEN_CY8CTMG110 -+ tristate "cy8ctmg110 touchscreen" -+ depends on I2C -+ default y -+ help -+ Say Y here if you have a cy8ctmg110 touchscreen capasitive touchscreen -+ If unsure, say N. -+ - config TOUCHSCREEN_DA9034 - tristate "Touchscreen support for Dialog Semiconductor DA9034" - depends on PMIC_DA903X -diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index 15ad257..e5b5fae 100644 ---- a/drivers/input/touchscreen/Makefile -+++ b/drivers/input/touchscreen/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o - obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o - obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o - obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o -+obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o - obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o - obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o - obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o -diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c -new file mode 100644 -index 0000000..5587385 ---- /dev/null -+++ b/drivers/input/touchscreen/cy8ctmg110_ts.c -@@ -0,0 +1,815 @@ -+/* -+ * cy8ctmg110_ts.c Driver for cypress touch screen controller -+ * Copyright (c) 2009 Aava Mobile -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/input.h> -+#include <linux/interrupt.h> -+#include <asm/io.h> -+#include <linux/i2c.h> -+#include <linux/timer.h> -+#include <linux/gpio.h> -+#include <linux/hrtimer.h> -+ -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/fs.h> -+#include <asm/ioctl.h> -+#include <asm/ipc_defs.h> -+#include <asm/uaccess.h> -+#include <linux/device.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/fs.h> -+#include <asm/ioctl.h> -+#include <linux/fs.h> -+#include <linux/init.h> -+#include <linux/miscdevice.h> -+#include <linux/module.h> -+ -+ -+#define CY8CTMG110_DRIVER_NAME "cy8ctmg110" -+#define CY8CTMG110_DRIVER_NAME_EXT "cy8ctmg110 ext" -+/*#define MOORESTOWN_CDK*/ -+/*#define CY8CTMG110_DEBUG_INFO*/ -+/*#define POLL_TOUCH_EVENTS*/ -+ -+ -+ -+/*HW definations*/ -+ -+/*Main touch specific*/ -+#define CY8CTMG110_I2C_ADDR 0x38 -+#define CY8CTMG110_RESET_PIN_GPIO 43 -+#define CY8CTMG110_IRQ_PIN_GPIO 59 -+ -+/*Extended specific*/ -+#define CY8CTMG110_I2C_ADDR_EXT 0x39 -+#define CY8CTMG110_RESET_PIN_GPIO_EXT 39 -+#define CY8CTMG110_IRQ_PIN_GPIO_EXT 31 -+ -+ -+#define CY8CTMG110_TOUCH_LENGHT 9787 -+#define CY8CTMG110_SCREEN_LENGHT 8424 -+ -+ -+/*Main Touch coordinates*/ -+#define CY8CTMG110_X_MIN 0 -+#define CY8CTMG110_Y_MIN 0 -+#define CY8CTMG110_X_MAX 864 -+#define CY8CTMG110_Y_MAX 480 -+ -+ -+/*cy8ctmg110 registers defination*/ -+#define CY8CTMG110_TOUCH_WAKEUP_TIME 0 -+#define CY8CTMG110_TOUCH_SLEEP_TIME 2 -+#define CY8CTMG110_TOUCH_X1 3 -+#define CY8CTMG110_TOUCH_Y1 5 -+#define CY8CTMG110_TOUCH_X2 7 -+#define CY8CTMG110_TOUCH_Y2 9 -+#define CY8CTMG110_FINGERS 11 -+#define CY8CTMG110_GESTURE 12 -+#define CY8CTMG110_VERSIONID 13 //not supported in touchpanel FW -+#define CY8CTMG110_REG_MAX 13 -+ -+#ifdef POLL_TOUCH_EVENTS -+ #define CY8CTMG110_POLL_TIMER_DELAY 1000*1000*100 -+ #define TOUCH_MAX_I2C_FAILS 50 -+#endif -+ -+#define CY8CTMG110_POLL_TIMER_DELAY 1000*1000*100 -+ -+/* Scale factors for coordinates */ -+#define X_SCALE_FACTOR 9387/8424 -+#define Y_SCALE_FACTOR 97/100 -+ -+/* For tracing */ -+static u16 g_y_trace_coord = 0; -+ -+/*if soutcanyon*/ -+static bool isSc = false; -+ -+ -+/* -+ * Touchtype -+ */ -+enum touch_type { -+ TOUCH_KOSKI=1, -+ TOUCH_SC, -+ TOUCH_EXT, -+}; -+ -+/* -+ * The touch position structure. -+ */ -+struct ts_event { -+ int x1; -+ int y1; -+ int x2; -+ int y2; -+ bool event_sended; -+}; -+ -+/* -+ * The touch driver structure. -+ */ -+struct cy8ctmg110 { -+ struct input_dev *input; -+ char phys[32]; -+ struct ts_event tc; -+ struct i2c_client *client; -+ bool pending; -+ spinlock_t lock; -+ bool initController; -+ bool sleepmode; -+ int irq_gpio; -+ int reset_gpio; -+ char driver_name[20]; -+ struct delayed_work work; -+ enum touch_type version_id; -+#ifdef POLL_TOUCH_EVENTS -+ struct hrtimer timer; -+ int i2c_fail_count; -+#endif -+}; -+ -+/* -+ * cy8ctmg110_poweroff is the routine that is called when touch hardware -+ * will powered off -+ */ -+static void cy8ctmg110_power(struct cy8ctmg110 *ts,bool poweron) -+{ -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("%s power:%d\n",ts->driver_name,poweron); -+#endif -+ if (poweron) -+ gpio_direction_output(ts->reset_gpio, 0); -+ else -+ gpio_direction_output(ts->reset_gpio, 1); -+} -+/* -+ * cy8ctmg110_write_req write regs to the i2c devices -+ * -+ */ -+static int cy8ctmg110_write_req(struct cy8ctmg110 *tsc,unsigned char reg,unsigned char len,unsigned char *value) -+{ -+ struct i2c_client *client = tsc->client; -+ unsigned int ret; -+ unsigned char i2c_data[]={0,0,0,0,0,0}; -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("cy8ctmg110_init_req:\n"); -+#endif -+ -+ i2c_data[0]=reg; -+ memcpy(i2c_data+1,value,len); -+ -+ { -+ struct i2c_msg msg[] = { -+ { client->addr, 0, len+1, i2c_data }, -+ }; -+ -+ ret = i2c_transfer(client->adapter, msg, 1); -+ -+ if (ret != 1) { -+ printk("cy8ctmg110 touch : i2c write data cmd failed \n"); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+/* -+ * get_time -+ * -+ */ -+#ifdef CY8CTMG110_DEBUG_INFO -+static inline long cy8ctmg110_get_time(void) -+{ -+ struct timeval t; -+ do_gettimeofday(&t); -+ return t.tv_usec; -+} -+#endif -+/* -+ * cy8ctmg110_read_req read regs from i2c devise -+ * -+ */ -+static int cy8ctmg110_read_req(struct cy8ctmg110 *tsc,unsigned char *i2c_data,unsigned char len ,unsigned char cmd) -+{ -+ struct i2c_client *client = tsc->client; -+ unsigned int ret; -+ unsigned char regs_cmd[2]={0,0}; -+#ifdef CY8CTMG110_DEBUG_INFO -+ long starttime = cy8ctmg110_get_time(); -+#endif -+ regs_cmd[0]=cmd; -+ -+ -+ /* first write slave position to i2c devices*/ -+ { -+ struct i2c_msg msg1[] = { -+ { client->addr, 0, 1, regs_cmd }, -+ }; -+ -+ ret = i2c_transfer(client->adapter, msg1, 1); -+ -+ if (ret != 1) { -+#ifdef POLL_TOUCH_EVENTS -+ tsc->i2c_fail_count++; -+#endif -+ return ret; -+ } -+ } -+ -+ -+ /* Second read data from position*/ -+ { -+ struct i2c_msg msg2[] = { -+ { client->addr, I2C_M_RD, len, i2c_data }, -+ }; -+ -+ ret = i2c_transfer(client->adapter, msg2, 1); -+ -+ -+ if (ret != 1) { -+#ifdef POLL_TOUCH_EVENTS -+ tsc->i2c_fail_count++; -+#endif -+ return ret; -+ } -+ } -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("%s time to get data bytes read:%d time:%d\n",tsc->driver_name,len,(cy8ctmg110_get_time()-starttime)); -+#endif -+ return 0; -+} -+/* -+ * cy8ctmg110_send_event delevery touch event to the userpace -+ * function use normal input interface -+ */ -+static void cy8ctmg110_send_event(void *tsc,int x,int y) -+{ -+ struct cy8ctmg110 *ts = tsc; -+ struct input_dev *input = ts->input; -+ u16 x2, y2; -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("cy8ctmg110_send_event\n"); -+#endif -+ -+ if(ts->tc.event_sended == false){ -+ -+ if (ts->client->addr==CY8CTMG110_I2C_ADDR_EXT){ -+ /*Extended touchpanel*/ -+ input_report_key(input, BTN_TOUCH, 1); -+ -+ -+ if ( ts->pending == true){ -+ input_report_rel(input, REL_Y, (ts->tc.x1-x)*2); -+ input_report_rel(input, REL_X, (y - ts->tc.y1)*3); -+ ts->tc.y1 = y; -+ ts->tc.x1 = x; -+ } -+ else{ -+ ts->pending = true; -+ ts->tc.y1 = y; -+ ts->tc.x1 = x; -+ } -+ -+ -+ } -+ else{ -+ /*Main touchpanel*/ -+ ts->tc.y1 = y; -+ ts->tc.x1 = x; -+ ts->pending = true; -+ input_report_key(input, BTN_TOUCH, 1); -+ -+ x2 = y; -+ y2 = x; -+ -+ if (isSc == false){ -+ /*Main touchpanel in koski*/ -+ x2 = (u16)(y*X_SCALE_FACTOR); -+ y2 = (u16)(x*Y_SCALE_FACTOR); -+ } -+ -+ input_report_abs(input, ABS_X, x2); -+ input_report_abs(input, ABS_Y, y2); -+ } -+ -+ input_sync(input); -+ if(g_y_trace_coord) -+ printk("%s touch position X:%d (was = %d) Y:%d (was = %d)\n",ts->driver_name, x2, y, y2, x); -+ } -+ -+} -+ -+/* -+ * cy8ctmg110_touch_pos check touch position from i2c devices -+ * -+ */ -+static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc) -+{ -+ unsigned char reg_p[CY8CTMG110_REG_MAX]; -+ -+ memset(reg_p,0,CY8CTMG110_REG_MAX); -+ -+ /*Reading coordinates*/ -+ if (cy8ctmg110_read_req(tsc,reg_p,1,CY8CTMG110_FINGERS)==0){ -+ -+ /*number of touch*/ -+ if (reg_p[0]==0){ -+ if (tsc->pending == true){ -+ struct input_dev *input = tsc->input; -+ -+ input_report_key(input, BTN_TOUCH, 0); -+ -+ input_sync(input); -+ tsc->tc.event_sended = true; -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("cy8ctmg110_send_event ts->pending = true;\n"); -+#endif -+ tsc->pending = false; -+ } -+ } -+ else { -+ -+ if (cy8ctmg110_read_req(tsc,reg_p,4,CY8CTMG110_TOUCH_X1)==0){ -+ int x = 0,y = 0; -+ y = reg_p[2]<<8 | reg_p[3]; -+ x = reg_p[0]<<8 | reg_p[1]; -+ -+ if (tsc->tc.x1 != x || tsc->tc.y1 != y){ -+ tsc->tc.event_sended = false; -+ cy8ctmg110_send_event(tsc,x,y); -+ } -+ } -+ } -+ } -+ else{ -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("cy8ctmg110 i2c reading error\n"); -+#endif -+ } -+ -+ return 0; -+} -+/* -+ * cy8ctmg110_read_versionid delevery touch event to the userpace -+ * function use normal input interface -+ */ -+static void cy8ctmg110_read_versionid(void *tsc) -+{ -+ struct cy8ctmg110 *ts = tsc; -+ unsigned char reg_p[2]; -+ -+ -+ if (cy8ctmg110_read_req(ts,reg_p,1,CY8CTMG110_VERSIONID)==0){ -+ printk("%s id 0x%x\n",ts->driver_name,reg_p[0]); -+ -+ /*Ugly hack solution if SC -+ */ -+ -+ if(ts->client->addr==CY8CTMG110_I2C_ADDR_EXT) -+ isSc = true; -+ -+ switch (reg_p[0]){ -+ case 0x01: -+ ts->version_id = TOUCH_EXT; -+ break; -+ case 0x02: -+ ts->version_id = TOUCH_SC; -+ break; -+ case 0x03: -+ ts->version_id = TOUCH_KOSKI; -+ break; -+ default: -+ ts->version_id = TOUCH_KOSKI; -+ break; -+ } -+ } -+} -+ -+ -+#ifdef POLL_TOUCH_EVENTS -+/* -+ * if interup is'n in use the touch positions can reads by polling -+ * -+ */ -+static enum hrtimer_restart cy8ctmg110_timer(struct hrtimer *handle) -+{ -+ struct cy8ctmg110 *ts = container_of(handle, struct cy8ctmg110, timer); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ts->lock, flags); -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("cy8ctmg110_timer\n"); -+#endif -+ -+ cy8ctmg110_touch_pos(ts); -+ -+ if (ts->i2c_fail_count<TOUCH_MAX_I2C_FAILS) -+ hrtimer_start(&ts->timer, ktime_set(0, CY8CTMG110_POLL_TIMER_DELAY), -+ HRTIMER_MODE_REL); -+ -+ spin_unlock_irqrestore(&ts->lock, flags); -+ -+ return HRTIMER_NORESTART; -+} -+#endif -+/* -+ * cy8ctmg110_init_controller set init value to touchcontroller -+ * -+ */ -+static bool cy8ctmg110_set_sleepmode(struct cy8ctmg110 *ts) -+{ -+ unsigned char reg_p[3]; -+ -+ if(ts->sleepmode==true){ -+ reg_p[0] = 0x00; reg_p[1] =0xff; reg_p[2] =5; -+ }else{ -+ reg_p[0] = 0x10;reg_p[1] =0xff;reg_p[2] =0; -+ } -+ -+ if (cy8ctmg110_write_req(ts,CY8CTMG110_TOUCH_WAKEUP_TIME,3,reg_p)){ -+ return false; -+ } -+ ts->initController = true; -+ -+ return true; -+} -+ -+ -+ -+static void cy8ctmg110_work(struct work_struct *work) -+{ -+ struct cy8ctmg110 *ts = -+ container_of(to_delayed_work(work), struct cy8ctmg110, work); -+ -+ cy8ctmg110_touch_pos(ts); -+} -+ -+ -+/* -+ * cy8ctmg110_irq_handler irq handling function -+ * -+ */ -+static irqreturn_t cy8ctmg110_irq_handler(int irq, void *handle) -+{ -+ struct cy8ctmg110 * tsc = (struct cy8ctmg110 *)handle; -+ -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("%s cy8ctmg110_irq_handler\n",tsc->driver_name); -+#endif -+ if (tsc->initController == false){ -+ if (cy8ctmg110_set_sleepmode(tsc) == true) -+ tsc->initController = true; -+ } -+ else -+ { -+ schedule_delayed_work(&tsc->work, -+ msecs_to_jiffies(1)); -+ } -+ -+#ifdef POLL_TOUCH_EVENTS -+ /*if interrupt supported in the touch controller -+ timer polling need to stop*/ -+ tsc->i2c_fail_count = TOUCH_MAX_I2C_FAILS; -+#endif -+ return IRQ_HANDLED; -+} -+ -+ -+static int cy8ctmg110_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct cy8ctmg110 *ts; -+ struct input_dev *input_dev; -+ int err; -+ -+ if (!i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_WORD_DATA)) -+ return -EIO; -+ -+ ts = kzalloc(sizeof(struct cy8ctmg110), GFP_KERNEL); -+ input_dev = input_allocate_device(); -+ -+ if (!ts || !input_dev) { -+ err = -ENOMEM; -+ goto err_free_mem; -+ } -+ -+ ts->client = client; -+ i2c_set_clientdata(client, ts); -+ -+ ts->input = input_dev; -+ ts->pending = false; -+ ts->sleepmode = false; -+ -+ -+ if(client->addr==CY8CTMG110_I2C_ADDR){ -+ ts->reset_gpio = CY8CTMG110_RESET_PIN_GPIO; -+ input_dev->name = CY8CTMG110_DRIVER_NAME" Touchscreen"; -+ snprintf(ts->driver_name, sizeof(ts->driver_name),"%s", CY8CTMG110_DRIVER_NAME); -+ } -+ else if (client->addr==CY8CTMG110_I2C_ADDR_EXT){ -+ ts->reset_gpio = CY8CTMG110_RESET_PIN_GPIO_EXT; -+ input_dev->name = CY8CTMG110_DRIVER_NAME_EXT" Touchscreen"; -+ snprintf(ts->driver_name, sizeof(ts->driver_name),"%s", CY8CTMG110_DRIVER_NAME_EXT); -+ } -+ -+ snprintf(ts->phys, sizeof(ts->phys), -+ "%s/input0", dev_name(&client->dev)); -+ -+ INIT_DELAYED_WORK(&ts->work, cy8ctmg110_work); -+ -+ input_dev->phys = ts->phys; -+ input_dev->id.bustype = BUS_I2C; -+ -+ spin_lock_init(&ts->lock); -+ -+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | -+ BIT_MASK(EV_REL) | BIT_MASK(EV_ABS); -+ -+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); -+ -+ input_set_capability(input_dev, EV_KEY, KEY_F); -+ -+ -+ input_set_abs_params(input_dev, ABS_X, CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 0, 0); -+ input_set_abs_params(input_dev, ABS_Y, CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 0, 0); -+ input_dev->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X)| BIT_MASK(REL_Y); -+ -+ err = gpio_request(ts->reset_gpio, NULL); -+ -+ if (err) { -+ printk("GPIO pin %d failed to request.\n", ts->reset_gpio); -+ goto err_free_thread; -+ } -+ -+ cy8ctmg110_power(ts,true); -+ -+ ts->initController = false; -+#ifdef POLL_TOUCH_EVENTS -+ ts->i2c_fail_count = 0; -+ hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ ts->timer.function = cy8ctmg110_timer; -+ -+ hrtimer_start(&ts->timer, ktime_set(10, 0), -+ HRTIMER_MODE_REL); -+#endif -+ err = gpio_request(client->irq, "touch_irq_key"); -+ -+ if (err < 0) { -+ printk("%s gpio-keys: failed to request GPIO %d," -+ " error %d\n",ts->driver_name,client->irq, err); -+ goto err_free_thread; -+ } -+ -+ err= gpio_direction_input(client->irq); -+ -+ if (err < 0) { -+ pr_err("%s gpio-keys: failed to configure input" -+ " direction for GPIO %d, error %d\n",ts->driver_name,client->irq, err); -+ gpio_free(client->irq); -+ goto err_free_thread; -+ } -+ -+ ts->irq_gpio = gpio_to_irq(client->irq); -+ -+ if (ts->irq_gpio < 0) { -+ err = ts->irq_gpio; -+ pr_err("cy8ctmg110 gpio-keys: Unable to get irq number" -+ " for GPIO %d, error %d\n", -+ ts->irq_gpio, err); -+ gpio_free(ts->irq_gpio); -+ goto err_free_thread; -+ } -+ -+ if (client->addr!=CY8CTMG110_I2C_ADDR_EXT){ -+ err = request_irq(ts->irq_gpio, cy8ctmg110_irq_handler, -+ IRQF_TRIGGER_RISING | IRQF_SHARED, -+ "touch_reset_key", -+ ts); -+ } -+ -+ if (err < 0) { -+ dev_err(&client->dev, "cy8ctmg110 irq %d busy? error %d\n", ts->irq_gpio ,err); -+ goto err_free_thread; -+ } -+ -+ err = input_register_device(input_dev); -+ cy8ctmg110_read_versionid(ts); -+ -+ if (err) -+ goto err_free_irq; -+ -+ return 0; -+ -+ err_free_irq: -+ printk("%s err_free_irq\n",ts->driver_name); -+ free_irq(client->irq, ts); -+ err_free_thread: -+ printk("%s err_free_thread\n",ts->driver_name); -+ err_free_mem: -+ printk("%s err_free_mem\n",ts->driver_name); -+ input_free_device(input_dev); -+ kfree(ts); -+ -+ return err; -+} -+/* -+ * cy8ctmg110_suspend -+ * -+ */ -+static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) -+{ -+ if (device_may_wakeup(&client->dev)) -+ enable_irq_wake(client->irq); -+ -+ return 0; -+} -+/* -+ * cy8ctmg110_resume -+ * -+ */ -+static int cy8ctmg110_resume(struct i2c_client *client) -+{ -+ if (device_may_wakeup(&client->dev)) -+ disable_irq_wake(client->irq); -+ -+ return 0; -+} -+/* -+ * cy8ctmg110_remove -+ * -+ */ -+static int cy8ctmg110_remove(struct i2c_client *client) -+{ -+ struct cy8ctmg110 *ts = i2c_get_clientdata(client); -+ -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("cy8ctmg110_remove\n"); -+#endif -+ -+ cy8ctmg110_power(ts,false); -+#ifdef POLL_TOUCH_EVENTS -+ hrtimer_cancel(&ts->timer); -+#endif -+ -+ free_irq(client->irq, ts); -+ input_unregister_device(ts->input); -+ kfree(ts); -+ -+ return 0; -+} -+ -+static struct i2c_device_id cy8ctmg110_idtable[] = { -+ { CY8CTMG110_DRIVER_NAME, 1 }, -+ { CY8CTMG110_DRIVER_NAME_EXT, 1 }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable); -+ -+static struct i2c_driver cy8ctmg110_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = CY8CTMG110_DRIVER_NAME, -+ .bus = &i2c_bus_type, -+ }, -+ .id_table = cy8ctmg110_idtable, -+ .probe = cy8ctmg110_probe, -+ .remove = cy8ctmg110_remove, -+ .suspend = cy8ctmg110_suspend, -+ .resume = cy8ctmg110_resume, -+}; -+ -+ -+static int __init cy8ctmg110_init(void) -+{ -+ printk("cy8ctmg110_init\n"); -+ -+ return i2c_add_driver(&cy8ctmg110_driver); -+} -+ -+static void __exit cy8ctmg110_exit(void) -+{ -+#ifdef CY8CTMG110_DEBUG_INFO -+ printk("cy8ctmg110_exit\n"); -+#endif -+ i2c_del_driver(&cy8ctmg110_driver); -+} -+ -+module_init(cy8ctmg110_init); -+module_exit(cy8ctmg110_exit); -+ -+ -+struct i2c_board_info __initdata koski_i2c_board_info2[] = { -+ { -+ I2C_BOARD_INFO(CY8CTMG110_DRIVER_NAME, CY8CTMG110_I2C_ADDR), -+ .irq = CY8CTMG110_IRQ_PIN_GPIO -+ }, -+ { -+ I2C_BOARD_INFO(CY8CTMG110_DRIVER_NAME_EXT, CY8CTMG110_I2C_ADDR_EXT), -+ .irq = CY8CTMG110_IRQ_PIN_GPIO_EXT -+ }, -+}; -+ -+ -+static int __init koski_i2c_init(void) -+{ -+ printk("init koski board\n"); -+ -+#ifdef MOORESTOWN_CDK -+ /*init koski i2c*/ -+ i2c_register_board_info(1, koski_i2c_board_info2, -+ ARRAY_SIZE(koski_i2c_board_info2)); -+#else -+ /*init koski i2c*/ -+ i2c_register_board_info(0, koski_i2c_board_info2, -+ ARRAY_SIZE(koski_i2c_board_info2)); -+#endif -+ return 0; -+} -+ -+module_init(koski_i2c_init); -+ -+MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>"); -+MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver"); -+MODULE_LICENSE("GPL v2"); -+ -+ -+// Aava access from sysfs begin -+static ssize_t aava_query_fw_info_func(struct class *class, char *buf) -+{ -+ ssize_t status; -+ int i = 0; -+ unsigned char mrst_fw_ver_info[16]; -+ -+ printk("!!! aava_query_fw_info_func() ENTER\n"); -+ -+ status = mrst_get_firmware_version(mrst_fw_ver_info); -+ for (i = 0; i < 16; i++){ -+ printk("%x\n", mrst_fw_ver_info[i]); -+ buf[i] = mrst_fw_ver_info[i]; -+ } -+ -+ return 16; -+} -+ -+static ssize_t aava_enable_touch_traces_func(struct class *class, \ -+ const char *buf, size_t len) -+{ -+ ssize_t status; -+ unsigned long value; -+ -+ status = strict_strtoul(buf, 0, &value); -+ printk("!!! aava_enable_touch_traces_func() = %d\n", (int)value); -+ -+ g_y_trace_coord = value; -+ -+ return len; -+} -+ -+static struct class_attribute aava_class_attrs[] = { -+ __ATTR(aava_query_fw_info, 0444, aava_query_fw_info_func, NULL), -+ __ATTR(aava_enable_touch_traces, 0200, NULL, aava_enable_touch_traces_func), -+ __ATTR_NULL, -+}; -+ -+static struct class aava_class = { -+ .name = "aava", -+ .owner = THIS_MODULE, -+ -+ .class_attrs = aava_class_attrs, -+}; -+ -+static int __init aava_sysfs_init(void) -+{ -+ int status; -+ -+ status = class_register(&aava_class); -+ if (status < 0) -+ return status; -+ -+ return status; -+} -+postcore_initcall(aava_sysfs_init); -+// Aava access from sysfs end --- -1.6.2.2 - |