1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Touch Screen driver for Renesas MIGO-R Platform 4 * 5 * Copyright (c) 2008 Magnus Damm 6 * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>, 7 * Kenati Technologies Pvt Ltd. 8 */ 9 #include <linux/module.h> 10 #include <linux/kernel.h> 11 #include <linux/input.h> 12 #include <linux/interrupt.h> 13 #include <linux/pm.h> 14 #include <linux/slab.h> 15 #include <asm/io.h> 16 #include <linux/i2c.h> 17 #include <linux/timer.h> 18 19 #define EVENT_PENDOWN 1 20 #define EVENT_REPEAT 2 21 #define EVENT_PENUP 3 22 23 struct migor_ts_priv { 24 struct i2c_client *client; 25 struct input_dev *input; 26 int irq; 27 }; 28 29 static const u_int8_t migor_ts_ena_seq[17] = { 0x33, 0x22, 0x11, 30 0x01, 0x06, 0x07, }; 31 static const u_int8_t migor_ts_dis_seq[17] = { }; 32 33 static irqreturn_t migor_ts_isr(int irq, void *dev_id) 34 { 35 struct migor_ts_priv *priv = dev_id; 36 unsigned short xpos, ypos; 37 unsigned char event; 38 u_int8_t buf[16]; 39 40 /* 41 * The touch screen controller chip is hooked up to the CPU 42 * using I2C and a single interrupt line. The interrupt line 43 * is pulled low whenever someone taps the screen. To deassert 44 * the interrupt line we need to acknowledge the interrupt by 45 * communicating with the controller over the slow i2c bus. 46 * 47 * Since I2C bus controller may sleep we are using threaded 48 * IRQ here. 49 */ 50 51 memset(buf, 0, sizeof(buf)); 52 53 /* Set Index 0 */ 54 buf[0] = 0; 55 if (i2c_master_send(priv->client, buf, 1) != 1) { 56 dev_err(&priv->client->dev, "Unable to write i2c index\n"); 57 goto out; 58 } 59 60 /* Now do Page Read */ 61 if (i2c_master_recv(priv->client, buf, sizeof(buf)) != sizeof(buf)) { 62 dev_err(&priv->client->dev, "Unable to read i2c page\n"); 63 goto out; 64 } 65 66 ypos = ((buf[9] & 0x03) << 8 | buf[8]); 67 xpos = ((buf[11] & 0x03) << 8 | buf[10]); 68 event = buf[12]; 69 70 switch (event) { 71 case EVENT_PENDOWN: 72 case EVENT_REPEAT: 73 input_report_key(priv->input, BTN_TOUCH, 1); 74 input_report_abs(priv->input, ABS_X, ypos); /*X-Y swap*/ 75 input_report_abs(priv->input, ABS_Y, xpos); 76 input_sync(priv->input); 77 break; 78 79 case EVENT_PENUP: 80 input_report_key(priv->input, BTN_TOUCH, 0); 81 input_sync(priv->input); 82 break; 83 } 84 85 out: 86 return IRQ_HANDLED; 87 } 88 89 static int migor_ts_open(struct input_dev *dev) 90 { 91 struct migor_ts_priv *priv = input_get_drvdata(dev); 92 struct i2c_client *client = priv->client; 93 int count; 94 95 /* enable controller */ 96 count = i2c_master_send(client, migor_ts_ena_seq, 97 sizeof(migor_ts_ena_seq)); 98 if (count != sizeof(migor_ts_ena_seq)) { 99 dev_err(&client->dev, "Unable to enable touchscreen.\n"); 100 return -ENXIO; 101 } 102 103 return 0; 104 } 105 106 static void migor_ts_close(struct input_dev *dev) 107 { 108 struct migor_ts_priv *priv = input_get_drvdata(dev); 109 struct i2c_client *client = priv->client; 110 111 disable_irq(priv->irq); 112 113 /* disable controller */ 114 i2c_master_send(client, migor_ts_dis_seq, sizeof(migor_ts_dis_seq)); 115 116 enable_irq(priv->irq); 117 } 118 119 static int migor_ts_probe(struct i2c_client *client, 120 const struct i2c_device_id *idp) 121 { 122 struct migor_ts_priv *priv; 123 struct input_dev *input; 124 int error; 125 126 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 127 input = input_allocate_device(); 128 if (!priv || !input) { 129 dev_err(&client->dev, "failed to allocate memory\n"); 130 error = -ENOMEM; 131 goto err_free_mem; 132 } 133 134 priv->client = client; 135 priv->input = input; 136 priv->irq = client->irq; 137 138 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 139 140 __set_bit(BTN_TOUCH, input->keybit); 141 142 input_set_abs_params(input, ABS_X, 95, 955, 0, 0); 143 input_set_abs_params(input, ABS_Y, 85, 935, 0, 0); 144 145 input->name = client->name; 146 input->id.bustype = BUS_I2C; 147 input->dev.parent = &client->dev; 148 149 input->open = migor_ts_open; 150 input->close = migor_ts_close; 151 152 input_set_drvdata(input, priv); 153 154 error = request_threaded_irq(priv->irq, NULL, migor_ts_isr, 155 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 156 client->name, priv); 157 if (error) { 158 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); 159 goto err_free_mem; 160 } 161 162 error = input_register_device(input); 163 if (error) 164 goto err_free_irq; 165 166 i2c_set_clientdata(client, priv); 167 device_init_wakeup(&client->dev, 1); 168 169 return 0; 170 171 err_free_irq: 172 free_irq(priv->irq, priv); 173 err_free_mem: 174 input_free_device(input); 175 kfree(priv); 176 return error; 177 } 178 179 static void migor_ts_remove(struct i2c_client *client) 180 { 181 struct migor_ts_priv *priv = i2c_get_clientdata(client); 182 183 free_irq(priv->irq, priv); 184 input_unregister_device(priv->input); 185 kfree(priv); 186 187 dev_set_drvdata(&client->dev, NULL); 188 } 189 190 static int __maybe_unused migor_ts_suspend(struct device *dev) 191 { 192 struct i2c_client *client = to_i2c_client(dev); 193 struct migor_ts_priv *priv = i2c_get_clientdata(client); 194 195 if (device_may_wakeup(&client->dev)) 196 enable_irq_wake(priv->irq); 197 198 return 0; 199 } 200 201 static int __maybe_unused migor_ts_resume(struct device *dev) 202 { 203 struct i2c_client *client = to_i2c_client(dev); 204 struct migor_ts_priv *priv = i2c_get_clientdata(client); 205 206 if (device_may_wakeup(&client->dev)) 207 disable_irq_wake(priv->irq); 208 209 return 0; 210 } 211 212 static SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume); 213 214 static const struct i2c_device_id migor_ts_id[] = { 215 { "migor_ts", 0 }, 216 { } 217 }; 218 MODULE_DEVICE_TABLE(i2c, migor_ts_id); 219 220 static struct i2c_driver migor_ts_driver = { 221 .driver = { 222 .name = "migor_ts", 223 .pm = &migor_ts_pm, 224 }, 225 .probe = migor_ts_probe, 226 .remove = migor_ts_remove, 227 .id_table = migor_ts_id, 228 }; 229 230 module_i2c_driver(migor_ts_driver); 231 232 MODULE_DESCRIPTION("MigoR Touchscreen driver"); 233 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); 234 MODULE_LICENSE("GPL"); 235