Lines Matching +full:adc +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0-only
3 * TI Touch Screen / ADC MFD driver
5 * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
12 #include <linux/clk.h>
33 spin_lock_irqsave(&tscadc->reg_lock, flags); in am335x_tsc_se_set_cache()
34 tscadc->reg_se_cache |= val; in am335x_tsc_se_set_cache()
35 if (tscadc->adc_waiting) in am335x_tsc_se_set_cache()
36 wake_up(&tscadc->reg_se_wait); in am335x_tsc_se_set_cache()
37 else if (!tscadc->adc_in_use) in am335x_tsc_se_set_cache()
38 regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache); in am335x_tsc_se_set_cache()
40 spin_unlock_irqrestore(&tscadc->reg_lock, flags); in am335x_tsc_se_set_cache()
49 regmap_read(tscadc->regmap, REG_ADCFSM, ®); in am335x_tscadc_need_adc()
51 tscadc->adc_waiting = true; in am335x_tscadc_need_adc()
52 prepare_to_wait(&tscadc->reg_se_wait, &wait, in am335x_tscadc_need_adc()
54 spin_unlock_irq(&tscadc->reg_lock); in am335x_tscadc_need_adc()
58 spin_lock_irq(&tscadc->reg_lock); in am335x_tscadc_need_adc()
59 finish_wait(&tscadc->reg_se_wait, &wait); in am335x_tscadc_need_adc()
65 regmap_read(tscadc->regmap, REG_ADCFSM, ®); in am335x_tscadc_need_adc()
67 tscadc->adc_waiting = false; in am335x_tscadc_need_adc()
69 tscadc->adc_in_use = true; in am335x_tscadc_need_adc()
74 spin_lock_irq(&tscadc->reg_lock); in am335x_tsc_se_set_once()
77 regmap_write(tscadc->regmap, REG_SE, val); in am335x_tsc_se_set_once()
78 spin_unlock_irq(&tscadc->reg_lock); in am335x_tsc_se_set_once()
86 spin_lock_irqsave(&tscadc->reg_lock, flags); in am335x_tsc_se_adc_done()
87 tscadc->adc_in_use = false; in am335x_tsc_se_adc_done()
88 regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache); in am335x_tsc_se_adc_done()
89 spin_unlock_irqrestore(&tscadc->reg_lock, flags); in am335x_tsc_se_adc_done()
97 spin_lock_irqsave(&tscadc->reg_lock, flags); in am335x_tsc_se_clr()
98 tscadc->reg_se_cache &= ~val; in am335x_tsc_se_clr()
99 regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache); in am335x_tsc_se_clr()
100 spin_unlock_irqrestore(&tscadc->reg_lock, flags); in am335x_tsc_se_clr()
112 regmap_write(tscadc->regmap, REG_IDLECONFIG, idleconfig); in tscadc_idle_config()
119 struct clk *clk; in ti_tscadc_probe() local
129 tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL); in ti_tscadc_probe()
131 return -ENOMEM; in ti_tscadc_probe()
133 tscadc->dev = &pdev->dev; in ti_tscadc_probe()
135 if (!pdev->dev.of_node) { in ti_tscadc_probe()
136 dev_err(&pdev->dev, "Could not find valid DT data.\n"); in ti_tscadc_probe()
137 return -EINVAL; in ti_tscadc_probe()
140 tscadc->data = of_device_get_match_data(&pdev->dev); in ti_tscadc_probe()
143 node = of_get_child_by_name(pdev->dev.of_node, "tsc"); in ti_tscadc_probe()
145 err = of_property_read_u32(node, "ti,coordinate-readouts", in ti_tscadc_probe()
148 of_property_read_u32(node, "ti,coordiante-readouts", in ti_tscadc_probe()
167 node = of_get_child_by_name(pdev->dev.of_node, "adc"); in ti_tscadc_probe()
168 of_property_for_each_u32(node, "ti,adc-channels", val) { in ti_tscadc_probe()
171 dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n", in ti_tscadc_probe()
174 return -EINVAL; in ti_tscadc_probe()
182 dev_err(&pdev->dev, "Number of i/p channels more than 8\n"); in ti_tscadc_probe()
183 return -EINVAL; in ti_tscadc_probe()
187 dev_err(&pdev->dev, "Need at least one channel.\n"); in ti_tscadc_probe()
188 return -EINVAL; in ti_tscadc_probe()
192 dev_err(&pdev->dev, "Too many step configurations requested\n"); in ti_tscadc_probe()
193 return -EINVAL; in ti_tscadc_probe()
200 tscadc->irq = err; in ti_tscadc_probe()
202 tscadc->tscadc_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in ti_tscadc_probe()
203 if (IS_ERR(tscadc->tscadc_base)) in ti_tscadc_probe()
204 return PTR_ERR(tscadc->tscadc_base); in ti_tscadc_probe()
206 tscadc->tscadc_phys_base = res->start; in ti_tscadc_probe()
207 tscadc->regmap = devm_regmap_init_mmio(&pdev->dev, in ti_tscadc_probe()
208 tscadc->tscadc_base, in ti_tscadc_probe()
210 if (IS_ERR(tscadc->regmap)) { in ti_tscadc_probe()
211 dev_err(&pdev->dev, "regmap init failed\n"); in ti_tscadc_probe()
212 return PTR_ERR(tscadc->regmap); in ti_tscadc_probe()
215 spin_lock_init(&tscadc->reg_lock); in ti_tscadc_probe()
216 init_waitqueue_head(&tscadc->reg_se_wait); in ti_tscadc_probe()
218 pm_runtime_enable(&pdev->dev); in ti_tscadc_probe()
219 pm_runtime_get_sync(&pdev->dev); in ti_tscadc_probe()
223 * ADCs produce a 12-bit sample every 15 ADC_CLK cycles. in ti_tscadc_probe()
226 * We need ADC clocks respectively running at 3MHz and 13MHz. in ti_tscadc_probe()
228 * assumes the OCP clock is at least 6x faster than the ADC clock. in ti_tscadc_probe()
230 clk = devm_clk_get(&pdev->dev, NULL); in ti_tscadc_probe()
231 if (IS_ERR(clk)) { in ti_tscadc_probe()
232 dev_err(&pdev->dev, "failed to get fck\n"); in ti_tscadc_probe()
233 err = PTR_ERR(clk); in ti_tscadc_probe()
237 tscadc->clk_div = (clk_get_rate(clk) / tscadc->data->target_clk_rate) - 1; in ti_tscadc_probe()
238 regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div); in ti_tscadc_probe()
241 * Set the control register bits. tscadc->ctrl stores the configuration in ti_tscadc_probe()
245 tscadc->ctrl = CNTRLREG_STEPID; in ti_tscadc_probe()
247 tscadc->ctrl |= CNTRLREG_TSC_STEPCONFIGWRT; in ti_tscadc_probe()
249 tscadc->ctrl |= CNTRLREG_TSC_ENB; in ti_tscadc_probe()
251 tscadc->ctrl |= CNTRLREG_TSC_5WIRE; in ti_tscadc_probe()
253 tscadc->ctrl |= CNTRLREG_TSC_4WIRE; in ti_tscadc_probe()
256 tscadc->ctrl |= CNTRLREG_MAG_PREAMP_PWRDOWN | in ti_tscadc_probe()
259 regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl); in ti_tscadc_probe()
264 regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl | CNTRLREG_SSENB); in ti_tscadc_probe()
268 cell = &tscadc->cells[cell_idx++]; in ti_tscadc_probe()
269 cell->name = tscadc->data->secondary_feature_name; in ti_tscadc_probe()
270 cell->of_compatible = tscadc->data->secondary_feature_compatible; in ti_tscadc_probe()
271 cell->platform_data = &tscadc; in ti_tscadc_probe()
272 cell->pdata_size = sizeof(tscadc); in ti_tscadc_probe()
275 /* ADC Cell */ in ti_tscadc_probe()
277 cell = &tscadc->cells[cell_idx++]; in ti_tscadc_probe()
278 cell->name = tscadc->data->adc_feature_name; in ti_tscadc_probe()
279 cell->of_compatible = tscadc->data->adc_feature_compatible; in ti_tscadc_probe()
280 cell->platform_data = &tscadc; in ti_tscadc_probe()
281 cell->pdata_size = sizeof(tscadc); in ti_tscadc_probe()
284 err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, in ti_tscadc_probe()
285 tscadc->cells, cell_idx, NULL, 0, NULL); in ti_tscadc_probe()
293 pm_runtime_put_sync(&pdev->dev); in ti_tscadc_probe()
294 pm_runtime_disable(&pdev->dev); in ti_tscadc_probe()
303 regmap_write(tscadc->regmap, REG_SE, 0x00); in ti_tscadc_remove()
305 pm_runtime_put_sync(&pdev->dev); in ti_tscadc_remove()
306 pm_runtime_disable(&pdev->dev); in ti_tscadc_remove()
308 mfd_remove_devices(tscadc->dev); in ti_tscadc_remove()
320 regmap_write(tscadc->regmap, REG_SE, 0x00); in tscadc_suspend()
324 regmap_read(tscadc->regmap, REG_CTRL, &ctrl); in tscadc_suspend()
327 regmap_write(tscadc->regmap, REG_CTRL, ctrl); in tscadc_suspend()
340 regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div); in tscadc_resume()
341 regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl); in tscadc_resume()
343 regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl | CNTRLREG_SSENB); in tscadc_resume()
351 .adc_feature_name = "TI-am335x-adc",
352 .adc_feature_compatible = "ti,am3359-adc",
353 .secondary_feature_name = "TI-am335x-tsc",
354 .secondary_feature_compatible = "ti,am3359-tsc",
359 .adc_feature_name = "TI-am43xx-adc",
360 .adc_feature_compatible = "ti,am4372-adc",
361 .secondary_feature_name = "TI-am43xx-mag",
362 .secondary_feature_compatible = "ti,am4372-mag",
367 { .compatible = "ti,am3359-tscadc", .data = &tscdata },
368 { .compatible = "ti,am4372-magadc", .data = &magdata },
375 .name = "ti_am3359-tscadc",
386 MODULE_DESCRIPTION("TI touchscreen/magnetic stripe reader/ADC MFD controller driver");