1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * TI Touch Screen / ADC MFD driver
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or
7*4882a593Smuzhiyun * modify it under the terms of the GNU General Public License as
8*4882a593Smuzhiyun * published by the Free Software Foundation version 2.
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11*4882a593Smuzhiyun * kind, whether express or implied; without even the implied warranty
12*4882a593Smuzhiyun * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*4882a593Smuzhiyun * GNU General Public License for more details.
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun #include <linux/slab.h>
18*4882a593Smuzhiyun #include <linux/err.h>
19*4882a593Smuzhiyun #include <linux/io.h>
20*4882a593Smuzhiyun #include <linux/clk.h>
21*4882a593Smuzhiyun #include <linux/regmap.h>
22*4882a593Smuzhiyun #include <linux/mfd/core.h>
23*4882a593Smuzhiyun #include <linux/pm_runtime.h>
24*4882a593Smuzhiyun #include <linux/of.h>
25*4882a593Smuzhiyun #include <linux/of_device.h>
26*4882a593Smuzhiyun #include <linux/sched.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #include <linux/mfd/ti_am335x_tscadc.h>
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun static const struct regmap_config tscadc_regmap_config = {
31*4882a593Smuzhiyun .name = "ti_tscadc",
32*4882a593Smuzhiyun .reg_bits = 32,
33*4882a593Smuzhiyun .reg_stride = 4,
34*4882a593Smuzhiyun .val_bits = 32,
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun
am335x_tsc_se_set_cache(struct ti_tscadc_dev * tscadc,u32 val)37*4882a593Smuzhiyun void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tscadc, u32 val)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun unsigned long flags;
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun spin_lock_irqsave(&tscadc->reg_lock, flags);
42*4882a593Smuzhiyun tscadc->reg_se_cache |= val;
43*4882a593Smuzhiyun if (tscadc->adc_waiting)
44*4882a593Smuzhiyun wake_up(&tscadc->reg_se_wait);
45*4882a593Smuzhiyun else if (!tscadc->adc_in_use)
46*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun spin_unlock_irqrestore(&tscadc->reg_lock, flags);
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache);
51*4882a593Smuzhiyun
am335x_tscadc_need_adc(struct ti_tscadc_dev * tscadc)52*4882a593Smuzhiyun static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tscadc)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun DEFINE_WAIT(wait);
55*4882a593Smuzhiyun u32 reg;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun regmap_read(tscadc->regmap, REG_ADCFSM, ®);
58*4882a593Smuzhiyun if (reg & SEQ_STATUS) {
59*4882a593Smuzhiyun tscadc->adc_waiting = true;
60*4882a593Smuzhiyun prepare_to_wait(&tscadc->reg_se_wait, &wait,
61*4882a593Smuzhiyun TASK_UNINTERRUPTIBLE);
62*4882a593Smuzhiyun spin_unlock_irq(&tscadc->reg_lock);
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun schedule();
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun spin_lock_irq(&tscadc->reg_lock);
67*4882a593Smuzhiyun finish_wait(&tscadc->reg_se_wait, &wait);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /*
70*4882a593Smuzhiyun * Sequencer should either be idle or
71*4882a593Smuzhiyun * busy applying the charge step.
72*4882a593Smuzhiyun */
73*4882a593Smuzhiyun regmap_read(tscadc->regmap, REG_ADCFSM, ®);
74*4882a593Smuzhiyun WARN_ON((reg & SEQ_STATUS) && !(reg & CHARGE_STEP));
75*4882a593Smuzhiyun tscadc->adc_waiting = false;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun tscadc->adc_in_use = true;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun
am335x_tsc_se_set_once(struct ti_tscadc_dev * tscadc,u32 val)80*4882a593Smuzhiyun void am335x_tsc_se_set_once(struct ti_tscadc_dev *tscadc, u32 val)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun spin_lock_irq(&tscadc->reg_lock);
83*4882a593Smuzhiyun am335x_tscadc_need_adc(tscadc);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_SE, val);
86*4882a593Smuzhiyun spin_unlock_irq(&tscadc->reg_lock);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once);
89*4882a593Smuzhiyun
am335x_tsc_se_adc_done(struct ti_tscadc_dev * tscadc)90*4882a593Smuzhiyun void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tscadc)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun unsigned long flags;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun spin_lock_irqsave(&tscadc->reg_lock, flags);
95*4882a593Smuzhiyun tscadc->adc_in_use = false;
96*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
97*4882a593Smuzhiyun spin_unlock_irqrestore(&tscadc->reg_lock, flags);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done);
100*4882a593Smuzhiyun
am335x_tsc_se_clr(struct ti_tscadc_dev * tscadc,u32 val)101*4882a593Smuzhiyun void am335x_tsc_se_clr(struct ti_tscadc_dev *tscadc, u32 val)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun unsigned long flags;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun spin_lock_irqsave(&tscadc->reg_lock, flags);
106*4882a593Smuzhiyun tscadc->reg_se_cache &= ~val;
107*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
108*4882a593Smuzhiyun spin_unlock_irqrestore(&tscadc->reg_lock, flags);
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
111*4882a593Smuzhiyun
tscadc_idle_config(struct ti_tscadc_dev * tscadc)112*4882a593Smuzhiyun static void tscadc_idle_config(struct ti_tscadc_dev *tscadc)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun unsigned int idleconfig;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun idleconfig = STEPCONFIG_YNN | STEPCONFIG_INM_ADCREFM |
117*4882a593Smuzhiyun STEPCONFIG_INP_ADCREFM | STEPCONFIG_YPN;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_IDLECONFIG, idleconfig);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
ti_tscadc_probe(struct platform_device * pdev)122*4882a593Smuzhiyun static int ti_tscadc_probe(struct platform_device *pdev)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun struct ti_tscadc_dev *tscadc;
125*4882a593Smuzhiyun struct resource *res;
126*4882a593Smuzhiyun struct clk *clk;
127*4882a593Smuzhiyun struct device_node *node;
128*4882a593Smuzhiyun struct mfd_cell *cell;
129*4882a593Smuzhiyun struct property *prop;
130*4882a593Smuzhiyun const __be32 *cur;
131*4882a593Smuzhiyun u32 val;
132*4882a593Smuzhiyun int err, ctrl;
133*4882a593Smuzhiyun int clock_rate;
134*4882a593Smuzhiyun int tsc_wires = 0, adc_channels = 0, total_channels;
135*4882a593Smuzhiyun int readouts = 0;
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if (!pdev->dev.of_node) {
138*4882a593Smuzhiyun dev_err(&pdev->dev, "Could not find valid DT data.\n");
139*4882a593Smuzhiyun return -EINVAL;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun node = of_get_child_by_name(pdev->dev.of_node, "tsc");
143*4882a593Smuzhiyun of_property_read_u32(node, "ti,wires", &tsc_wires);
144*4882a593Smuzhiyun of_property_read_u32(node, "ti,coordiante-readouts", &readouts);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun node = of_get_child_by_name(pdev->dev.of_node, "adc");
147*4882a593Smuzhiyun of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
148*4882a593Smuzhiyun adc_channels++;
149*4882a593Smuzhiyun if (val > 7) {
150*4882a593Smuzhiyun dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n",
151*4882a593Smuzhiyun val);
152*4882a593Smuzhiyun return -EINVAL;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun total_channels = tsc_wires + adc_channels;
156*4882a593Smuzhiyun if (total_channels > 8) {
157*4882a593Smuzhiyun dev_err(&pdev->dev, "Number of i/p channels more than 8\n");
158*4882a593Smuzhiyun return -EINVAL;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun if (total_channels == 0) {
161*4882a593Smuzhiyun dev_err(&pdev->dev, "Need atleast one channel.\n");
162*4882a593Smuzhiyun return -EINVAL;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun if (readouts * 2 + 2 + adc_channels > 16) {
166*4882a593Smuzhiyun dev_err(&pdev->dev, "Too many step configurations requested\n");
167*4882a593Smuzhiyun return -EINVAL;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun /* Allocate memory for device */
171*4882a593Smuzhiyun tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
172*4882a593Smuzhiyun if (!tscadc)
173*4882a593Smuzhiyun return -ENOMEM;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun tscadc->dev = &pdev->dev;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun err = platform_get_irq(pdev, 0);
178*4882a593Smuzhiyun if (err < 0) {
179*4882a593Smuzhiyun dev_err(&pdev->dev, "no irq ID is specified.\n");
180*4882a593Smuzhiyun goto ret;
181*4882a593Smuzhiyun } else
182*4882a593Smuzhiyun tscadc->irq = err;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
185*4882a593Smuzhiyun tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
186*4882a593Smuzhiyun if (IS_ERR(tscadc->tscadc_base))
187*4882a593Smuzhiyun return PTR_ERR(tscadc->tscadc_base);
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun tscadc->tscadc_phys_base = res->start;
190*4882a593Smuzhiyun tscadc->regmap = devm_regmap_init_mmio(&pdev->dev,
191*4882a593Smuzhiyun tscadc->tscadc_base, &tscadc_regmap_config);
192*4882a593Smuzhiyun if (IS_ERR(tscadc->regmap)) {
193*4882a593Smuzhiyun dev_err(&pdev->dev, "regmap init failed\n");
194*4882a593Smuzhiyun err = PTR_ERR(tscadc->regmap);
195*4882a593Smuzhiyun goto ret;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun spin_lock_init(&tscadc->reg_lock);
199*4882a593Smuzhiyun init_waitqueue_head(&tscadc->reg_se_wait);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun pm_runtime_enable(&pdev->dev);
202*4882a593Smuzhiyun pm_runtime_get_sync(&pdev->dev);
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun /*
205*4882a593Smuzhiyun * The TSC_ADC_Subsystem has 2 clock domains
206*4882a593Smuzhiyun * OCP_CLK and ADC_CLK.
207*4882a593Smuzhiyun * The ADC clock is expected to run at target of 3MHz,
208*4882a593Smuzhiyun * and expected to capture 12-bit data at a rate of 200 KSPS.
209*4882a593Smuzhiyun * The TSC_ADC_SS controller design assumes the OCP clock is
210*4882a593Smuzhiyun * at least 6x faster than the ADC clock.
211*4882a593Smuzhiyun */
212*4882a593Smuzhiyun clk = devm_clk_get(&pdev->dev, "adc_tsc_fck");
213*4882a593Smuzhiyun if (IS_ERR(clk)) {
214*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get TSC fck\n");
215*4882a593Smuzhiyun err = PTR_ERR(clk);
216*4882a593Smuzhiyun goto err_disable_clk;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun clock_rate = clk_get_rate(clk);
219*4882a593Smuzhiyun tscadc->clk_div = clock_rate / ADC_CLK;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun /* TSCADC_CLKDIV needs to be configured to the value minus 1 */
222*4882a593Smuzhiyun tscadc->clk_div--;
223*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /* Set the control register bits */
226*4882a593Smuzhiyun ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID;
227*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_CTRL, ctrl);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun /* Set register bits for Idle Config Mode */
230*4882a593Smuzhiyun if (tsc_wires > 0) {
231*4882a593Smuzhiyun tscadc->tsc_wires = tsc_wires;
232*4882a593Smuzhiyun if (tsc_wires == 5)
233*4882a593Smuzhiyun ctrl |= CNTRLREG_5WIRE | CNTRLREG_TSCENB;
234*4882a593Smuzhiyun else
235*4882a593Smuzhiyun ctrl |= CNTRLREG_4WIRE | CNTRLREG_TSCENB;
236*4882a593Smuzhiyun tscadc_idle_config(tscadc);
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun /* Enable the TSC module enable bit */
240*4882a593Smuzhiyun ctrl |= CNTRLREG_TSCSSENB;
241*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_CTRL, ctrl);
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun tscadc->used_cells = 0;
244*4882a593Smuzhiyun tscadc->tsc_cell = -1;
245*4882a593Smuzhiyun tscadc->adc_cell = -1;
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun /* TSC Cell */
248*4882a593Smuzhiyun if (tsc_wires > 0) {
249*4882a593Smuzhiyun tscadc->tsc_cell = tscadc->used_cells;
250*4882a593Smuzhiyun cell = &tscadc->cells[tscadc->used_cells++];
251*4882a593Smuzhiyun cell->name = "TI-am335x-tsc";
252*4882a593Smuzhiyun cell->of_compatible = "ti,am3359-tsc";
253*4882a593Smuzhiyun cell->platform_data = &tscadc;
254*4882a593Smuzhiyun cell->pdata_size = sizeof(tscadc);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun /* ADC Cell */
258*4882a593Smuzhiyun if (adc_channels > 0) {
259*4882a593Smuzhiyun tscadc->adc_cell = tscadc->used_cells;
260*4882a593Smuzhiyun cell = &tscadc->cells[tscadc->used_cells++];
261*4882a593Smuzhiyun cell->name = "TI-am335x-adc";
262*4882a593Smuzhiyun cell->of_compatible = "ti,am3359-adc";
263*4882a593Smuzhiyun cell->platform_data = &tscadc;
264*4882a593Smuzhiyun cell->pdata_size = sizeof(tscadc);
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
268*4882a593Smuzhiyun tscadc->cells, tscadc->used_cells, NULL,
269*4882a593Smuzhiyun 0, NULL);
270*4882a593Smuzhiyun if (err < 0)
271*4882a593Smuzhiyun goto err_disable_clk;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun platform_set_drvdata(pdev, tscadc);
274*4882a593Smuzhiyun return 0;
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun err_disable_clk:
277*4882a593Smuzhiyun pm_runtime_put_sync(&pdev->dev);
278*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
279*4882a593Smuzhiyun ret:
280*4882a593Smuzhiyun return err;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
ti_tscadc_remove(struct platform_device * pdev)283*4882a593Smuzhiyun static int ti_tscadc_remove(struct platform_device *pdev)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun struct ti_tscadc_dev *tscadc = platform_get_drvdata(pdev);
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_SE, 0x00);
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun pm_runtime_put_sync(&pdev->dev);
290*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun mfd_remove_devices(tscadc->dev);
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun return 0;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
ti_tscadc_can_wakeup(struct device * dev,void * data)297*4882a593Smuzhiyun static int __maybe_unused ti_tscadc_can_wakeup(struct device *dev, void *data)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun return device_may_wakeup(dev);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
tscadc_suspend(struct device * dev)302*4882a593Smuzhiyun static int __maybe_unused tscadc_suspend(struct device *dev)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_SE, 0x00);
307*4882a593Smuzhiyun if (device_for_each_child(dev, NULL, ti_tscadc_can_wakeup)) {
308*4882a593Smuzhiyun u32 ctrl;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun regmap_read(tscadc->regmap, REG_CTRL, &ctrl);
311*4882a593Smuzhiyun ctrl &= ~(CNTRLREG_POWERDOWN);
312*4882a593Smuzhiyun ctrl |= CNTRLREG_TSCSSENB;
313*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_CTRL, ctrl);
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun pm_runtime_put_sync(dev);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun return 0;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
tscadc_resume(struct device * dev)320*4882a593Smuzhiyun static int __maybe_unused tscadc_resume(struct device *dev)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
323*4882a593Smuzhiyun u32 ctrl;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun pm_runtime_get_sync(dev);
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun /* context restore */
328*4882a593Smuzhiyun ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID;
329*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_CTRL, ctrl);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun if (tscadc->tsc_cell != -1) {
332*4882a593Smuzhiyun if (tscadc->tsc_wires == 5)
333*4882a593Smuzhiyun ctrl |= CNTRLREG_5WIRE | CNTRLREG_TSCENB;
334*4882a593Smuzhiyun else
335*4882a593Smuzhiyun ctrl |= CNTRLREG_4WIRE | CNTRLREG_TSCENB;
336*4882a593Smuzhiyun tscadc_idle_config(tscadc);
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun ctrl |= CNTRLREG_TSCSSENB;
339*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_CTRL, ctrl);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun return 0;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume);
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun static const struct of_device_id ti_tscadc_dt_ids[] = {
349*4882a593Smuzhiyun { .compatible = "ti,am3359-tscadc", },
350*4882a593Smuzhiyun { }
351*4882a593Smuzhiyun };
352*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun static struct platform_driver ti_tscadc_driver = {
355*4882a593Smuzhiyun .driver = {
356*4882a593Smuzhiyun .name = "ti_am3359-tscadc",
357*4882a593Smuzhiyun .pm = &tscadc_pm_ops,
358*4882a593Smuzhiyun .of_match_table = ti_tscadc_dt_ids,
359*4882a593Smuzhiyun },
360*4882a593Smuzhiyun .probe = ti_tscadc_probe,
361*4882a593Smuzhiyun .remove = ti_tscadc_remove,
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun };
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun module_platform_driver(ti_tscadc_driver);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun MODULE_DESCRIPTION("TI touchscreen / ADC MFD controller driver");
368*4882a593Smuzhiyun MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
369*4882a593Smuzhiyun MODULE_LICENSE("GPL");
370