1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
5 * This is the driver for the imx25 GCQ (Generic Conversion Queue)
6 * connected to the imx25 ADC.
9 #include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
10 #include <linux/clk.h>
11 #include <linux/iio/iio.h>
12 #include <linux/interrupt.h>
13 #include <linux/mfd/imx25-tsadc.h>
14 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
20 #define MX25_GCQ_TIMEOUT (msecs_to_jiffies(2000))
22 static const char * const driver_name
= "mx25-gcq";
36 struct mx25_gcq_priv
{
38 struct completion completed
;
41 struct regulator
*vref
[4];
42 u32 channel_vref_mv
[MX25_NUM_CFGS
];
45 #define MX25_CQG_CHAN(chan, id) {\
49 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
50 BIT(IIO_CHAN_INFO_SCALE),\
51 .datasheet_name = id,\
54 static const struct iio_chan_spec mx25_gcq_channels
[MX25_NUM_CFGS
] = {
55 MX25_CQG_CHAN(MX25_CFG_XP
, "xp"),
56 MX25_CQG_CHAN(MX25_CFG_YP
, "yp"),
57 MX25_CQG_CHAN(MX25_CFG_XN
, "xn"),
58 MX25_CQG_CHAN(MX25_CFG_YN
, "yn"),
59 MX25_CQG_CHAN(MX25_CFG_WIPER
, "wiper"),
60 MX25_CQG_CHAN(MX25_CFG_INAUX0
, "inaux0"),
61 MX25_CQG_CHAN(MX25_CFG_INAUX1
, "inaux1"),
62 MX25_CQG_CHAN(MX25_CFG_INAUX2
, "inaux2"),
65 static const char * const mx25_gcq_refp_names
[] = {
66 [MX25_ADC_REFP_YP
] = "yp",
67 [MX25_ADC_REFP_XP
] = "xp",
68 [MX25_ADC_REFP_INT
] = "int",
69 [MX25_ADC_REFP_EXT
] = "ext",
72 static irqreturn_t
mx25_gcq_irq(int irq
, void *data
)
74 struct mx25_gcq_priv
*priv
= data
;
77 regmap_read(priv
->regs
, MX25_ADCQ_SR
, &stats
);
79 if (stats
& MX25_ADCQ_SR_EOQ
) {
80 regmap_update_bits(priv
->regs
, MX25_ADCQ_MR
,
81 MX25_ADCQ_MR_EOQ_IRQ
, MX25_ADCQ_MR_EOQ_IRQ
);
82 complete(&priv
->completed
);
85 /* Disable conversion queue run */
86 regmap_update_bits(priv
->regs
, MX25_ADCQ_CR
, MX25_ADCQ_CR_FQS
, 0);
88 /* Acknowledge all possible irqs */
89 regmap_write(priv
->regs
, MX25_ADCQ_SR
, MX25_ADCQ_SR_FRR
|
90 MX25_ADCQ_SR_FUR
| MX25_ADCQ_SR_FOR
|
91 MX25_ADCQ_SR_EOQ
| MX25_ADCQ_SR_PD
);
96 static int mx25_gcq_get_raw_value(struct device
*dev
,
97 struct iio_chan_spec
const *chan
,
98 struct mx25_gcq_priv
*priv
,
104 /* Setup the configuration we want to use */
105 regmap_write(priv
->regs
, MX25_ADCQ_ITEM_7_0
,
106 MX25_ADCQ_ITEM(0, chan
->channel
));
108 regmap_update_bits(priv
->regs
, MX25_ADCQ_MR
, MX25_ADCQ_MR_EOQ_IRQ
, 0);
110 /* Trigger queue for one run */
111 regmap_update_bits(priv
->regs
, MX25_ADCQ_CR
, MX25_ADCQ_CR_FQS
,
114 timeout
= wait_for_completion_interruptible_timeout(
115 &priv
->completed
, MX25_GCQ_TIMEOUT
);
117 dev_err(dev
, "ADC wait for measurement failed\n");
119 } else if (timeout
== 0) {
120 dev_err(dev
, "ADC timed out\n");
124 regmap_read(priv
->regs
, MX25_ADCQ_FIFO
, &data
);
126 *val
= MX25_ADCQ_FIFO_DATA(data
);
131 static int mx25_gcq_read_raw(struct iio_dev
*indio_dev
,
132 struct iio_chan_spec
const *chan
, int *val
,
133 int *val2
, long mask
)
135 struct mx25_gcq_priv
*priv
= iio_priv(indio_dev
);
139 case IIO_CHAN_INFO_RAW
:
140 mutex_lock(&indio_dev
->mlock
);
141 ret
= mx25_gcq_get_raw_value(&indio_dev
->dev
, chan
, priv
, val
);
142 mutex_unlock(&indio_dev
->mlock
);
145 case IIO_CHAN_INFO_SCALE
:
146 *val
= priv
->channel_vref_mv
[chan
->channel
];
148 return IIO_VAL_FRACTIONAL_LOG2
;
155 static const struct iio_info mx25_gcq_iio_info
= {
156 .read_raw
= mx25_gcq_read_raw
,
159 static const struct regmap_config mx25_gcq_regconfig
= {
160 .max_register
= 0x5c,
166 static int mx25_gcq_setup_cfgs(struct platform_device
*pdev
,
167 struct mx25_gcq_priv
*priv
)
169 struct device_node
*np
= pdev
->dev
.of_node
;
170 struct device_node
*child
;
171 struct device
*dev
= &pdev
->dev
;
172 unsigned int refp_used
[4] = {};
176 * Setup all configurations registers with a default conversion
177 * configuration for each input
179 for (i
= 0; i
< MX25_NUM_CFGS
; ++i
)
180 regmap_write(priv
->regs
, MX25_ADCQ_CFG(i
),
181 MX25_ADCQ_CFG_YPLL_OFF
|
182 MX25_ADCQ_CFG_XNUR_OFF
|
183 MX25_ADCQ_CFG_XPUL_OFF
|
184 MX25_ADCQ_CFG_REFP_INT
|
185 MX25_ADCQ_CFG_IN(i
) |
186 MX25_ADCQ_CFG_REFN_NGND2
);
189 * First get all regulators to store them in channel_vref_mv if
190 * necessary. Later we use that information for proper IIO scale
193 priv
->vref
[MX25_ADC_REFP_INT
] = NULL
;
194 priv
->vref
[MX25_ADC_REFP_EXT
] =
195 devm_regulator_get_optional(&pdev
->dev
, "vref-ext");
196 priv
->vref
[MX25_ADC_REFP_XP
] =
197 devm_regulator_get_optional(&pdev
->dev
, "vref-xp");
198 priv
->vref
[MX25_ADC_REFP_YP
] =
199 devm_regulator_get_optional(&pdev
->dev
, "vref-yp");
201 for_each_child_of_node(np
, child
) {
203 u32 refp
= MX25_ADCQ_CFG_REFP_INT
;
204 u32 refn
= MX25_ADCQ_CFG_REFN_NGND2
;
206 ret
= of_property_read_u32(child
, "reg", ®
);
208 dev_err(dev
, "Failed to get reg property\n");
213 if (reg
>= MX25_NUM_CFGS
) {
215 "reg value is greater than the number of available configuration registers\n");
220 of_property_read_u32(child
, "fsl,adc-refp", &refp
);
221 of_property_read_u32(child
, "fsl,adc-refn", &refn
);
224 case MX25_ADC_REFP_EXT
:
225 case MX25_ADC_REFP_XP
:
226 case MX25_ADC_REFP_YP
:
227 if (IS_ERR(priv
->vref
[refp
])) {
228 dev_err(dev
, "Error, trying to use external voltage reference without a vref-%s regulator.",
229 mx25_gcq_refp_names
[refp
]);
231 return PTR_ERR(priv
->vref
[refp
]);
233 priv
->channel_vref_mv
[reg
] =
234 regulator_get_voltage(priv
->vref
[refp
]);
235 /* Conversion from uV to mV */
236 priv
->channel_vref_mv
[reg
] /= 1000;
238 case MX25_ADC_REFP_INT
:
239 priv
->channel_vref_mv
[reg
] = 2500;
242 dev_err(dev
, "Invalid positive reference %d\n", refp
);
250 * Shift the read values to the correct positions within the
253 refp
= MX25_ADCQ_CFG_REFP(refp
);
254 refn
= MX25_ADCQ_CFG_REFN(refn
);
256 if ((refp
& MX25_ADCQ_CFG_REFP_MASK
) != refp
) {
257 dev_err(dev
, "Invalid fsl,adc-refp property value\n");
261 if ((refn
& MX25_ADCQ_CFG_REFN_MASK
) != refn
) {
262 dev_err(dev
, "Invalid fsl,adc-refn property value\n");
267 regmap_update_bits(priv
->regs
, MX25_ADCQ_CFG(reg
),
268 MX25_ADCQ_CFG_REFP_MASK
|
269 MX25_ADCQ_CFG_REFN_MASK
,
272 regmap_update_bits(priv
->regs
, MX25_ADCQ_CR
,
273 MX25_ADCQ_CR_FRST
| MX25_ADCQ_CR_QRST
,
274 MX25_ADCQ_CR_FRST
| MX25_ADCQ_CR_QRST
);
276 regmap_write(priv
->regs
, MX25_ADCQ_CR
,
277 MX25_ADCQ_CR_PDMSK
| MX25_ADCQ_CR_QSM_FQS
);
279 /* Remove unused regulators */
280 for (i
= 0; i
!= 4; ++i
) {
282 if (!IS_ERR_OR_NULL(priv
->vref
[i
]))
283 devm_regulator_put(priv
->vref
[i
]);
284 priv
->vref
[i
] = NULL
;
291 static int mx25_gcq_probe(struct platform_device
*pdev
)
293 struct iio_dev
*indio_dev
;
294 struct mx25_gcq_priv
*priv
;
295 struct mx25_tsadc
*tsadc
= dev_get_drvdata(pdev
->dev
.parent
);
296 struct device
*dev
= &pdev
->dev
;
297 struct resource
*res
;
302 indio_dev
= devm_iio_device_alloc(&pdev
->dev
, sizeof(*priv
));
306 priv
= iio_priv(indio_dev
);
308 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
309 mem
= devm_ioremap_resource(dev
, res
);
313 priv
->regs
= devm_regmap_init_mmio(dev
, mem
, &mx25_gcq_regconfig
);
314 if (IS_ERR(priv
->regs
)) {
315 dev_err(dev
, "Failed to initialize regmap\n");
316 return PTR_ERR(priv
->regs
);
319 init_completion(&priv
->completed
);
321 ret
= mx25_gcq_setup_cfgs(pdev
, priv
);
325 for (i
= 0; i
!= 4; ++i
) {
329 ret
= regulator_enable(priv
->vref
[i
]);
331 goto err_regulator_disable
;
334 priv
->clk
= tsadc
->clk
;
335 ret
= clk_prepare_enable(priv
->clk
);
337 dev_err(dev
, "Failed to enable clock\n");
338 goto err_vref_disable
;
341 priv
->irq
= platform_get_irq(pdev
, 0);
342 if (priv
->irq
<= 0) {
346 goto err_clk_unprepare
;
349 ret
= request_irq(priv
->irq
, mx25_gcq_irq
, 0, pdev
->name
, priv
);
351 dev_err(dev
, "Failed requesting IRQ\n");
352 goto err_clk_unprepare
;
355 indio_dev
->dev
.parent
= &pdev
->dev
;
356 indio_dev
->channels
= mx25_gcq_channels
;
357 indio_dev
->num_channels
= ARRAY_SIZE(mx25_gcq_channels
);
358 indio_dev
->info
= &mx25_gcq_iio_info
;
359 indio_dev
->name
= driver_name
;
361 ret
= iio_device_register(indio_dev
);
363 dev_err(dev
, "Failed to register iio device\n");
367 platform_set_drvdata(pdev
, indio_dev
);
372 free_irq(priv
->irq
, priv
);
374 clk_disable_unprepare(priv
->clk
);
377 err_regulator_disable
:
380 regulator_disable(priv
->vref
[i
]);
385 static int mx25_gcq_remove(struct platform_device
*pdev
)
387 struct iio_dev
*indio_dev
= platform_get_drvdata(pdev
);
388 struct mx25_gcq_priv
*priv
= iio_priv(indio_dev
);
391 iio_device_unregister(indio_dev
);
392 free_irq(priv
->irq
, priv
);
393 clk_disable_unprepare(priv
->clk
);
394 for (i
= 4; i
-- > 0;) {
396 regulator_disable(priv
->vref
[i
]);
402 static const struct of_device_id mx25_gcq_ids
[] = {
403 { .compatible
= "fsl,imx25-gcq", },
406 MODULE_DEVICE_TABLE(of
, mx25_gcq_ids
);
408 static struct platform_driver mx25_gcq_driver
= {
411 .of_match_table
= mx25_gcq_ids
,
413 .probe
= mx25_gcq_probe
,
414 .remove
= mx25_gcq_remove
,
416 module_platform_driver(mx25_gcq_driver
);
418 MODULE_DESCRIPTION("ADC driver for Freescale mx25");
419 MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
420 MODULE_LICENSE("GPL v2");