0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/input.h>
0011 #include <linux/delay.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/interrupt.h>
0014
0015 #include <linux/mfd/da9052/reg.h>
0016 #include <linux/mfd/da9052/da9052.h>
0017
0018 #define TSI_PEN_DOWN_STATUS 0x40
0019
0020 struct da9052_tsi {
0021 struct da9052 *da9052;
0022 struct input_dev *dev;
0023 struct delayed_work ts_pen_work;
0024 bool stopped;
0025 bool adc_on;
0026 };
0027
0028 static void da9052_ts_adc_toggle(struct da9052_tsi *tsi, bool on)
0029 {
0030 da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 0, on);
0031 tsi->adc_on = on;
0032 }
0033
0034 static irqreturn_t da9052_ts_pendwn_irq(int irq, void *data)
0035 {
0036 struct da9052_tsi *tsi = data;
0037
0038 if (!tsi->stopped) {
0039
0040 da9052_disable_irq_nosync(tsi->da9052, DA9052_IRQ_PENDOWN);
0041 da9052_enable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
0042
0043 da9052_ts_adc_toggle(tsi, true);
0044
0045 schedule_delayed_work(&tsi->ts_pen_work, HZ / 50);
0046 }
0047
0048 return IRQ_HANDLED;
0049 }
0050
0051 static void da9052_ts_read(struct da9052_tsi *tsi)
0052 {
0053 struct input_dev *input = tsi->dev;
0054 int ret;
0055 u16 x, y, z;
0056 u8 v;
0057
0058 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_X_MSB_REG);
0059 if (ret < 0)
0060 return;
0061
0062 x = (u16) ret;
0063
0064 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Y_MSB_REG);
0065 if (ret < 0)
0066 return;
0067
0068 y = (u16) ret;
0069
0070 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Z_MSB_REG);
0071 if (ret < 0)
0072 return;
0073
0074 z = (u16) ret;
0075
0076 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG);
0077 if (ret < 0)
0078 return;
0079
0080 v = (u8) ret;
0081
0082 x = ((x << 2) & 0x3fc) | (v & 0x3);
0083 y = ((y << 2) & 0x3fc) | ((v & 0xc) >> 2);
0084 z = ((z << 2) & 0x3fc) | ((v & 0x30) >> 4);
0085
0086 input_report_key(input, BTN_TOUCH, 1);
0087 input_report_abs(input, ABS_X, x);
0088 input_report_abs(input, ABS_Y, y);
0089 input_report_abs(input, ABS_PRESSURE, z);
0090 input_sync(input);
0091 }
0092
0093 static irqreturn_t da9052_ts_datardy_irq(int irq, void *data)
0094 {
0095 struct da9052_tsi *tsi = data;
0096
0097 da9052_ts_read(tsi);
0098
0099 return IRQ_HANDLED;
0100 }
0101
0102 static void da9052_ts_pen_work(struct work_struct *work)
0103 {
0104 struct da9052_tsi *tsi = container_of(work, struct da9052_tsi,
0105 ts_pen_work.work);
0106 if (!tsi->stopped) {
0107 int ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG);
0108 if (ret < 0 || (ret & TSI_PEN_DOWN_STATUS)) {
0109
0110 schedule_delayed_work(&tsi->ts_pen_work, HZ / 50);
0111 } else {
0112 struct input_dev *input = tsi->dev;
0113
0114
0115 da9052_ts_adc_toggle(tsi, false);
0116
0117
0118 input_report_key(input, BTN_TOUCH, 0);
0119 input_report_abs(input, ABS_PRESSURE, 0);
0120 input_sync(input);
0121
0122
0123
0124
0125
0126 ret = da9052_reg_update(tsi->da9052,
0127 DA9052_EVENT_B_REG, 0xC0, 0xC0);
0128 if (ret < 0)
0129 return;
0130
0131
0132 da9052_disable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
0133 da9052_enable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
0134 }
0135 }
0136 }
0137
0138 static int da9052_ts_configure_gpio(struct da9052 *da9052)
0139 {
0140 int error;
0141
0142 error = da9052_reg_update(da9052, DA9052_GPIO_2_3_REG, 0x30, 0);
0143 if (error < 0)
0144 return error;
0145
0146 error = da9052_reg_update(da9052, DA9052_GPIO_4_5_REG, 0x33, 0);
0147 if (error < 0)
0148 return error;
0149
0150 error = da9052_reg_update(da9052, DA9052_GPIO_6_7_REG, 0x33, 0);
0151 if (error < 0)
0152 return error;
0153
0154 return 0;
0155 }
0156
0157 static int da9052_configure_tsi(struct da9052_tsi *tsi)
0158 {
0159 int error;
0160
0161 error = da9052_ts_configure_gpio(tsi->da9052);
0162 if (error)
0163 return error;
0164
0165
0166 error = da9052_reg_update(tsi->da9052, DA9052_ADC_CONT_REG,
0167 1 << 6, 1 << 6);
0168 if (error < 0)
0169 return error;
0170
0171
0172 error = da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 0xFC, 0xC0);
0173 if (error < 0)
0174 return error;
0175
0176
0177 error = da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x59);
0178 if (error < 0)
0179 return error;
0180
0181 return 0;
0182 }
0183
0184 static int da9052_ts_input_open(struct input_dev *input_dev)
0185 {
0186 struct da9052_tsi *tsi = input_get_drvdata(input_dev);
0187
0188 tsi->stopped = false;
0189 mb();
0190
0191
0192 da9052_enable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
0193
0194
0195 return da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG,
0196 1 << 1, 1 << 1);
0197 }
0198
0199 static void da9052_ts_input_close(struct input_dev *input_dev)
0200 {
0201 struct da9052_tsi *tsi = input_get_drvdata(input_dev);
0202
0203 tsi->stopped = true;
0204 mb();
0205 da9052_disable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
0206 cancel_delayed_work_sync(&tsi->ts_pen_work);
0207
0208 if (tsi->adc_on) {
0209 da9052_disable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
0210 da9052_ts_adc_toggle(tsi, false);
0211
0212
0213
0214
0215
0216
0217 da9052_enable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
0218 }
0219
0220
0221 da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0);
0222 }
0223
0224 static int da9052_ts_probe(struct platform_device *pdev)
0225 {
0226 struct da9052 *da9052;
0227 struct da9052_tsi *tsi;
0228 struct input_dev *input_dev;
0229 int error;
0230
0231 da9052 = dev_get_drvdata(pdev->dev.parent);
0232 if (!da9052)
0233 return -EINVAL;
0234
0235 tsi = kzalloc(sizeof(struct da9052_tsi), GFP_KERNEL);
0236 input_dev = input_allocate_device();
0237 if (!tsi || !input_dev) {
0238 error = -ENOMEM;
0239 goto err_free_mem;
0240 }
0241
0242 tsi->da9052 = da9052;
0243 tsi->dev = input_dev;
0244 tsi->stopped = true;
0245 INIT_DELAYED_WORK(&tsi->ts_pen_work, da9052_ts_pen_work);
0246
0247 input_dev->id.version = 0x0101;
0248 input_dev->id.vendor = 0x15B6;
0249 input_dev->id.product = 0x9052;
0250 input_dev->name = "Dialog DA9052 TouchScreen Driver";
0251 input_dev->dev.parent = &pdev->dev;
0252 input_dev->open = da9052_ts_input_open;
0253 input_dev->close = da9052_ts_input_close;
0254
0255 __set_bit(EV_ABS, input_dev->evbit);
0256 __set_bit(EV_KEY, input_dev->evbit);
0257 __set_bit(BTN_TOUCH, input_dev->keybit);
0258
0259 input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
0260 input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
0261 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1023, 0, 0);
0262
0263 input_set_drvdata(input_dev, tsi);
0264
0265
0266 da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0);
0267
0268
0269 da9052_ts_adc_toggle(tsi, false);
0270
0271 error = da9052_request_irq(tsi->da9052, DA9052_IRQ_PENDOWN,
0272 "pendown-irq", da9052_ts_pendwn_irq, tsi);
0273 if (error) {
0274 dev_err(tsi->da9052->dev,
0275 "Failed to register PENDWN IRQ: %d\n", error);
0276 goto err_free_mem;
0277 }
0278
0279 error = da9052_request_irq(tsi->da9052, DA9052_IRQ_TSIREADY,
0280 "tsiready-irq", da9052_ts_datardy_irq, tsi);
0281 if (error) {
0282 dev_err(tsi->da9052->dev,
0283 "Failed to register TSIRDY IRQ :%d\n", error);
0284 goto err_free_pendwn_irq;
0285 }
0286
0287
0288 da9052_disable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
0289 da9052_disable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
0290
0291 error = da9052_configure_tsi(tsi);
0292 if (error)
0293 goto err_free_datardy_irq;
0294
0295 error = input_register_device(tsi->dev);
0296 if (error)
0297 goto err_free_datardy_irq;
0298
0299 platform_set_drvdata(pdev, tsi);
0300
0301 return 0;
0302
0303 err_free_datardy_irq:
0304 da9052_free_irq(tsi->da9052, DA9052_IRQ_TSIREADY, tsi);
0305 err_free_pendwn_irq:
0306 da9052_free_irq(tsi->da9052, DA9052_IRQ_PENDOWN, tsi);
0307 err_free_mem:
0308 kfree(tsi);
0309 input_free_device(input_dev);
0310
0311 return error;
0312 }
0313
0314 static int da9052_ts_remove(struct platform_device *pdev)
0315 {
0316 struct da9052_tsi *tsi = platform_get_drvdata(pdev);
0317
0318 da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19);
0319
0320 da9052_free_irq(tsi->da9052, DA9052_IRQ_TSIREADY, tsi);
0321 da9052_free_irq(tsi->da9052, DA9052_IRQ_PENDOWN, tsi);
0322
0323 input_unregister_device(tsi->dev);
0324 kfree(tsi);
0325
0326 return 0;
0327 }
0328
0329 static struct platform_driver da9052_tsi_driver = {
0330 .probe = da9052_ts_probe,
0331 .remove = da9052_ts_remove,
0332 .driver = {
0333 .name = "da9052-tsi",
0334 },
0335 };
0336
0337 module_platform_driver(da9052_tsi_driver);
0338
0339 MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9052");
0340 MODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>");
0341 MODULE_LICENSE("GPL");
0342 MODULE_ALIAS("platform:da9052-tsi");