0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/platform_device.h>
0009 #include <linux/input.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/module.h>
0012 #include <linux/clk.h>
0013 #include <linux/io.h>
0014 #include <linux/slab.h>
0015 #include <linux/of.h>
0016
0017
0018
0019
0020 #define LPC32XX_TSC_STAT 0x00
0021 #define LPC32XX_TSC_SEL 0x04
0022 #define LPC32XX_TSC_CON 0x08
0023 #define LPC32XX_TSC_FIFO 0x0C
0024 #define LPC32XX_TSC_DTR 0x10
0025 #define LPC32XX_TSC_RTR 0x14
0026 #define LPC32XX_TSC_UTR 0x18
0027 #define LPC32XX_TSC_TTR 0x1C
0028 #define LPC32XX_TSC_DXP 0x20
0029 #define LPC32XX_TSC_MIN_X 0x24
0030 #define LPC32XX_TSC_MAX_X 0x28
0031 #define LPC32XX_TSC_MIN_Y 0x2C
0032 #define LPC32XX_TSC_MAX_Y 0x30
0033 #define LPC32XX_TSC_AUX_UTR 0x34
0034 #define LPC32XX_TSC_AUX_MIN 0x38
0035 #define LPC32XX_TSC_AUX_MAX 0x3C
0036
0037 #define LPC32XX_TSC_STAT_FIFO_OVRRN BIT(8)
0038 #define LPC32XX_TSC_STAT_FIFO_EMPTY BIT(7)
0039
0040 #define LPC32XX_TSC_SEL_DEFVAL 0x0284
0041
0042 #define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11)
0043 #define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - (s)) << 7)
0044 #define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - (s)) << 4)
0045 #define LPC32XX_TSC_ADCCON_POWER_UP BIT(2)
0046 #define LPC32XX_TSC_ADCCON_AUTO_EN BIT(0)
0047
0048 #define LPC32XX_TSC_FIFO_TS_P_LEVEL BIT(31)
0049 #define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16)
0050 #define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF)
0051
0052 #define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF
0053
0054 #define LPC32XX_TSC_MIN_XY_VAL 0x0
0055 #define LPC32XX_TSC_MAX_XY_VAL 0x3FF
0056
0057 #define MOD_NAME "ts-lpc32xx"
0058
0059 #define tsc_readl(dev, reg) \
0060 __raw_readl((dev)->tsc_base + (reg))
0061 #define tsc_writel(dev, reg, val) \
0062 __raw_writel((val), (dev)->tsc_base + (reg))
0063
0064 struct lpc32xx_tsc {
0065 struct input_dev *dev;
0066 void __iomem *tsc_base;
0067 int irq;
0068 struct clk *clk;
0069 };
0070
0071 static void lpc32xx_fifo_clear(struct lpc32xx_tsc *tsc)
0072 {
0073 while (!(tsc_readl(tsc, LPC32XX_TSC_STAT) &
0074 LPC32XX_TSC_STAT_FIFO_EMPTY))
0075 tsc_readl(tsc, LPC32XX_TSC_FIFO);
0076 }
0077
0078 static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id)
0079 {
0080 u32 tmp, rv[4], xs[4], ys[4];
0081 int idx;
0082 struct lpc32xx_tsc *tsc = dev_id;
0083 struct input_dev *input = tsc->dev;
0084
0085 tmp = tsc_readl(tsc, LPC32XX_TSC_STAT);
0086
0087 if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) {
0088
0089 lpc32xx_fifo_clear(tsc);
0090 return IRQ_HANDLED;
0091 }
0092
0093
0094
0095
0096
0097
0098 idx = 0;
0099 while (idx < 4 &&
0100 !(tsc_readl(tsc, LPC32XX_TSC_STAT) &
0101 LPC32XX_TSC_STAT_FIFO_EMPTY)) {
0102 tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO);
0103 xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK -
0104 LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp);
0105 ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK -
0106 LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp);
0107 rv[idx] = tmp;
0108 idx++;
0109 }
0110
0111
0112 if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) {
0113
0114 input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2);
0115 input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2);
0116 input_report_key(input, BTN_TOUCH, 1);
0117 } else {
0118 input_report_key(input, BTN_TOUCH, 0);
0119 }
0120
0121 input_sync(input);
0122
0123 return IRQ_HANDLED;
0124 }
0125
0126 static void lpc32xx_stop_tsc(struct lpc32xx_tsc *tsc)
0127 {
0128
0129 tsc_writel(tsc, LPC32XX_TSC_CON,
0130 tsc_readl(tsc, LPC32XX_TSC_CON) &
0131 ~LPC32XX_TSC_ADCCON_AUTO_EN);
0132
0133 clk_disable_unprepare(tsc->clk);
0134 }
0135
0136 static int lpc32xx_setup_tsc(struct lpc32xx_tsc *tsc)
0137 {
0138 u32 tmp;
0139 int err;
0140
0141 err = clk_prepare_enable(tsc->clk);
0142 if (err)
0143 return err;
0144
0145 tmp = tsc_readl(tsc, LPC32XX_TSC_CON) & ~LPC32XX_TSC_ADCCON_POWER_UP;
0146
0147
0148 tmp = LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 |
0149 LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) |
0150 LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10);
0151 tsc_writel(tsc, LPC32XX_TSC_CON, tmp);
0152
0153
0154 tsc_writel(tsc, LPC32XX_TSC_SEL, LPC32XX_TSC_SEL_DEFVAL);
0155 tsc_writel(tsc, LPC32XX_TSC_MIN_X, LPC32XX_TSC_MIN_XY_VAL);
0156 tsc_writel(tsc, LPC32XX_TSC_MAX_X, LPC32XX_TSC_MAX_XY_VAL);
0157 tsc_writel(tsc, LPC32XX_TSC_MIN_Y, LPC32XX_TSC_MIN_XY_VAL);
0158 tsc_writel(tsc, LPC32XX_TSC_MAX_Y, LPC32XX_TSC_MAX_XY_VAL);
0159
0160
0161 tsc_writel(tsc, LPC32XX_TSC_AUX_UTR, 0);
0162 tsc_writel(tsc, LPC32XX_TSC_AUX_MIN, 0);
0163 tsc_writel(tsc, LPC32XX_TSC_AUX_MAX, 0);
0164
0165
0166
0167
0168
0169
0170
0171 tsc_writel(tsc, LPC32XX_TSC_RTR, 0x2);
0172 tsc_writel(tsc, LPC32XX_TSC_DTR, 0x2);
0173 tsc_writel(tsc, LPC32XX_TSC_TTR, 0x10);
0174 tsc_writel(tsc, LPC32XX_TSC_DXP, 0x4);
0175 tsc_writel(tsc, LPC32XX_TSC_UTR, 88);
0176
0177 lpc32xx_fifo_clear(tsc);
0178
0179
0180 tsc_writel(tsc, LPC32XX_TSC_CON, tmp | LPC32XX_TSC_ADCCON_AUTO_EN);
0181
0182 return 0;
0183 }
0184
0185 static int lpc32xx_ts_open(struct input_dev *dev)
0186 {
0187 struct lpc32xx_tsc *tsc = input_get_drvdata(dev);
0188
0189 return lpc32xx_setup_tsc(tsc);
0190 }
0191
0192 static void lpc32xx_ts_close(struct input_dev *dev)
0193 {
0194 struct lpc32xx_tsc *tsc = input_get_drvdata(dev);
0195
0196 lpc32xx_stop_tsc(tsc);
0197 }
0198
0199 static int lpc32xx_ts_probe(struct platform_device *pdev)
0200 {
0201 struct lpc32xx_tsc *tsc;
0202 struct input_dev *input;
0203 struct resource *res;
0204 resource_size_t size;
0205 int irq;
0206 int error;
0207
0208 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0209 if (!res) {
0210 dev_err(&pdev->dev, "Can't get memory resource\n");
0211 return -ENOENT;
0212 }
0213
0214 irq = platform_get_irq(pdev, 0);
0215 if (irq < 0)
0216 return irq;
0217
0218 tsc = kzalloc(sizeof(*tsc), GFP_KERNEL);
0219 input = input_allocate_device();
0220 if (!tsc || !input) {
0221 dev_err(&pdev->dev, "failed allocating memory\n");
0222 error = -ENOMEM;
0223 goto err_free_mem;
0224 }
0225
0226 tsc->dev = input;
0227 tsc->irq = irq;
0228
0229 size = resource_size(res);
0230
0231 if (!request_mem_region(res->start, size, pdev->name)) {
0232 dev_err(&pdev->dev, "TSC registers are not free\n");
0233 error = -EBUSY;
0234 goto err_free_mem;
0235 }
0236
0237 tsc->tsc_base = ioremap(res->start, size);
0238 if (!tsc->tsc_base) {
0239 dev_err(&pdev->dev, "Can't map memory\n");
0240 error = -ENOMEM;
0241 goto err_release_mem;
0242 }
0243
0244 tsc->clk = clk_get(&pdev->dev, NULL);
0245 if (IS_ERR(tsc->clk)) {
0246 dev_err(&pdev->dev, "failed getting clock\n");
0247 error = PTR_ERR(tsc->clk);
0248 goto err_unmap;
0249 }
0250
0251 input->name = MOD_NAME;
0252 input->phys = "lpc32xx/input0";
0253 input->id.bustype = BUS_HOST;
0254 input->id.vendor = 0x0001;
0255 input->id.product = 0x0002;
0256 input->id.version = 0x0100;
0257 input->dev.parent = &pdev->dev;
0258 input->open = lpc32xx_ts_open;
0259 input->close = lpc32xx_ts_close;
0260
0261 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
0262 input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
0263 input_set_abs_params(input, ABS_X, LPC32XX_TSC_MIN_XY_VAL,
0264 LPC32XX_TSC_MAX_XY_VAL, 0, 0);
0265 input_set_abs_params(input, ABS_Y, LPC32XX_TSC_MIN_XY_VAL,
0266 LPC32XX_TSC_MAX_XY_VAL, 0, 0);
0267
0268 input_set_drvdata(input, tsc);
0269
0270 error = request_irq(tsc->irq, lpc32xx_ts_interrupt,
0271 0, pdev->name, tsc);
0272 if (error) {
0273 dev_err(&pdev->dev, "failed requesting interrupt\n");
0274 goto err_put_clock;
0275 }
0276
0277 error = input_register_device(input);
0278 if (error) {
0279 dev_err(&pdev->dev, "failed registering input device\n");
0280 goto err_free_irq;
0281 }
0282
0283 platform_set_drvdata(pdev, tsc);
0284 device_init_wakeup(&pdev->dev, 1);
0285
0286 return 0;
0287
0288 err_free_irq:
0289 free_irq(tsc->irq, tsc);
0290 err_put_clock:
0291 clk_put(tsc->clk);
0292 err_unmap:
0293 iounmap(tsc->tsc_base);
0294 err_release_mem:
0295 release_mem_region(res->start, size);
0296 err_free_mem:
0297 input_free_device(input);
0298 kfree(tsc);
0299
0300 return error;
0301 }
0302
0303 static int lpc32xx_ts_remove(struct platform_device *pdev)
0304 {
0305 struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev);
0306 struct resource *res;
0307
0308 free_irq(tsc->irq, tsc);
0309
0310 input_unregister_device(tsc->dev);
0311
0312 clk_put(tsc->clk);
0313
0314 iounmap(tsc->tsc_base);
0315 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0316 release_mem_region(res->start, resource_size(res));
0317
0318 kfree(tsc);
0319
0320 return 0;
0321 }
0322
0323 #ifdef CONFIG_PM
0324 static int lpc32xx_ts_suspend(struct device *dev)
0325 {
0326 struct lpc32xx_tsc *tsc = dev_get_drvdata(dev);
0327 struct input_dev *input = tsc->dev;
0328
0329
0330
0331
0332
0333
0334
0335 mutex_lock(&input->mutex);
0336
0337 if (input_device_enabled(input)) {
0338 if (device_may_wakeup(dev))
0339 enable_irq_wake(tsc->irq);
0340 else
0341 lpc32xx_stop_tsc(tsc);
0342 }
0343
0344 mutex_unlock(&input->mutex);
0345
0346 return 0;
0347 }
0348
0349 static int lpc32xx_ts_resume(struct device *dev)
0350 {
0351 struct lpc32xx_tsc *tsc = dev_get_drvdata(dev);
0352 struct input_dev *input = tsc->dev;
0353
0354 mutex_lock(&input->mutex);
0355
0356 if (input_device_enabled(input)) {
0357 if (device_may_wakeup(dev))
0358 disable_irq_wake(tsc->irq);
0359 else
0360 lpc32xx_setup_tsc(tsc);
0361 }
0362
0363 mutex_unlock(&input->mutex);
0364
0365 return 0;
0366 }
0367
0368 static const struct dev_pm_ops lpc32xx_ts_pm_ops = {
0369 .suspend = lpc32xx_ts_suspend,
0370 .resume = lpc32xx_ts_resume,
0371 };
0372 #define LPC32XX_TS_PM_OPS (&lpc32xx_ts_pm_ops)
0373 #else
0374 #define LPC32XX_TS_PM_OPS NULL
0375 #endif
0376
0377 #ifdef CONFIG_OF
0378 static const struct of_device_id lpc32xx_tsc_of_match[] = {
0379 { .compatible = "nxp,lpc3220-tsc", },
0380 { },
0381 };
0382 MODULE_DEVICE_TABLE(of, lpc32xx_tsc_of_match);
0383 #endif
0384
0385 static struct platform_driver lpc32xx_ts_driver = {
0386 .probe = lpc32xx_ts_probe,
0387 .remove = lpc32xx_ts_remove,
0388 .driver = {
0389 .name = MOD_NAME,
0390 .pm = LPC32XX_TS_PM_OPS,
0391 .of_match_table = of_match_ptr(lpc32xx_tsc_of_match),
0392 },
0393 };
0394 module_platform_driver(lpc32xx_ts_driver);
0395
0396 MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com");
0397 MODULE_DESCRIPTION("LPC32XX TSC Driver");
0398 MODULE_LICENSE("GPL");
0399 MODULE_ALIAS("platform:lpc32xx_ts");