Lines Matching +full:touchscreen +full:- +full:average +full:- +full:samples

1 // SPDX-License-Identifier: GPL-2.0
3 // Freescale i.MX6UL touchscreen controller driver
111 reinit_completion(&tsc->completion); in imx6ul_adc_init()
113 adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG); in imx6ul_adc_init()
118 if (tsc->average_enable) { in imx6ul_adc_init()
120 adc_cfg |= (tsc->average_select) << ADC_AVGS_SHIFT; in imx6ul_adc_init()
123 writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG); in imx6ul_adc_init()
128 writel(adc_hc, tsc->adc_regs + REG_ADC_HC0); in imx6ul_adc_init()
131 adc_gc = readl(tsc->adc_regs + REG_ADC_GC); in imx6ul_adc_init()
133 if (tsc->average_enable) in imx6ul_adc_init()
135 writel(adc_gc, tsc->adc_regs + REG_ADC_GC); in imx6ul_adc_init()
138 (&tsc->completion, ADC_TIMEOUT); in imx6ul_adc_init()
140 dev_err(tsc->dev, "Timeout for adc calibration\n"); in imx6ul_adc_init()
141 return -ETIMEDOUT; in imx6ul_adc_init()
144 adc_gs = readl(tsc->adc_regs + REG_ADC_GS); in imx6ul_adc_init()
146 dev_err(tsc->dev, "ADC calibration failed\n"); in imx6ul_adc_init()
147 return -EINVAL; in imx6ul_adc_init()
151 adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG); in imx6ul_adc_init()
153 writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG); in imx6ul_adc_init()
168 writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0); in imx6ul_tsc_channel_config()
171 writel(adc_hc1, tsc->adc_regs + REG_ADC_HC1); in imx6ul_tsc_channel_config()
174 writel(adc_hc2, tsc->adc_regs + REG_ADC_HC2); in imx6ul_tsc_channel_config()
177 writel(adc_hc3, tsc->adc_regs + REG_ADC_HC3); in imx6ul_tsc_channel_config()
180 writel(adc_hc4, tsc->adc_regs + REG_ADC_HC4); in imx6ul_tsc_channel_config()
184 * TSC setting, confige the pre-charge time and measure delay time.
185 * different touch screen may need different pre-charge time and
193 basic_setting |= tsc->measure_delay_time << 8; in imx6ul_tsc_set()
195 writel(basic_setting, tsc->tsc_regs + REG_TSC_BASIC_SETING); in imx6ul_tsc_set()
197 writel(DE_GLITCH_2, tsc->tsc_regs + REG_TSC_DEBUG_MODE2); in imx6ul_tsc_set()
199 writel(tsc->pre_charge_time, tsc->tsc_regs + REG_TSC_PRE_CHARGE_TIME); in imx6ul_tsc_set()
200 writel(MEASURE_INT_EN, tsc->tsc_regs + REG_TSC_INT_EN); in imx6ul_tsc_set()
202 tsc->tsc_regs + REG_TSC_INT_SIG_EN); in imx6ul_tsc_set()
205 start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL); in imx6ul_tsc_set()
208 writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL); in imx6ul_tsc_set()
230 tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL); in imx6ul_tsc_disable()
232 writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL); in imx6ul_tsc_disable()
235 adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0); in imx6ul_tsc_disable()
237 writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0); in imx6ul_tsc_disable()
240 /* Delay some time (max 2ms), wait the pre-charge done. */
252 debug_mode2 = readl(tsc->tsc_regs + REG_TSC_DEBUG_MODE2); in tsc_wait_detect_mode()
268 status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS); in tsc_irq_fn()
270 /* write 1 to clear the bit measure-signal */ in tsc_irq_fn()
272 tsc->tsc_regs + REG_TSC_INT_STATUS); in tsc_irq_fn()
274 /* It's a HW self-clean bit. Set this bit and start sense detection */ in tsc_irq_fn()
275 start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL); in tsc_irq_fn()
277 writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL); in tsc_irq_fn()
280 value = readl(tsc->tsc_regs + REG_TSC_MEASURE_VALUE); in tsc_irq_fn()
289 gpiod_get_value_cansleep(tsc->xnur_gpio)) { in tsc_irq_fn()
290 input_report_key(tsc->input, BTN_TOUCH, 1); in tsc_irq_fn()
291 input_report_abs(tsc->input, ABS_X, x); in tsc_irq_fn()
292 input_report_abs(tsc->input, ABS_Y, y); in tsc_irq_fn()
294 input_report_key(tsc->input, BTN_TOUCH, 0); in tsc_irq_fn()
297 input_sync(tsc->input); in tsc_irq_fn()
309 coco = readl(tsc->adc_regs + REG_ADC_HS); in adc_irq_fn()
311 value = readl(tsc->adc_regs + REG_ADC_R0); in adc_irq_fn()
312 complete(&tsc->completion); in adc_irq_fn()
322 err = clk_prepare_enable(tsc->adc_clk); in imx6ul_tsc_start()
324 dev_err(tsc->dev, in imx6ul_tsc_start()
330 err = clk_prepare_enable(tsc->tsc_clk); in imx6ul_tsc_start()
332 dev_err(tsc->dev, in imx6ul_tsc_start()
345 clk_disable_unprepare(tsc->tsc_clk); in imx6ul_tsc_start()
347 clk_disable_unprepare(tsc->adc_clk); in imx6ul_tsc_start()
355 clk_disable_unprepare(tsc->tsc_clk); in imx6ul_tsc_stop()
356 clk_disable_unprepare(tsc->adc_clk); in imx6ul_tsc_stop()
376 struct device_node *np = pdev->dev.of_node; in imx6ul_tsc_probe()
384 tsc = devm_kzalloc(&pdev->dev, sizeof(*tsc), GFP_KERNEL); in imx6ul_tsc_probe()
386 return -ENOMEM; in imx6ul_tsc_probe()
388 input_dev = devm_input_allocate_device(&pdev->dev); in imx6ul_tsc_probe()
390 return -ENOMEM; in imx6ul_tsc_probe()
392 input_dev->name = "iMX6UL Touchscreen Controller"; in imx6ul_tsc_probe()
393 input_dev->id.bustype = BUS_HOST; in imx6ul_tsc_probe()
395 input_dev->open = imx6ul_tsc_open; in imx6ul_tsc_probe()
396 input_dev->close = imx6ul_tsc_close; in imx6ul_tsc_probe()
404 tsc->dev = &pdev->dev; in imx6ul_tsc_probe()
405 tsc->input = input_dev; in imx6ul_tsc_probe()
406 init_completion(&tsc->completion); in imx6ul_tsc_probe()
408 tsc->xnur_gpio = devm_gpiod_get(&pdev->dev, "xnur", GPIOD_IN); in imx6ul_tsc_probe()
409 if (IS_ERR(tsc->xnur_gpio)) { in imx6ul_tsc_probe()
410 err = PTR_ERR(tsc->xnur_gpio); in imx6ul_tsc_probe()
411 dev_err(&pdev->dev, in imx6ul_tsc_probe()
412 "failed to request GPIO tsc_X- (xnur): %d\n", err); in imx6ul_tsc_probe()
416 tsc->tsc_regs = devm_platform_ioremap_resource(pdev, 0); in imx6ul_tsc_probe()
417 if (IS_ERR(tsc->tsc_regs)) { in imx6ul_tsc_probe()
418 err = PTR_ERR(tsc->tsc_regs); in imx6ul_tsc_probe()
419 dev_err(&pdev->dev, "failed to remap tsc memory: %d\n", err); in imx6ul_tsc_probe()
423 tsc->adc_regs = devm_platform_ioremap_resource(pdev, 1); in imx6ul_tsc_probe()
424 if (IS_ERR(tsc->adc_regs)) { in imx6ul_tsc_probe()
425 err = PTR_ERR(tsc->adc_regs); in imx6ul_tsc_probe()
426 dev_err(&pdev->dev, "failed to remap adc memory: %d\n", err); in imx6ul_tsc_probe()
430 tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc"); in imx6ul_tsc_probe()
431 if (IS_ERR(tsc->tsc_clk)) { in imx6ul_tsc_probe()
432 err = PTR_ERR(tsc->tsc_clk); in imx6ul_tsc_probe()
433 dev_err(&pdev->dev, "failed getting tsc clock: %d\n", err); in imx6ul_tsc_probe()
437 tsc->adc_clk = devm_clk_get(&pdev->dev, "adc"); in imx6ul_tsc_probe()
438 if (IS_ERR(tsc->adc_clk)) { in imx6ul_tsc_probe()
439 err = PTR_ERR(tsc->adc_clk); in imx6ul_tsc_probe()
440 dev_err(&pdev->dev, "failed getting adc clock: %d\n", err); in imx6ul_tsc_probe()
452 err = devm_request_threaded_irq(tsc->dev, tsc_irq, in imx6ul_tsc_probe()
454 dev_name(&pdev->dev), tsc); in imx6ul_tsc_probe()
456 dev_err(&pdev->dev, in imx6ul_tsc_probe()
462 err = devm_request_irq(tsc->dev, adc_irq, adc_irq_fn, 0, in imx6ul_tsc_probe()
463 dev_name(&pdev->dev), tsc); in imx6ul_tsc_probe()
465 dev_err(&pdev->dev, in imx6ul_tsc_probe()
471 err = of_property_read_u32(np, "measure-delay-time", in imx6ul_tsc_probe()
472 &tsc->measure_delay_time); in imx6ul_tsc_probe()
474 tsc->measure_delay_time = 0xffff; in imx6ul_tsc_probe()
476 err = of_property_read_u32(np, "pre-charge-time", in imx6ul_tsc_probe()
477 &tsc->pre_charge_time); in imx6ul_tsc_probe()
479 tsc->pre_charge_time = 0xfff; in imx6ul_tsc_probe()
481 err = of_property_read_u32(np, "touchscreen-average-samples", in imx6ul_tsc_probe()
488 tsc->average_enable = false; in imx6ul_tsc_probe()
489 tsc->average_select = 0; /* value unused; initialize anyway */ in imx6ul_tsc_probe()
495 tsc->average_enable = true; in imx6ul_tsc_probe()
496 tsc->average_select = ilog2(average_samples) - 2; in imx6ul_tsc_probe()
499 dev_err(&pdev->dev, in imx6ul_tsc_probe()
500 "touchscreen-average-samples (%u) must be 1, 4, 8, 16 or 32\n", in imx6ul_tsc_probe()
502 return -EINVAL; in imx6ul_tsc_probe()
505 err = input_register_device(tsc->input); in imx6ul_tsc_probe()
507 dev_err(&pdev->dev, in imx6ul_tsc_probe()
520 struct input_dev *input_dev = tsc->input; in imx6ul_tsc_suspend()
522 mutex_lock(&input_dev->mutex); in imx6ul_tsc_suspend()
524 if (input_dev->users) in imx6ul_tsc_suspend()
527 mutex_unlock(&input_dev->mutex); in imx6ul_tsc_suspend()
536 struct input_dev *input_dev = tsc->input; in imx6ul_tsc_resume()
539 mutex_lock(&input_dev->mutex); in imx6ul_tsc_resume()
541 if (input_dev->users) in imx6ul_tsc_resume()
544 mutex_unlock(&input_dev->mutex); in imx6ul_tsc_resume()
553 { .compatible = "fsl,imx6ul-tsc", },
560 .name = "imx6ul-tsc",
569 MODULE_DESCRIPTION("Freescale i.MX6UL Touchscreen controller driver");