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/
8 #include <linux/module.h>
9 #include <linux/slab.h>
10 #include <linux/err.h>
12 #include <linux/clk.h>
13 #include <linux/regmap.h>
14 #include <linux/mfd/core.h>
15 #include <linux/pm_runtime.h>
17 #include <linux/platform_device.h>
18 #include <linux/sched.h>
20 #include <linux/mfd/ti_am335x_tscadc.h>
22 static const struct regmap_config tscadc_regmap_config
= {
29 void am335x_tsc_se_set_cache(struct ti_tscadc_dev
*tscadc
, u32 val
)
33 spin_lock_irqsave(&tscadc
->reg_lock
, flags
);
34 tscadc
->reg_se_cache
|= val
;
35 if (tscadc
->adc_waiting
)
36 wake_up(&tscadc
->reg_se_wait
);
37 else if (!tscadc
->adc_in_use
)
38 regmap_write(tscadc
->regmap
, REG_SE
, tscadc
->reg_se_cache
);
40 spin_unlock_irqrestore(&tscadc
->reg_lock
, flags
);
42 EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache
);
44 static void am335x_tscadc_need_adc(struct ti_tscadc_dev
*tscadc
)
49 regmap_read(tscadc
->regmap
, REG_ADCFSM
, ®
);
50 if (reg
& SEQ_STATUS
) {
51 tscadc
->adc_waiting
= true;
52 prepare_to_wait(&tscadc
->reg_se_wait
, &wait
,
53 TASK_UNINTERRUPTIBLE
);
54 spin_unlock_irq(&tscadc
->reg_lock
);
58 spin_lock_irq(&tscadc
->reg_lock
);
59 finish_wait(&tscadc
->reg_se_wait
, &wait
);
62 * Sequencer should either be idle or
63 * busy applying the charge step.
65 regmap_read(tscadc
->regmap
, REG_ADCFSM
, ®
);
66 WARN_ON((reg
& SEQ_STATUS
) && !(reg
& CHARGE_STEP
));
67 tscadc
->adc_waiting
= false;
69 tscadc
->adc_in_use
= true;
72 void am335x_tsc_se_set_once(struct ti_tscadc_dev
*tscadc
, u32 val
)
74 spin_lock_irq(&tscadc
->reg_lock
);
75 am335x_tscadc_need_adc(tscadc
);
77 regmap_write(tscadc
->regmap
, REG_SE
, val
);
78 spin_unlock_irq(&tscadc
->reg_lock
);
80 EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once
);
82 void am335x_tsc_se_adc_done(struct ti_tscadc_dev
*tscadc
)
86 spin_lock_irqsave(&tscadc
->reg_lock
, flags
);
87 tscadc
->adc_in_use
= false;
88 regmap_write(tscadc
->regmap
, REG_SE
, tscadc
->reg_se_cache
);
89 spin_unlock_irqrestore(&tscadc
->reg_lock
, flags
);
91 EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done
);
93 void am335x_tsc_se_clr(struct ti_tscadc_dev
*tscadc
, u32 val
)
97 spin_lock_irqsave(&tscadc
->reg_lock
, flags
);
98 tscadc
->reg_se_cache
&= ~val
;
99 regmap_write(tscadc
->regmap
, REG_SE
, tscadc
->reg_se_cache
);
100 spin_unlock_irqrestore(&tscadc
->reg_lock
, flags
);
102 EXPORT_SYMBOL_GPL(am335x_tsc_se_clr
);
104 static void tscadc_idle_config(struct ti_tscadc_dev
*tscadc
)
106 unsigned int idleconfig
;
108 idleconfig
= STEPCONFIG_INM_ADCREFM
| STEPCONFIG_INP_ADCREFM
;
109 if (ti_adc_with_touchscreen(tscadc
))
110 idleconfig
|= STEPCONFIG_YNN
| STEPCONFIG_YPN
;
112 regmap_write(tscadc
->regmap
, REG_IDLECONFIG
, idleconfig
);
115 static int ti_tscadc_probe(struct platform_device
*pdev
)
117 struct ti_tscadc_dev
*tscadc
;
118 struct resource
*res
;
120 struct device_node
*node
;
121 struct mfd_cell
*cell
;
122 bool use_tsc
= false, use_mag
= false;
125 int tscmag_wires
= 0, adc_channels
= 0, cell_idx
= 0, total_channels
;
126 int readouts
= 0, mag_tracks
= 0;
128 /* Allocate memory for device */
129 tscadc
= devm_kzalloc(&pdev
->dev
, sizeof(*tscadc
), GFP_KERNEL
);
133 tscadc
->dev
= &pdev
->dev
;
135 if (!pdev
->dev
.of_node
) {
136 dev_err(&pdev
->dev
, "Could not find valid DT data.\n");
140 tscadc
->data
= of_device_get_match_data(&pdev
->dev
);
142 if (ti_adc_with_touchscreen(tscadc
)) {
143 node
= of_get_child_by_name(pdev
->dev
.of_node
, "tsc");
144 of_property_read_u32(node
, "ti,wires", &tscmag_wires
);
145 err
= of_property_read_u32(node
, "ti,coordinate-readouts",
148 of_property_read_u32(node
, "ti,coordiante-readouts",
157 * When adding support for the magnetic stripe reader, here is
158 * the place to look for the number of tracks used from device
159 * tree. Let's default to 0 for now.
162 tscmag_wires
= mag_tracks
* 2;
167 node
= of_get_child_by_name(pdev
->dev
.of_node
, "adc");
168 of_property_for_each_u32(node
, "ti,adc-channels", val
) {
171 dev_err(&pdev
->dev
, " PIN numbers are 0..7 (not %d)\n",
180 total_channels
= tscmag_wires
+ adc_channels
;
181 if (total_channels
> 8) {
182 dev_err(&pdev
->dev
, "Number of i/p channels more than 8\n");
186 if (total_channels
== 0) {
187 dev_err(&pdev
->dev
, "Need at least one channel.\n");
191 if (use_tsc
&& (readouts
* 2 + 2 + adc_channels
> 16)) {
192 dev_err(&pdev
->dev
, "Too many step configurations requested\n");
196 err
= platform_get_irq(pdev
, 0);
202 tscadc
->tscadc_base
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
203 if (IS_ERR(tscadc
->tscadc_base
))
204 return PTR_ERR(tscadc
->tscadc_base
);
206 tscadc
->tscadc_phys_base
= res
->start
;
207 tscadc
->regmap
= devm_regmap_init_mmio(&pdev
->dev
,
209 &tscadc_regmap_config
);
210 if (IS_ERR(tscadc
->regmap
)) {
211 dev_err(&pdev
->dev
, "regmap init failed\n");
212 return PTR_ERR(tscadc
->regmap
);
215 spin_lock_init(&tscadc
->reg_lock
);
216 init_waitqueue_head(&tscadc
->reg_se_wait
);
218 pm_runtime_enable(&pdev
->dev
);
219 pm_runtime_get_sync(&pdev
->dev
);
222 * The TSC_ADC_Subsystem has 2 clock domains: OCP_CLK and ADC_CLK.
223 * ADCs produce a 12-bit sample every 15 ADC_CLK cycles.
224 * am33xx ADCs expect to capture 200ksps.
225 * am47xx ADCs expect to capture 867ksps.
226 * We need ADC clocks respectively running at 3MHz and 13MHz.
227 * These frequencies are valid since TSC_ADC_SS controller design
228 * assumes the OCP clock is at least 6x faster than the ADC clock.
230 clk
= devm_clk_get(&pdev
->dev
, NULL
);
232 dev_err(&pdev
->dev
, "failed to get fck\n");
234 goto err_disable_clk
;
237 tscadc
->clk_div
= (clk_get_rate(clk
) / tscadc
->data
->target_clk_rate
) - 1;
238 regmap_write(tscadc
->regmap
, REG_CLKDIV
, tscadc
->clk_div
);
241 * Set the control register bits. tscadc->ctrl stores the configuration
242 * of the CTRL register but not the subsystem enable bit which must be
243 * added manually when timely.
245 tscadc
->ctrl
= CNTRLREG_STEPID
;
246 if (ti_adc_with_touchscreen(tscadc
)) {
247 tscadc
->ctrl
|= CNTRLREG_TSC_STEPCONFIGWRT
;
249 tscadc
->ctrl
|= CNTRLREG_TSC_ENB
;
250 if (tscmag_wires
== 5)
251 tscadc
->ctrl
|= CNTRLREG_TSC_5WIRE
;
253 tscadc
->ctrl
|= CNTRLREG_TSC_4WIRE
;
256 tscadc
->ctrl
|= CNTRLREG_MAG_PREAMP_PWRDOWN
|
257 CNTRLREG_MAG_PREAMP_BYPASS
;
259 regmap_write(tscadc
->regmap
, REG_CTRL
, tscadc
->ctrl
);
261 tscadc_idle_config(tscadc
);
263 /* Enable the TSC module enable bit */
264 regmap_write(tscadc
->regmap
, REG_CTRL
, tscadc
->ctrl
| CNTRLREG_SSENB
);
266 /* TSC or MAG Cell */
267 if (use_tsc
|| use_mag
) {
268 cell
= &tscadc
->cells
[cell_idx
++];
269 cell
->name
= tscadc
->data
->secondary_feature_name
;
270 cell
->of_compatible
= tscadc
->data
->secondary_feature_compatible
;
271 cell
->platform_data
= &tscadc
;
272 cell
->pdata_size
= sizeof(tscadc
);
276 if (adc_channels
> 0) {
277 cell
= &tscadc
->cells
[cell_idx
++];
278 cell
->name
= tscadc
->data
->adc_feature_name
;
279 cell
->of_compatible
= tscadc
->data
->adc_feature_compatible
;
280 cell
->platform_data
= &tscadc
;
281 cell
->pdata_size
= sizeof(tscadc
);
284 err
= mfd_add_devices(&pdev
->dev
, PLATFORM_DEVID_AUTO
,
285 tscadc
->cells
, cell_idx
, NULL
, 0, NULL
);
287 goto err_disable_clk
;
289 platform_set_drvdata(pdev
, tscadc
);
293 pm_runtime_put_sync(&pdev
->dev
);
294 pm_runtime_disable(&pdev
->dev
);
299 static void ti_tscadc_remove(struct platform_device
*pdev
)
301 struct ti_tscadc_dev
*tscadc
= platform_get_drvdata(pdev
);
303 regmap_write(tscadc
->regmap
, REG_SE
, 0x00);
305 pm_runtime_put_sync(&pdev
->dev
);
306 pm_runtime_disable(&pdev
->dev
);
308 mfd_remove_devices(tscadc
->dev
);
311 static int __maybe_unused
ti_tscadc_can_wakeup(struct device
*dev
, void *data
)
313 return device_may_wakeup(dev
);
316 static int __maybe_unused
tscadc_suspend(struct device
*dev
)
318 struct ti_tscadc_dev
*tscadc
= dev_get_drvdata(dev
);
320 regmap_write(tscadc
->regmap
, REG_SE
, 0x00);
321 if (device_for_each_child(dev
, NULL
, ti_tscadc_can_wakeup
)) {
324 regmap_read(tscadc
->regmap
, REG_CTRL
, &ctrl
);
325 ctrl
&= ~(CNTRLREG_POWERDOWN
);
326 ctrl
|= CNTRLREG_SSENB
;
327 regmap_write(tscadc
->regmap
, REG_CTRL
, ctrl
);
329 pm_runtime_put_sync(dev
);
334 static int __maybe_unused
tscadc_resume(struct device
*dev
)
336 struct ti_tscadc_dev
*tscadc
= dev_get_drvdata(dev
);
338 pm_runtime_get_sync(dev
);
340 regmap_write(tscadc
->regmap
, REG_CLKDIV
, tscadc
->clk_div
);
341 regmap_write(tscadc
->regmap
, REG_CTRL
, tscadc
->ctrl
);
342 tscadc_idle_config(tscadc
);
343 regmap_write(tscadc
->regmap
, REG_CTRL
, tscadc
->ctrl
| CNTRLREG_SSENB
);
348 static SIMPLE_DEV_PM_OPS(tscadc_pm_ops
, tscadc_suspend
, tscadc_resume
);
350 static const struct ti_tscadc_data tscdata
= {
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",
355 .target_clk_rate
= TSC_ADC_CLK
,
358 static const struct ti_tscadc_data magdata
= {
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",
363 .target_clk_rate
= MAG_ADC_CLK
,
366 static const struct of_device_id ti_tscadc_dt_ids
[] = {
367 { .compatible
= "ti,am3359-tscadc", .data
= &tscdata
},
368 { .compatible
= "ti,am4372-magadc", .data
= &magdata
},
371 MODULE_DEVICE_TABLE(of
, ti_tscadc_dt_ids
);
373 static struct platform_driver ti_tscadc_driver
= {
375 .name
= "ti_am3359-tscadc",
376 .pm
= &tscadc_pm_ops
,
377 .of_match_table
= ti_tscadc_dt_ids
,
379 .probe
= ti_tscadc_probe
,
380 .remove
= ti_tscadc_remove
,
384 module_platform_driver(ti_tscadc_driver
);
386 MODULE_DESCRIPTION("TI touchscreen/magnetic stripe reader/ADC MFD controller driver");
387 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
388 MODULE_LICENSE("GPL");