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>
15 #include <linux/mod_devicetable.h>
16 #include <linux/platform_device.h>
17 #include <linux/property.h>
18 #include <linux/regmap.h>
19 #include <linux/regulator/consumer.h>
21 #define MX25_GCQ_TIMEOUT (msecs_to_jiffies(2000))
23 static const char * const driver_name
= "mx25-gcq";
37 struct mx25_gcq_priv
{
39 struct completion completed
;
42 struct regulator
*vref
[4];
43 u32 channel_vref_mv
[MX25_NUM_CFGS
];
45 * Lock to protect the device state during a potential concurrent
46 * read access from userspace. Reading a raw value requires a sequence
47 * of register writes, then a wait for a completion callback,
48 * and finally a register read, during which userspace could issue
49 * another read request. This lock protects a read access from
50 * ocurring before another one has finished.
55 #define MX25_CQG_CHAN(chan, id) {\
59 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
60 BIT(IIO_CHAN_INFO_SCALE),\
61 .datasheet_name = id,\
64 static const struct iio_chan_spec mx25_gcq_channels
[MX25_NUM_CFGS
] = {
65 MX25_CQG_CHAN(MX25_CFG_XP
, "xp"),
66 MX25_CQG_CHAN(MX25_CFG_YP
, "yp"),
67 MX25_CQG_CHAN(MX25_CFG_XN
, "xn"),
68 MX25_CQG_CHAN(MX25_CFG_YN
, "yn"),
69 MX25_CQG_CHAN(MX25_CFG_WIPER
, "wiper"),
70 MX25_CQG_CHAN(MX25_CFG_INAUX0
, "inaux0"),
71 MX25_CQG_CHAN(MX25_CFG_INAUX1
, "inaux1"),
72 MX25_CQG_CHAN(MX25_CFG_INAUX2
, "inaux2"),
75 static const char * const mx25_gcq_refp_names
[] = {
76 [MX25_ADC_REFP_YP
] = "yp",
77 [MX25_ADC_REFP_XP
] = "xp",
78 [MX25_ADC_REFP_INT
] = "int",
79 [MX25_ADC_REFP_EXT
] = "ext",
82 static irqreturn_t
mx25_gcq_irq(int irq
, void *data
)
84 struct mx25_gcq_priv
*priv
= data
;
87 regmap_read(priv
->regs
, MX25_ADCQ_SR
, &stats
);
89 if (stats
& MX25_ADCQ_SR_EOQ
) {
90 regmap_set_bits(priv
->regs
, MX25_ADCQ_MR
,
91 MX25_ADCQ_MR_EOQ_IRQ
);
92 complete(&priv
->completed
);
95 /* Disable conversion queue run */
96 regmap_clear_bits(priv
->regs
, MX25_ADCQ_CR
, MX25_ADCQ_CR_FQS
);
98 /* Acknowledge all possible irqs */
99 regmap_write(priv
->regs
, MX25_ADCQ_SR
, MX25_ADCQ_SR_FRR
|
100 MX25_ADCQ_SR_FUR
| MX25_ADCQ_SR_FOR
|
101 MX25_ADCQ_SR_EOQ
| MX25_ADCQ_SR_PD
);
106 static int mx25_gcq_get_raw_value(struct device
*dev
,
107 struct iio_chan_spec
const *chan
,
108 struct mx25_gcq_priv
*priv
,
114 /* Setup the configuration we want to use */
115 regmap_write(priv
->regs
, MX25_ADCQ_ITEM_7_0
,
116 MX25_ADCQ_ITEM(0, chan
->channel
));
118 regmap_clear_bits(priv
->regs
, MX25_ADCQ_MR
, MX25_ADCQ_MR_EOQ_IRQ
);
120 /* Trigger queue for one run */
121 regmap_set_bits(priv
->regs
, MX25_ADCQ_CR
, MX25_ADCQ_CR_FQS
);
123 time_left
= wait_for_completion_interruptible_timeout(
124 &priv
->completed
, MX25_GCQ_TIMEOUT
);
126 dev_err(dev
, "ADC wait for measurement failed\n");
128 } else if (time_left
== 0) {
129 dev_err(dev
, "ADC timed out\n");
133 regmap_read(priv
->regs
, MX25_ADCQ_FIFO
, &data
);
135 *val
= MX25_ADCQ_FIFO_DATA(data
);
140 static int mx25_gcq_read_raw(struct iio_dev
*indio_dev
,
141 struct iio_chan_spec
const *chan
, int *val
,
142 int *val2
, long mask
)
144 struct mx25_gcq_priv
*priv
= iio_priv(indio_dev
);
148 case IIO_CHAN_INFO_RAW
:
149 mutex_lock(&priv
->lock
);
150 ret
= mx25_gcq_get_raw_value(&indio_dev
->dev
, chan
, priv
, val
);
151 mutex_unlock(&priv
->lock
);
154 case IIO_CHAN_INFO_SCALE
:
155 *val
= priv
->channel_vref_mv
[chan
->channel
];
157 return IIO_VAL_FRACTIONAL_LOG2
;
164 static const struct iio_info mx25_gcq_iio_info
= {
165 .read_raw
= mx25_gcq_read_raw
,
168 static const struct regmap_config mx25_gcq_regconfig
= {
169 .max_register
= 0x5c,
175 static int mx25_gcq_ext_regulator_setup(struct device
*dev
,
176 struct mx25_gcq_priv
*priv
, u32 refp
)
181 if (priv
->vref
[refp
])
184 ret
= snprintf(reg_name
, sizeof(reg_name
), "vref-%s",
185 mx25_gcq_refp_names
[refp
]);
189 priv
->vref
[refp
] = devm_regulator_get_optional(dev
, reg_name
);
190 if (IS_ERR(priv
->vref
[refp
]))
191 return dev_err_probe(dev
, PTR_ERR(priv
->vref
[refp
]),
192 "Error, trying to use external voltage reference without a %s regulator.",
198 static int mx25_gcq_setup_cfgs(struct platform_device
*pdev
,
199 struct mx25_gcq_priv
*priv
)
201 struct device
*dev
= &pdev
->dev
;
205 * Setup all configurations registers with a default conversion
206 * configuration for each input
208 for (i
= 0; i
< MX25_NUM_CFGS
; ++i
)
209 regmap_write(priv
->regs
, MX25_ADCQ_CFG(i
),
210 MX25_ADCQ_CFG_YPLL_OFF
|
211 MX25_ADCQ_CFG_XNUR_OFF
|
212 MX25_ADCQ_CFG_XPUL_OFF
|
213 MX25_ADCQ_CFG_REFP_INT
|
214 MX25_ADCQ_CFG_IN(i
) |
215 MX25_ADCQ_CFG_REFN_NGND2
);
217 device_for_each_child_node_scoped(dev
, child
) {
219 u32 refp
= MX25_ADCQ_CFG_REFP_INT
;
220 u32 refn
= MX25_ADCQ_CFG_REFN_NGND2
;
222 ret
= fwnode_property_read_u32(child
, "reg", ®
);
224 return dev_err_probe(dev
, ret
,
225 "Failed to get reg property\n");
227 if (reg
>= MX25_NUM_CFGS
)
228 return dev_err_probe(dev
, -EINVAL
,
229 "reg value is greater than the number of available configuration registers\n");
231 fwnode_property_read_u32(child
, "fsl,adc-refp", &refp
);
232 fwnode_property_read_u32(child
, "fsl,adc-refn", &refn
);
235 case MX25_ADC_REFP_EXT
:
236 case MX25_ADC_REFP_XP
:
237 case MX25_ADC_REFP_YP
:
238 ret
= mx25_gcq_ext_regulator_setup(&pdev
->dev
, priv
, refp
);
241 priv
->channel_vref_mv
[reg
] =
242 regulator_get_voltage(priv
->vref
[refp
]);
243 /* Conversion from uV to mV */
244 priv
->channel_vref_mv
[reg
] /= 1000;
246 case MX25_ADC_REFP_INT
:
247 priv
->channel_vref_mv
[reg
] = 2500;
250 return dev_err_probe(dev
, -EINVAL
,
251 "Invalid positive reference %d\n", refp
);
255 * Shift the read values to the correct positions within the
258 refp
= MX25_ADCQ_CFG_REFP(refp
);
259 refn
= MX25_ADCQ_CFG_REFN(refn
);
261 if ((refp
& MX25_ADCQ_CFG_REFP_MASK
) != refp
)
262 return dev_err_probe(dev
, -EINVAL
,
263 "Invalid fsl,adc-refp property value\n");
265 if ((refn
& MX25_ADCQ_CFG_REFN_MASK
) != refn
)
266 return dev_err_probe(dev
, -EINVAL
,
267 "Invalid fsl,adc-refn property value\n");
269 regmap_update_bits(priv
->regs
, MX25_ADCQ_CFG(reg
),
270 MX25_ADCQ_CFG_REFP_MASK
|
271 MX25_ADCQ_CFG_REFN_MASK
,
274 regmap_set_bits(priv
->regs
, MX25_ADCQ_CR
,
275 MX25_ADCQ_CR_FRST
| MX25_ADCQ_CR_QRST
);
277 regmap_write(priv
->regs
, MX25_ADCQ_CR
,
278 MX25_ADCQ_CR_PDMSK
| MX25_ADCQ_CR_QSM_FQS
);
283 static void mx25_gcq_reg_disable(void *reg
)
285 regulator_disable(reg
);
288 /* Custom handling needed as this driver doesn't own the clock */
289 static void mx25_gcq_clk_disable(void *clk
)
291 clk_disable_unprepare(clk
);
294 static int mx25_gcq_probe(struct platform_device
*pdev
)
296 struct iio_dev
*indio_dev
;
297 struct mx25_gcq_priv
*priv
;
298 struct mx25_tsadc
*tsadc
= dev_get_drvdata(pdev
->dev
.parent
);
299 struct device
*dev
= &pdev
->dev
;
304 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*priv
));
308 priv
= iio_priv(indio_dev
);
310 mem
= devm_platform_ioremap_resource(pdev
, 0);
314 priv
->regs
= devm_regmap_init_mmio(dev
, mem
, &mx25_gcq_regconfig
);
315 if (IS_ERR(priv
->regs
))
316 return dev_err_probe(dev
, PTR_ERR(priv
->regs
),
317 "Failed to initialize regmap\n");
319 mutex_init(&priv
->lock
);
321 init_completion(&priv
->completed
);
323 ret
= mx25_gcq_setup_cfgs(pdev
, priv
);
327 for (i
= 0; i
!= 4; ++i
) {
331 ret
= regulator_enable(priv
->vref
[i
]);
335 ret
= devm_add_action_or_reset(dev
, mx25_gcq_reg_disable
,
341 priv
->clk
= tsadc
->clk
;
342 ret
= clk_prepare_enable(priv
->clk
);
344 return dev_err_probe(dev
, ret
, "Failed to enable clock\n");
346 ret
= devm_add_action_or_reset(dev
, mx25_gcq_clk_disable
,
351 ret
= platform_get_irq(pdev
, 0);
356 ret
= devm_request_irq(dev
, priv
->irq
, mx25_gcq_irq
, 0, pdev
->name
,
359 return dev_err_probe(dev
, ret
, "Failed requesting IRQ\n");
361 indio_dev
->channels
= mx25_gcq_channels
;
362 indio_dev
->num_channels
= ARRAY_SIZE(mx25_gcq_channels
);
363 indio_dev
->info
= &mx25_gcq_iio_info
;
364 indio_dev
->name
= driver_name
;
366 ret
= devm_iio_device_register(dev
, indio_dev
);
368 return dev_err_probe(dev
, ret
, "Failed to register iio device\n");
373 static const struct of_device_id mx25_gcq_ids
[] = {
374 { .compatible
= "fsl,imx25-gcq", },
377 MODULE_DEVICE_TABLE(of
, mx25_gcq_ids
);
379 static struct platform_driver mx25_gcq_driver
= {
382 .of_match_table
= mx25_gcq_ids
,
384 .probe
= mx25_gcq_probe
,
386 module_platform_driver(mx25_gcq_driver
);
388 MODULE_DESCRIPTION("ADC driver for Freescale mx25");
389 MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
390 MODULE_LICENSE("GPL v2");