Lines Matching +full:adc +full:- +full:vref
1 // SPDX-License-Identifier: GPL-2.0+
3 * NXP i.MX8QXP ADC driver
30 #define ADC_DRIVER_NAME "imx8qxp-adc"
46 /* ADC bit shift */
75 /* ADC PARAMETER*/
94 struct regulator *vref; member
95 /* Serialise ADC channel reads */
120 static void imx8qxp_adc_reset(struct imx8qxp_adc *adc) in imx8qxp_adc_reset() argument
125 ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
127 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
130 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
134 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
137 static void imx8qxp_adc_reg_config(struct imx8qxp_adc *adc, int channel) in imx8qxp_adc_reg_config() argument
141 /* ADC configuration */ in imx8qxp_adc_reg_config()
147 writel(adc_cfg, adc->regs + IMX8QXP_ADR_ADC_CFG); in imx8qxp_adc_reg_config()
154 writel(adc_tctrl, adc->regs + IMX8QXP_ADR_ADC_TCTRL(0)); in imx8qxp_adc_reg_config()
162 writel(adc_cmdl, adc->regs + IMX8QXP_ADR_ADC_CMDL(0)); in imx8qxp_adc_reg_config()
170 writel(adc_cmdh, adc->regs + IMX8QXP_ADR_ADC_CMDH(0)); in imx8qxp_adc_reg_config()
173 static void imx8qxp_adc_fifo_config(struct imx8qxp_adc *adc) in imx8qxp_adc_fifo_config() argument
177 fifo_ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL); in imx8qxp_adc_fifo_config()
181 writel(fifo_ctrl, adc->regs + IMX8QXP_ADR_ADC_FCTRL); in imx8qxp_adc_fifo_config()
184 interrupt_en = readl(adc->regs + IMX8QXP_ADR_ADC_IE); in imx8qxp_adc_fifo_config()
186 writel(interrupt_en, adc->regs + IMX8QXP_ADR_ADC_IE); in imx8qxp_adc_fifo_config()
189 static void imx8qxp_adc_disable(struct imx8qxp_adc *adc) in imx8qxp_adc_disable() argument
193 ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_disable()
195 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_disable()
202 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_read_raw() local
203 struct device *dev = adc->dev; in imx8qxp_adc_read_raw()
212 mutex_lock(&adc->lock); in imx8qxp_adc_read_raw()
213 reinit_completion(&adc->completion); in imx8qxp_adc_read_raw()
215 imx8qxp_adc_reg_config(adc, chan->channel); in imx8qxp_adc_read_raw()
217 imx8qxp_adc_fifo_config(adc); in imx8qxp_adc_read_raw()
219 /* adc enable */ in imx8qxp_adc_read_raw()
220 ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_read_raw()
222 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_read_raw()
223 /* adc start */ in imx8qxp_adc_read_raw()
224 writel(1, adc->regs + IMX8QXP_ADR_ADC_SWTRIG); in imx8qxp_adc_read_raw()
226 ret = wait_for_completion_interruptible_timeout(&adc->completion, in imx8qxp_adc_read_raw()
233 mutex_unlock(&adc->lock); in imx8qxp_adc_read_raw()
234 return -ETIMEDOUT; in imx8qxp_adc_read_raw()
237 mutex_unlock(&adc->lock); in imx8qxp_adc_read_raw()
242 readl(adc->regs + IMX8QXP_ADR_ADC_RESFIFO)); in imx8qxp_adc_read_raw()
244 mutex_unlock(&adc->lock); in imx8qxp_adc_read_raw()
248 ret = regulator_get_voltage(adc->vref); in imx8qxp_adc_read_raw()
256 *val = clk_get_rate(adc->clk) / 3; in imx8qxp_adc_read_raw()
260 return -EINVAL; in imx8qxp_adc_read_raw()
266 struct imx8qxp_adc *adc = dev_id; in imx8qxp_adc_isr() local
270 readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL)); in imx8qxp_adc_isr()
273 complete(&adc->completion); in imx8qxp_adc_isr()
281 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_reg_access() local
282 struct device *dev = adc->dev; in imx8qxp_adc_reg_access()
285 return -EINVAL; in imx8qxp_adc_reg_access()
289 *readval = readl(adc->regs + reg); in imx8qxp_adc_reg_access()
304 struct imx8qxp_adc *adc; in imx8qxp_adc_probe() local
306 struct device *dev = &pdev->dev; in imx8qxp_adc_probe()
310 indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); in imx8qxp_adc_probe()
313 return -ENOMEM; in imx8qxp_adc_probe()
316 adc = iio_priv(indio_dev); in imx8qxp_adc_probe()
317 adc->dev = dev; in imx8qxp_adc_probe()
319 mutex_init(&adc->lock); in imx8qxp_adc_probe()
320 adc->regs = devm_platform_ioremap_resource(pdev, 0); in imx8qxp_adc_probe()
321 if (IS_ERR(adc->regs)) in imx8qxp_adc_probe()
322 return PTR_ERR(adc->regs); in imx8qxp_adc_probe()
328 adc->clk = devm_clk_get(dev, "per"); in imx8qxp_adc_probe()
329 if (IS_ERR(adc->clk)) in imx8qxp_adc_probe()
330 return dev_err_probe(dev, PTR_ERR(adc->clk), "Failed getting clock\n"); in imx8qxp_adc_probe()
332 adc->ipg_clk = devm_clk_get(dev, "ipg"); in imx8qxp_adc_probe()
333 if (IS_ERR(adc->ipg_clk)) in imx8qxp_adc_probe()
334 return dev_err_probe(dev, PTR_ERR(adc->ipg_clk), "Failed getting clock\n"); in imx8qxp_adc_probe()
336 adc->vref = devm_regulator_get(dev, "vref"); in imx8qxp_adc_probe()
337 if (IS_ERR(adc->vref)) in imx8qxp_adc_probe()
338 return dev_err_probe(dev, PTR_ERR(adc->vref), "Failed getting reference voltage\n"); in imx8qxp_adc_probe()
340 ret = regulator_enable(adc->vref); in imx8qxp_adc_probe()
342 dev_err(dev, "Can't enable adc reference top voltage\n"); in imx8qxp_adc_probe()
348 init_completion(&adc->completion); in imx8qxp_adc_probe()
350 indio_dev->name = ADC_DRIVER_NAME; in imx8qxp_adc_probe()
351 indio_dev->info = &imx8qxp_adc_iio_info; in imx8qxp_adc_probe()
352 indio_dev->modes = INDIO_DIRECT_MODE; in imx8qxp_adc_probe()
353 indio_dev->channels = imx8qxp_adc_iio_channels; in imx8qxp_adc_probe()
354 indio_dev->num_channels = ARRAY_SIZE(imx8qxp_adc_iio_channels); in imx8qxp_adc_probe()
356 ret = clk_prepare_enable(adc->clk); in imx8qxp_adc_probe()
358 dev_err(&pdev->dev, "Could not prepare or enable the clock.\n"); in imx8qxp_adc_probe()
362 ret = clk_prepare_enable(adc->ipg_clk); in imx8qxp_adc_probe()
364 dev_err(&pdev->dev, "Could not prepare or enable the clock.\n"); in imx8qxp_adc_probe()
368 ret = devm_request_irq(dev, irq, imx8qxp_adc_isr, 0, ADC_DRIVER_NAME, adc); in imx8qxp_adc_probe()
374 imx8qxp_adc_reset(adc); in imx8qxp_adc_probe()
378 imx8qxp_adc_disable(adc); in imx8qxp_adc_probe()
391 clk_disable_unprepare(adc->ipg_clk); in imx8qxp_adc_probe()
393 clk_disable_unprepare(adc->clk); in imx8qxp_adc_probe()
395 regulator_disable(adc->vref); in imx8qxp_adc_probe()
403 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_remove() local
404 struct device *dev = adc->dev; in imx8qxp_adc_remove()
410 imx8qxp_adc_disable(adc); in imx8qxp_adc_remove()
412 clk_disable_unprepare(adc->clk); in imx8qxp_adc_remove()
413 clk_disable_unprepare(adc->ipg_clk); in imx8qxp_adc_remove()
414 regulator_disable(adc->vref); in imx8qxp_adc_remove()
425 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_runtime_suspend() local
427 imx8qxp_adc_disable(adc); in imx8qxp_adc_runtime_suspend()
429 clk_disable_unprepare(adc->clk); in imx8qxp_adc_runtime_suspend()
430 clk_disable_unprepare(adc->ipg_clk); in imx8qxp_adc_runtime_suspend()
431 regulator_disable(adc->vref); in imx8qxp_adc_runtime_suspend()
439 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_runtime_resume() local
442 ret = regulator_enable(adc->vref); in imx8qxp_adc_runtime_resume()
444 dev_err(dev, "Can't enable adc reference top voltage, err = %d\n", ret); in imx8qxp_adc_runtime_resume()
448 ret = clk_prepare_enable(adc->clk); in imx8qxp_adc_runtime_resume()
454 ret = clk_prepare_enable(adc->ipg_clk); in imx8qxp_adc_runtime_resume()
460 imx8qxp_adc_reset(adc); in imx8qxp_adc_runtime_resume()
465 clk_disable_unprepare(adc->clk); in imx8qxp_adc_runtime_resume()
468 regulator_disable(adc->vref); in imx8qxp_adc_runtime_resume()
478 { .compatible = "nxp,imx8qxp-adc", },
495 MODULE_DESCRIPTION("i.MX8QuadXPlus ADC driver");