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 { 121 struct migor_ts_priv *priv; 122 struct input_dev *input; 123 int error; 124 125 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 126 input = input_allocate_device(); 127 if (!priv || !input) { 128 dev_err(&client->dev, "failed to allocate memory\n"); 129 error = -ENOMEM; 130 goto err_free_mem; 131 } 132 133 priv->client = client; 134 priv->input = input; 135 priv->irq = client->irq; 136 137 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 138 139 __set_bit(BTN_TOUCH, input->keybit); 140 141 input_set_abs_params(input, ABS_X, 95, 955, 0, 0); 142 input_set_abs_params(input, ABS_Y, 85, 935, 0, 0); 143 144 input->name = client->name; 145 input->id.bustype = BUS_I2C; 146 input->dev.parent = &client->dev; 147 148 input->open = migor_ts_open; 149 input->close = migor_ts_close; 150 151 input_set_drvdata(input, priv); 152 153 error = request_threaded_irq(priv->irq, NULL, migor_ts_isr, 154 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 155 client->name, priv); 156 if (error) { 157 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); 158 goto err_free_mem; 159 } 160 161 error = input_register_device(input); 162 if (error) 163 goto err_free_irq; 164 165 i2c_set_clientdata(client, priv); 166 device_init_wakeup(&client->dev, 1); 167 168 return 0; 169 170 err_free_irq: 171 free_irq(priv->irq, priv); 172 err_free_mem: 173 input_free_device(input); 174 kfree(priv); 175 return error; 176 } 177 178 static void migor_ts_remove(struct i2c_client *client) 179 { 180 struct migor_ts_priv *priv = i2c_get_clientdata(client); 181 182 free_irq(priv->irq, priv); 183 input_unregister_device(priv->input); 184 kfree(priv); 185 186 dev_set_drvdata(&client->dev, NULL); 187 } 188 189 static int migor_ts_suspend(struct device *dev) 190 { 191 struct i2c_client *client = to_i2c_client(dev); 192 struct migor_ts_priv *priv = i2c_get_clientdata(client); 193 194 if (device_may_wakeup(&client->dev)) 195 enable_irq_wake(priv->irq); 196 197 return 0; 198 } 199 200 static int migor_ts_resume(struct device *dev) 201 { 202 struct i2c_client *client = to_i2c_client(dev); 203 struct migor_ts_priv *priv = i2c_get_clientdata(client); 204 205 if (device_may_wakeup(&client->dev)) 206 disable_irq_wake(priv->irq); 207 208 return 0; 209 } 210 211 static DEFINE_SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume); 212 213 static const struct i2c_device_id migor_ts_id[] = { 214 { "migor_ts" }, 215 { } 216 }; 217 MODULE_DEVICE_TABLE(i2c, migor_ts_id); 218 219 static struct i2c_driver migor_ts_driver = { 220 .driver = { 221 .name = "migor_ts", 222 .pm = pm_sleep_ptr(&migor_ts_pm), 223 }, 224 .probe = migor_ts_probe, 225 .remove = migor_ts_remove, 226 .id_table = migor_ts_id, 227 }; 228 229 module_i2c_driver(migor_ts_driver); 230 231 MODULE_DESCRIPTION("MigoR Touchscreen driver"); 232 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); 233 MODULE_LICENSE("GPL"); 234