1 /* 2 * Touchscreen driver for the tps6507x chip. 3 * 4 * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com) 5 * 6 * Credits: 7 * 8 * Using code from tsc2007, MtekVision Co., Ltd. 9 * 10 * For licencing details see kernel-base/COPYING 11 * 12 * TPS65070, TPS65073, TPS650731, and TPS650732 support 13 * 10 bit touch screen interface. 14 */ 15 16 #include <linux/module.h> 17 #include <linux/workqueue.h> 18 #include <linux/slab.h> 19 #include <linux/input.h> 20 #include <linux/input-polldev.h> 21 #include <linux/platform_device.h> 22 #include <linux/mfd/tps6507x.h> 23 #include <linux/input/tps6507x-ts.h> 24 #include <linux/delay.h> 25 26 #define TSC_DEFAULT_POLL_PERIOD 30 /* ms */ 27 #define TPS_DEFAULT_MIN_PRESSURE 0x30 28 #define MAX_10BIT ((1 << 10) - 1) 29 30 #define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \ 31 TPS6507X_ADCONFIG_START_CONVERSION | \ 32 TPS6507X_ADCONFIG_INPUT_REAL_TSC) 33 #define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC) 34 35 struct ts_event { 36 u16 x; 37 u16 y; 38 u16 pressure; 39 }; 40 41 struct tps6507x_ts { 42 struct device *dev; 43 struct input_polled_dev *poll_dev; 44 struct tps6507x_dev *mfd; 45 char phys[32]; 46 struct ts_event tc; 47 u16 min_pressure; 48 bool pendown; 49 }; 50 51 static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data) 52 { 53 return tsc->mfd->read_dev(tsc->mfd, reg, 1, data); 54 } 55 56 static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data) 57 { 58 return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data); 59 } 60 61 static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc, 62 u8 tsc_mode, u16 *value) 63 { 64 s32 ret; 65 u8 adc_status; 66 u8 result; 67 68 /* Route input signal to A/D converter */ 69 70 ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode); 71 if (ret) { 72 dev_err(tsc->dev, "TSC mode read failed\n"); 73 goto err; 74 } 75 76 /* Start A/D conversion */ 77 78 ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, 79 TPS6507X_ADCONFIG_CONVERT_TS); 80 if (ret) { 81 dev_err(tsc->dev, "ADC config write failed\n"); 82 return ret; 83 } 84 85 do { 86 ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG, 87 &adc_status); 88 if (ret) { 89 dev_err(tsc->dev, "ADC config read failed\n"); 90 goto err; 91 } 92 } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION); 93 94 ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result); 95 if (ret) { 96 dev_err(tsc->dev, "ADC result 2 read failed\n"); 97 goto err; 98 } 99 100 *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8; 101 102 ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result); 103 if (ret) { 104 dev_err(tsc->dev, "ADC result 1 read failed\n"); 105 goto err; 106 } 107 108 *value |= result; 109 110 dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value); 111 112 err: 113 return ret; 114 } 115 116 /* Need to call tps6507x_adc_standby() after using A/D converter for the 117 * touch screen interrupt to work properly. 118 */ 119 120 static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) 121 { 122 s32 ret; 123 s32 loops = 0; 124 u8 val; 125 126 ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, 127 TPS6507X_ADCONFIG_INPUT_TSC); 128 if (ret) 129 return ret; 130 131 ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, 132 TPS6507X_TSCMODE_STANDBY); 133 if (ret) 134 return ret; 135 136 ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); 137 if (ret) 138 return ret; 139 140 while (val & TPS6507X_REG_TSC_INT) { 141 mdelay(10); 142 ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); 143 if (ret) 144 return ret; 145 loops++; 146 } 147 148 return ret; 149 } 150 151 static void tps6507x_ts_poll(struct input_polled_dev *poll_dev) 152 { 153 struct tps6507x_ts *tsc = poll_dev->private; 154 struct input_dev *input_dev = poll_dev->input; 155 bool pendown; 156 s32 ret; 157 158 ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, 159 &tsc->tc.pressure); 160 if (ret) 161 goto done; 162 163 pendown = tsc->tc.pressure > tsc->min_pressure; 164 165 if (unlikely(!pendown && tsc->pendown)) { 166 dev_dbg(tsc->dev, "UP\n"); 167 input_report_key(input_dev, BTN_TOUCH, 0); 168 input_report_abs(input_dev, ABS_PRESSURE, 0); 169 input_sync(input_dev); 170 tsc->pendown = false; 171 } 172 173 if (pendown) { 174 175 if (!tsc->pendown) { 176 dev_dbg(tsc->dev, "DOWN\n"); 177 input_report_key(input_dev, BTN_TOUCH, 1); 178 } else 179 dev_dbg(tsc->dev, "still down\n"); 180 181 ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION, 182 &tsc->tc.x); 183 if (ret) 184 goto done; 185 186 ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION, 187 &tsc->tc.y); 188 if (ret) 189 goto done; 190 191 input_report_abs(input_dev, ABS_X, tsc->tc.x); 192 input_report_abs(input_dev, ABS_Y, tsc->tc.y); 193 input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); 194 input_sync(input_dev); 195 tsc->pendown = true; 196 } 197 198 done: 199 tps6507x_adc_standby(tsc); 200 } 201 202 static int tps6507x_ts_probe(struct platform_device *pdev) 203 { 204 struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); 205 const struct tps6507x_board *tps_board; 206 const struct touchscreen_init_data *init_data; 207 struct tps6507x_ts *tsc; 208 struct input_polled_dev *poll_dev; 209 struct input_dev *input_dev; 210 int error; 211 212 /* 213 * tps_board points to pmic related constants 214 * coming from the board-evm file. 215 */ 216 tps_board = dev_get_platdata(tps6507x_dev->dev); 217 if (!tps_board) { 218 dev_err(tps6507x_dev->dev, 219 "Could not find tps6507x platform data\n"); 220 return -ENODEV; 221 } 222 223 /* 224 * init_data points to array of regulator_init structures 225 * coming from the board-evm file. 226 */ 227 init_data = tps_board->tps6507x_ts_init_data; 228 229 tsc = devm_kzalloc(&pdev->dev, sizeof(struct tps6507x_ts), GFP_KERNEL); 230 if (!tsc) { 231 dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); 232 return -ENOMEM; 233 } 234 235 tsc->mfd = tps6507x_dev; 236 tsc->dev = tps6507x_dev->dev; 237 tsc->min_pressure = init_data ? 238 init_data->min_pressure : TPS_DEFAULT_MIN_PRESSURE; 239 240 snprintf(tsc->phys, sizeof(tsc->phys), 241 "%s/input0", dev_name(tsc->dev)); 242 243 poll_dev = devm_input_allocate_polled_device(&pdev->dev); 244 if (!poll_dev) { 245 dev_err(tsc->dev, "Failed to allocate polled input device.\n"); 246 return -ENOMEM; 247 } 248 249 tsc->poll_dev = poll_dev; 250 251 poll_dev->private = tsc; 252 poll_dev->poll = tps6507x_ts_poll; 253 poll_dev->poll_interval = init_data ? 254 init_data->poll_period : TSC_DEFAULT_POLL_PERIOD; 255 256 input_dev = poll_dev->input; 257 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 258 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 259 260 input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0); 261 input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0); 262 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); 263 264 input_dev->name = "TPS6507x Touchscreen"; 265 input_dev->phys = tsc->phys; 266 input_dev->dev.parent = tsc->dev; 267 input_dev->id.bustype = BUS_I2C; 268 if (init_data) { 269 input_dev->id.vendor = init_data->vendor; 270 input_dev->id.product = init_data->product; 271 input_dev->id.version = init_data->version; 272 } 273 274 error = tps6507x_adc_standby(tsc); 275 if (error) 276 return error; 277 278 error = input_register_polled_device(poll_dev); 279 if (error) 280 return error; 281 282 return 0; 283 } 284 285 static struct platform_driver tps6507x_ts_driver = { 286 .driver = { 287 .name = "tps6507x-ts", 288 }, 289 .probe = tps6507x_ts_probe, 290 }; 291 module_platform_driver(tps6507x_ts_driver); 292 293 MODULE_AUTHOR("Todd Fischer <todd.fischer@ridgerun.com>"); 294 MODULE_DESCRIPTION("TPS6507x - TouchScreen driver"); 295 MODULE_LICENSE("GPL v2"); 296 MODULE_ALIAS("platform:tps6507x-ts"); 297