1 /* 2 * Driver for cypress touch screen controller 3 * 4 * Copyright (c) 2009 Aava Mobile 5 * 6 * Some cleanups by Alan Cox <alan@linux.intel.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 #include <linux/module.h> 23 #include <linux/kernel.h> 24 #include <linux/input.h> 25 #include <linux/slab.h> 26 #include <linux/interrupt.h> 27 #include <linux/io.h> 28 #include <linux/i2c.h> 29 #include <linux/gpio.h> 30 #include <linux/input/cy8ctmg110_pdata.h> 31 32 #define CY8CTMG110_DRIVER_NAME "cy8ctmg110" 33 34 /* Touch coordinates */ 35 #define CY8CTMG110_X_MIN 0 36 #define CY8CTMG110_Y_MIN 0 37 #define CY8CTMG110_X_MAX 759 38 #define CY8CTMG110_Y_MAX 465 39 40 41 /* cy8ctmg110 register definitions */ 42 #define CY8CTMG110_TOUCH_WAKEUP_TIME 0 43 #define CY8CTMG110_TOUCH_SLEEP_TIME 2 44 #define CY8CTMG110_TOUCH_X1 3 45 #define CY8CTMG110_TOUCH_Y1 5 46 #define CY8CTMG110_TOUCH_X2 7 47 #define CY8CTMG110_TOUCH_Y2 9 48 #define CY8CTMG110_FINGERS 11 49 #define CY8CTMG110_GESTURE 12 50 #define CY8CTMG110_REG_MAX 13 51 52 53 /* 54 * The touch driver structure. 55 */ 56 struct cy8ctmg110 { 57 struct input_dev *input; 58 char phys[32]; 59 struct i2c_client *client; 60 int reset_pin; 61 int irq_pin; 62 }; 63 64 /* 65 * cy8ctmg110_power is the routine that is called when touch hardware 66 * will powered off or on. 67 */ 68 static void cy8ctmg110_power(struct cy8ctmg110 *ts, bool poweron) 69 { 70 if (ts->reset_pin) 71 gpio_direction_output(ts->reset_pin, 1 - poweron); 72 } 73 74 static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg, 75 unsigned char len, unsigned char *value) 76 { 77 struct i2c_client *client = tsc->client; 78 int ret; 79 unsigned char i2c_data[6]; 80 81 BUG_ON(len > 5); 82 83 i2c_data[0] = reg; 84 memcpy(i2c_data + 1, value, len); 85 86 ret = i2c_master_send(client, i2c_data, len + 1); 87 if (ret != len + 1) { 88 dev_err(&client->dev, "i2c write data cmd failed\n"); 89 return ret < 0 ? ret : -EIO; 90 } 91 92 return 0; 93 } 94 95 static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc, 96 unsigned char *data, unsigned char len, unsigned char cmd) 97 { 98 struct i2c_client *client = tsc->client; 99 int ret; 100 struct i2c_msg msg[2] = { 101 /* first write slave position to i2c devices */ 102 { client->addr, 0, 1, &cmd }, 103 /* Second read data from position */ 104 { client->addr, I2C_M_RD, len, data } 105 }; 106 107 ret = i2c_transfer(client->adapter, msg, 2); 108 if (ret < 0) 109 return ret; 110 111 return 0; 112 } 113 114 static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc) 115 { 116 struct input_dev *input = tsc->input; 117 unsigned char reg_p[CY8CTMG110_REG_MAX]; 118 int x, y; 119 120 memset(reg_p, 0, CY8CTMG110_REG_MAX); 121 122 /* Reading coordinates */ 123 if (cy8ctmg110_read_regs(tsc, reg_p, 9, CY8CTMG110_TOUCH_X1) != 0) 124 return -EIO; 125 126 y = reg_p[2] << 8 | reg_p[3]; 127 x = reg_p[0] << 8 | reg_p[1]; 128 129 /* Number of touch */ 130 if (reg_p[8] == 0) { 131 input_report_key(input, BTN_TOUCH, 0); 132 } else { 133 input_report_key(input, BTN_TOUCH, 1); 134 input_report_abs(input, ABS_X, x); 135 input_report_abs(input, ABS_Y, y); 136 } 137 138 input_sync(input); 139 140 return 0; 141 } 142 143 static int cy8ctmg110_set_sleepmode(struct cy8ctmg110 *ts, bool sleep) 144 { 145 unsigned char reg_p[3]; 146 147 if (sleep) { 148 reg_p[0] = 0x00; 149 reg_p[1] = 0xff; 150 reg_p[2] = 5; 151 } else { 152 reg_p[0] = 0x10; 153 reg_p[1] = 0xff; 154 reg_p[2] = 0; 155 } 156 157 return cy8ctmg110_write_regs(ts, CY8CTMG110_TOUCH_WAKEUP_TIME, 3, reg_p); 158 } 159 160 static irqreturn_t cy8ctmg110_irq_thread(int irq, void *dev_id) 161 { 162 struct cy8ctmg110 *tsc = dev_id; 163 164 cy8ctmg110_touch_pos(tsc); 165 166 return IRQ_HANDLED; 167 } 168 169 static int __devinit cy8ctmg110_probe(struct i2c_client *client, 170 const struct i2c_device_id *id) 171 { 172 const struct cy8ctmg110_pdata *pdata = client->dev.platform_data; 173 struct cy8ctmg110 *ts; 174 struct input_dev *input_dev; 175 int err; 176 177 /* No pdata no way forward */ 178 if (pdata == NULL) { 179 dev_err(&client->dev, "no pdata\n"); 180 return -ENODEV; 181 } 182 183 if (!i2c_check_functionality(client->adapter, 184 I2C_FUNC_SMBUS_READ_WORD_DATA)) 185 return -EIO; 186 187 ts = kzalloc(sizeof(struct cy8ctmg110), GFP_KERNEL); 188 input_dev = input_allocate_device(); 189 if (!ts || !input_dev) { 190 err = -ENOMEM; 191 goto err_free_mem; 192 } 193 194 ts->client = client; 195 ts->input = input_dev; 196 ts->reset_pin = pdata->reset_pin; 197 ts->irq_pin = pdata->irq_pin; 198 199 snprintf(ts->phys, sizeof(ts->phys), 200 "%s/input0", dev_name(&client->dev)); 201 202 input_dev->name = CY8CTMG110_DRIVER_NAME " Touchscreen"; 203 input_dev->phys = ts->phys; 204 input_dev->id.bustype = BUS_I2C; 205 input_dev->dev.parent = &client->dev; 206 207 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 208 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 209 210 input_set_abs_params(input_dev, ABS_X, 211 CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0); 212 input_set_abs_params(input_dev, ABS_Y, 213 CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0); 214 215 if (ts->reset_pin) { 216 err = gpio_request(ts->reset_pin, NULL); 217 if (err) { 218 dev_err(&client->dev, 219 "Unable to request GPIO pin %d.\n", 220 ts->reset_pin); 221 goto err_free_mem; 222 } 223 } 224 225 cy8ctmg110_power(ts, true); 226 cy8ctmg110_set_sleepmode(ts, false); 227 228 err = gpio_request(ts->irq_pin, "touch_irq_key"); 229 if (err < 0) { 230 dev_err(&client->dev, 231 "Failed to request GPIO %d, error %d\n", 232 ts->irq_pin, err); 233 goto err_shutoff_device; 234 } 235 236 err = gpio_direction_input(ts->irq_pin); 237 if (err < 0) { 238 dev_err(&client->dev, 239 "Failed to configure input direction for GPIO %d, error %d\n", 240 ts->irq_pin, err); 241 goto err_free_irq_gpio; 242 } 243 244 client->irq = gpio_to_irq(ts->irq_pin); 245 if (client->irq < 0) { 246 err = client->irq; 247 dev_err(&client->dev, 248 "Unable to get irq number for GPIO %d, error %d\n", 249 ts->irq_pin, err); 250 goto err_free_irq_gpio; 251 } 252 253 err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread, 254 IRQF_TRIGGER_RISING | IRQF_ONESHOT, 255 "touch_reset_key", ts); 256 if (err < 0) { 257 dev_err(&client->dev, 258 "irq %d busy? error %d\n", client->irq, err); 259 goto err_free_irq_gpio; 260 } 261 262 err = input_register_device(input_dev); 263 if (err) 264 goto err_free_irq; 265 266 i2c_set_clientdata(client, ts); 267 device_init_wakeup(&client->dev, 1); 268 return 0; 269 270 err_free_irq: 271 free_irq(client->irq, ts); 272 err_free_irq_gpio: 273 gpio_free(ts->irq_pin); 274 err_shutoff_device: 275 cy8ctmg110_set_sleepmode(ts, true); 276 cy8ctmg110_power(ts, false); 277 if (ts->reset_pin) 278 gpio_free(ts->reset_pin); 279 err_free_mem: 280 input_free_device(input_dev); 281 kfree(ts); 282 return err; 283 } 284 285 #ifdef CONFIG_PM 286 static int cy8ctmg110_suspend(struct device *dev) 287 { 288 struct i2c_client *client = to_i2c_client(dev); 289 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 290 291 if (device_may_wakeup(&client->dev)) 292 enable_irq_wake(client->irq); 293 else { 294 cy8ctmg110_set_sleepmode(ts, true); 295 cy8ctmg110_power(ts, false); 296 } 297 return 0; 298 } 299 300 static int cy8ctmg110_resume(struct device *dev) 301 { 302 struct i2c_client *client = to_i2c_client(dev); 303 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 304 305 if (device_may_wakeup(&client->dev)) 306 disable_irq_wake(client->irq); 307 else { 308 cy8ctmg110_power(ts, true); 309 cy8ctmg110_set_sleepmode(ts, false); 310 } 311 return 0; 312 } 313 314 static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); 315 #endif 316 317 static int __devexit cy8ctmg110_remove(struct i2c_client *client) 318 { 319 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 320 321 cy8ctmg110_set_sleepmode(ts, true); 322 cy8ctmg110_power(ts, false); 323 324 free_irq(client->irq, ts); 325 input_unregister_device(ts->input); 326 gpio_free(ts->irq_pin); 327 if (ts->reset_pin) 328 gpio_free(ts->reset_pin); 329 kfree(ts); 330 331 return 0; 332 } 333 334 static const struct i2c_device_id cy8ctmg110_idtable[] = { 335 { CY8CTMG110_DRIVER_NAME, 1 }, 336 { } 337 }; 338 339 MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable); 340 341 static struct i2c_driver cy8ctmg110_driver = { 342 .driver = { 343 .owner = THIS_MODULE, 344 .name = CY8CTMG110_DRIVER_NAME, 345 #ifdef CONFIG_PM 346 .pm = &cy8ctmg110_pm, 347 #endif 348 }, 349 .id_table = cy8ctmg110_idtable, 350 .probe = cy8ctmg110_probe, 351 .remove = __devexit_p(cy8ctmg110_remove), 352 }; 353 354 module_i2c_driver(cy8ctmg110_driver); 355 356 MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>"); 357 MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver"); 358 MODULE_LICENSE("GPL v2"); 359