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, "touch_reset_key", ts); 255 if (err < 0) { 256 dev_err(&client->dev, 257 "irq %d busy? error %d\n", client->irq, err); 258 goto err_free_irq_gpio; 259 } 260 261 err = input_register_device(input_dev); 262 if (err) 263 goto err_free_irq; 264 265 i2c_set_clientdata(client, ts); 266 device_init_wakeup(&client->dev, 1); 267 return 0; 268 269 err_free_irq: 270 free_irq(client->irq, ts); 271 err_free_irq_gpio: 272 gpio_free(ts->irq_pin); 273 err_shutoff_device: 274 cy8ctmg110_set_sleepmode(ts, true); 275 cy8ctmg110_power(ts, false); 276 if (ts->reset_pin) 277 gpio_free(ts->reset_pin); 278 err_free_mem: 279 input_free_device(input_dev); 280 kfree(ts); 281 return err; 282 } 283 284 #ifdef CONFIG_PM 285 static int cy8ctmg110_suspend(struct device *dev) 286 { 287 struct i2c_client *client = to_i2c_client(dev); 288 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 289 290 if (device_may_wakeup(&client->dev)) 291 enable_irq_wake(client->irq); 292 else { 293 cy8ctmg110_set_sleepmode(ts, true); 294 cy8ctmg110_power(ts, false); 295 } 296 return 0; 297 } 298 299 static int cy8ctmg110_resume(struct device *dev) 300 { 301 struct i2c_client *client = to_i2c_client(dev); 302 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 303 304 if (device_may_wakeup(&client->dev)) 305 disable_irq_wake(client->irq); 306 else { 307 cy8ctmg110_power(ts, true); 308 cy8ctmg110_set_sleepmode(ts, false); 309 } 310 return 0; 311 } 312 313 static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); 314 #endif 315 316 static int __devexit cy8ctmg110_remove(struct i2c_client *client) 317 { 318 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 319 320 cy8ctmg110_set_sleepmode(ts, true); 321 cy8ctmg110_power(ts, false); 322 323 free_irq(client->irq, ts); 324 input_unregister_device(ts->input); 325 gpio_free(ts->irq_pin); 326 if (ts->reset_pin) 327 gpio_free(ts->reset_pin); 328 kfree(ts); 329 330 return 0; 331 } 332 333 static const struct i2c_device_id cy8ctmg110_idtable[] = { 334 { CY8CTMG110_DRIVER_NAME, 1 }, 335 { } 336 }; 337 338 MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable); 339 340 static struct i2c_driver cy8ctmg110_driver = { 341 .driver = { 342 .owner = THIS_MODULE, 343 .name = CY8CTMG110_DRIVER_NAME, 344 #ifdef CONFIG_PM 345 .pm = &cy8ctmg110_pm, 346 #endif 347 }, 348 .id_table = cy8ctmg110_idtable, 349 .probe = cy8ctmg110_probe, 350 .remove = __devexit_p(cy8ctmg110_remove), 351 }; 352 353 module_i2c_driver(cy8ctmg110_driver); 354 355 MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>"); 356 MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver"); 357 MODULE_LICENSE("GPL v2"); 358