Lines Matching +full:adc +full:- +full:clk

1 // SPDX-License-Identifier: GPL-2.0+
3 * NXP i.MX8QXP ADC driver
15 #include <linux/clk.h>
30 #define ADC_DRIVER_NAME "imx8qxp-adc"
46 /* ADC bit shift */
75 /* ADC PARAMETER*/
94 struct clk *clk; member
95 struct clk *ipg_clk;
97 /* Serialise ADC channel reads */
123 static void imx8qxp_adc_reset(struct imx8qxp_adc *adc) in imx8qxp_adc_reset() argument
128 ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
130 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
133 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
137 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_reset()
140 static void imx8qxp_adc_reg_config(struct imx8qxp_adc *adc, int channel) in imx8qxp_adc_reg_config() argument
144 /* ADC configuration */ in imx8qxp_adc_reg_config()
150 writel(adc_cfg, adc->regs + IMX8QXP_ADR_ADC_CFG); in imx8qxp_adc_reg_config()
157 writel(adc_tctrl, adc->regs + IMX8QXP_ADR_ADC_TCTRL(0)); in imx8qxp_adc_reg_config()
165 writel(adc_cmdl, adc->regs + IMX8QXP_ADR_ADC_CMDL(0)); in imx8qxp_adc_reg_config()
173 writel(adc_cmdh, adc->regs + IMX8QXP_ADR_ADC_CMDH(0)); in imx8qxp_adc_reg_config()
176 static void imx8qxp_adc_fifo_config(struct imx8qxp_adc *adc) in imx8qxp_adc_fifo_config() argument
180 fifo_ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL); in imx8qxp_adc_fifo_config()
184 writel(fifo_ctrl, adc->regs + IMX8QXP_ADR_ADC_FCTRL); in imx8qxp_adc_fifo_config()
187 interrupt_en = readl(adc->regs + IMX8QXP_ADR_ADC_IE); in imx8qxp_adc_fifo_config()
189 writel(interrupt_en, adc->regs + IMX8QXP_ADR_ADC_IE); in imx8qxp_adc_fifo_config()
192 static void imx8qxp_adc_disable(struct imx8qxp_adc *adc) in imx8qxp_adc_disable() argument
196 ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_disable()
198 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_disable()
205 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_read_raw() local
206 struct device *dev = adc->dev; in imx8qxp_adc_read_raw()
215 mutex_lock(&adc->lock); in imx8qxp_adc_read_raw()
216 reinit_completion(&adc->completion); in imx8qxp_adc_read_raw()
218 imx8qxp_adc_reg_config(adc, chan->channel); in imx8qxp_adc_read_raw()
220 imx8qxp_adc_fifo_config(adc); in imx8qxp_adc_read_raw()
222 /* adc enable */ in imx8qxp_adc_read_raw()
223 ctrl = readl(adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_read_raw()
225 writel(ctrl, adc->regs + IMX8QXP_ADR_ADC_CTRL); in imx8qxp_adc_read_raw()
226 /* adc start */ in imx8qxp_adc_read_raw()
227 writel(1, adc->regs + IMX8QXP_ADR_ADC_SWTRIG); in imx8qxp_adc_read_raw()
229 ret = wait_for_completion_interruptible_timeout(&adc->completion, in imx8qxp_adc_read_raw()
236 mutex_unlock(&adc->lock); in imx8qxp_adc_read_raw()
237 return -ETIMEDOUT; in imx8qxp_adc_read_raw()
240 mutex_unlock(&adc->lock); in imx8qxp_adc_read_raw()
244 *val = adc->fifo[0]; in imx8qxp_adc_read_raw()
246 mutex_unlock(&adc->lock); in imx8qxp_adc_read_raw()
250 ret = regulator_get_voltage(adc->vref); in imx8qxp_adc_read_raw()
258 *val = clk_get_rate(adc->clk) / 3; in imx8qxp_adc_read_raw()
262 return -EINVAL; in imx8qxp_adc_read_raw()
268 struct imx8qxp_adc *adc = dev_id; in imx8qxp_adc_isr() local
273 readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL)); in imx8qxp_adc_isr()
276 adc->fifo[i] = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK, in imx8qxp_adc_isr()
277 readl_relaxed(adc->regs + IMX8QXP_ADR_ADC_RESFIFO)); in imx8qxp_adc_isr()
280 complete(&adc->completion); in imx8qxp_adc_isr()
288 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_reg_access() local
289 struct device *dev = adc->dev; in imx8qxp_adc_reg_access()
292 return -EINVAL; in imx8qxp_adc_reg_access()
296 *readval = readl(adc->regs + reg); in imx8qxp_adc_reg_access()
311 struct imx8qxp_adc *adc; in imx8qxp_adc_probe() local
313 struct device *dev = &pdev->dev; in imx8qxp_adc_probe()
317 indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); in imx8qxp_adc_probe()
320 return -ENOMEM; in imx8qxp_adc_probe()
323 adc = iio_priv(indio_dev); in imx8qxp_adc_probe()
324 adc->dev = dev; in imx8qxp_adc_probe()
326 mutex_init(&adc->lock); in imx8qxp_adc_probe()
327 adc->regs = devm_platform_ioremap_resource(pdev, 0); in imx8qxp_adc_probe()
328 if (IS_ERR(adc->regs)) in imx8qxp_adc_probe()
329 return PTR_ERR(adc->regs); in imx8qxp_adc_probe()
335 adc->clk = devm_clk_get(dev, "per"); in imx8qxp_adc_probe()
336 if (IS_ERR(adc->clk)) in imx8qxp_adc_probe()
337 return dev_err_probe(dev, PTR_ERR(adc->clk), "Failed getting clock\n"); in imx8qxp_adc_probe()
339 adc->ipg_clk = devm_clk_get(dev, "ipg"); in imx8qxp_adc_probe()
340 if (IS_ERR(adc->ipg_clk)) in imx8qxp_adc_probe()
341 return dev_err_probe(dev, PTR_ERR(adc->ipg_clk), "Failed getting clock\n"); in imx8qxp_adc_probe()
343 adc->vref = devm_regulator_get(dev, "vref"); in imx8qxp_adc_probe()
344 if (IS_ERR(adc->vref)) in imx8qxp_adc_probe()
345 return dev_err_probe(dev, PTR_ERR(adc->vref), "Failed getting reference voltage\n"); in imx8qxp_adc_probe()
347 ret = regulator_enable(adc->vref); in imx8qxp_adc_probe()
349 dev_err(dev, "Can't enable adc reference top voltage\n"); in imx8qxp_adc_probe()
355 init_completion(&adc->completion); in imx8qxp_adc_probe()
357 indio_dev->name = ADC_DRIVER_NAME; in imx8qxp_adc_probe()
358 indio_dev->info = &imx8qxp_adc_iio_info; in imx8qxp_adc_probe()
359 indio_dev->modes = INDIO_DIRECT_MODE; in imx8qxp_adc_probe()
360 indio_dev->channels = imx8qxp_adc_iio_channels; in imx8qxp_adc_probe()
361 indio_dev->num_channels = ARRAY_SIZE(imx8qxp_adc_iio_channels); in imx8qxp_adc_probe()
363 ret = clk_prepare_enable(adc->clk); in imx8qxp_adc_probe()
365 dev_err(&pdev->dev, "Could not prepare or enable the clock.\n"); in imx8qxp_adc_probe()
369 ret = clk_prepare_enable(adc->ipg_clk); in imx8qxp_adc_probe()
371 dev_err(&pdev->dev, "Could not prepare or enable the clock.\n"); in imx8qxp_adc_probe()
375 ret = devm_request_irq(dev, irq, imx8qxp_adc_isr, 0, ADC_DRIVER_NAME, adc); in imx8qxp_adc_probe()
381 imx8qxp_adc_reset(adc); in imx8qxp_adc_probe()
385 imx8qxp_adc_disable(adc); in imx8qxp_adc_probe()
398 clk_disable_unprepare(adc->ipg_clk); in imx8qxp_adc_probe()
400 clk_disable_unprepare(adc->clk); in imx8qxp_adc_probe()
402 regulator_disable(adc->vref); in imx8qxp_adc_probe()
410 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_remove() local
411 struct device *dev = adc->dev; in imx8qxp_adc_remove()
417 imx8qxp_adc_disable(adc); in imx8qxp_adc_remove()
419 clk_disable_unprepare(adc->clk); in imx8qxp_adc_remove()
420 clk_disable_unprepare(adc->ipg_clk); in imx8qxp_adc_remove()
421 regulator_disable(adc->vref); in imx8qxp_adc_remove()
430 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_runtime_suspend() local
432 imx8qxp_adc_disable(adc); in imx8qxp_adc_runtime_suspend()
434 clk_disable_unprepare(adc->clk); in imx8qxp_adc_runtime_suspend()
435 clk_disable_unprepare(adc->ipg_clk); in imx8qxp_adc_runtime_suspend()
436 regulator_disable(adc->vref); in imx8qxp_adc_runtime_suspend()
444 struct imx8qxp_adc *adc = iio_priv(indio_dev); in imx8qxp_adc_runtime_resume() local
447 ret = regulator_enable(adc->vref); in imx8qxp_adc_runtime_resume()
449 dev_err(dev, "Can't enable adc reference top voltage, err = %d\n", ret); in imx8qxp_adc_runtime_resume()
453 ret = clk_prepare_enable(adc->clk); in imx8qxp_adc_runtime_resume()
459 ret = clk_prepare_enable(adc->ipg_clk); in imx8qxp_adc_runtime_resume()
465 imx8qxp_adc_reset(adc); in imx8qxp_adc_runtime_resume()
470 clk_disable_unprepare(adc->clk); in imx8qxp_adc_runtime_resume()
473 regulator_disable(adc->vref); in imx8qxp_adc_runtime_resume()
483 { .compatible = "nxp,imx8qxp-adc", },
500 MODULE_DESCRIPTION("i.MX8QuadXPlus ADC driver");