Lines Matching +full:adc +full:- +full:dev
1 // SPDX-License-Identifier: GPL-2.0
7 * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
24 #define DRIVER_NAME "rzg2l-adc"
93 static unsigned int rzg2l_adc_readl(struct rzg2l_adc *adc, u32 reg) in rzg2l_adc_readl() argument
95 return readl(adc->base + reg); in rzg2l_adc_readl()
98 static void rzg2l_adc_writel(struct rzg2l_adc *adc, unsigned int reg, u32 val) in rzg2l_adc_writel() argument
100 writel(val, adc->base + reg); in rzg2l_adc_writel()
103 static void rzg2l_adc_pwr(struct rzg2l_adc *adc, bool on) in rzg2l_adc_pwr() argument
107 reg = rzg2l_adc_readl(adc, RZG2L_ADM(0)); in rzg2l_adc_pwr()
112 rzg2l_adc_writel(adc, RZG2L_ADM(0), reg); in rzg2l_adc_pwr()
116 static void rzg2l_adc_start_stop(struct rzg2l_adc *adc, bool start) in rzg2l_adc_start_stop() argument
121 reg = rzg2l_adc_readl(adc, RZG2L_ADM(0)); in rzg2l_adc_start_stop()
126 rzg2l_adc_writel(adc, RZG2L_ADM(0), reg); in rzg2l_adc_start_stop()
133 reg = rzg2l_adc_readl(adc, RZG2L_ADM(0)); in rzg2l_adc_start_stop()
134 timeout--; in rzg2l_adc_start_stop()
136 pr_err("%s stopping ADC timed out\n", __func__); in rzg2l_adc_start_stop()
142 static void rzg2l_set_trigger(struct rzg2l_adc *adc) in rzg2l_set_trigger() argument
148 * EGA[13:12] - Set 00 to indicate hardware trigger is invalid in rzg2l_set_trigger()
149 * BS[4] - Enable 1-buffer mode in rzg2l_set_trigger()
150 * MS[1] - Enable Select mode in rzg2l_set_trigger()
151 * TRG[0] - Enable software trigger mode in rzg2l_set_trigger()
153 reg = rzg2l_adc_readl(adc, RZG2L_ADM(1)); in rzg2l_set_trigger()
158 rzg2l_adc_writel(adc, RZG2L_ADM(1), reg); in rzg2l_set_trigger()
161 static int rzg2l_adc_conversion_setup(struct rzg2l_adc *adc, u8 ch) in rzg2l_adc_conversion_setup() argument
165 if (rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_ADBSY) in rzg2l_adc_conversion_setup()
166 return -EBUSY; in rzg2l_adc_conversion_setup()
168 rzg2l_set_trigger(adc); in rzg2l_adc_conversion_setup()
171 reg = rzg2l_adc_readl(adc, RZG2L_ADM(2)); in rzg2l_adc_conversion_setup()
174 rzg2l_adc_writel(adc, RZG2L_ADM(2), reg); in rzg2l_adc_conversion_setup()
178 * INTS[31] - Select pulse signal in rzg2l_adc_conversion_setup()
179 * CSEEN[16] - Enable channel select error interrupt in rzg2l_adc_conversion_setup()
180 * INTEN[7:0] - Select channel interrupt in rzg2l_adc_conversion_setup()
182 reg = rzg2l_adc_readl(adc, RZG2L_ADINT); in rzg2l_adc_conversion_setup()
186 rzg2l_adc_writel(adc, RZG2L_ADINT, reg); in rzg2l_adc_conversion_setup()
193 struct device *dev = indio_dev->dev.parent; in rzg2l_adc_set_power() local
196 return pm_runtime_resume_and_get(dev); in rzg2l_adc_set_power()
198 return pm_runtime_put_sync(dev); in rzg2l_adc_set_power()
201 static int rzg2l_adc_conversion(struct iio_dev *indio_dev, struct rzg2l_adc *adc, u8 ch) in rzg2l_adc_conversion() argument
209 ret = rzg2l_adc_conversion_setup(adc, ch); in rzg2l_adc_conversion()
215 reinit_completion(&adc->completion); in rzg2l_adc_conversion()
217 rzg2l_adc_start_stop(adc, true); in rzg2l_adc_conversion()
219 if (!wait_for_completion_timeout(&adc->completion, RZG2L_ADC_TIMEOUT)) { in rzg2l_adc_conversion()
220 rzg2l_adc_writel(adc, RZG2L_ADINT, in rzg2l_adc_conversion()
221 rzg2l_adc_readl(adc, RZG2L_ADINT) & ~RZG2L_ADINT_INTEN_MASK); in rzg2l_adc_conversion()
222 rzg2l_adc_start_stop(adc, false); in rzg2l_adc_conversion()
224 return -ETIMEDOUT; in rzg2l_adc_conversion()
234 struct rzg2l_adc *adc = iio_priv(indio_dev); in rzg2l_adc_read_raw() local
240 if (chan->type != IIO_VOLTAGE) in rzg2l_adc_read_raw()
241 return -EINVAL; in rzg2l_adc_read_raw()
243 mutex_lock(&adc->lock); in rzg2l_adc_read_raw()
244 ch = chan->channel & RZG2L_ADC_CHN_MASK; in rzg2l_adc_read_raw()
245 ret = rzg2l_adc_conversion(indio_dev, adc, ch); in rzg2l_adc_read_raw()
247 mutex_unlock(&adc->lock); in rzg2l_adc_read_raw()
250 *val = adc->last_val[ch]; in rzg2l_adc_read_raw()
251 mutex_unlock(&adc->lock); in rzg2l_adc_read_raw()
256 return -EINVAL; in rzg2l_adc_read_raw()
264 return sysfs_emit(label, "%s\n", rzg2l_adc_channel_name[chan->channel]); in rzg2l_adc_read_label()
274 struct rzg2l_adc *adc = dev_id; in rzg2l_adc_isr() local
279 reg = rzg2l_adc_readl(adc, RZG2L_ADSTS); in rzg2l_adc_isr()
283 rzg2l_adc_writel(adc, RZG2L_ADSTS, reg); in rzg2l_adc_isr()
292 adc->last_val[ch] = rzg2l_adc_readl(adc, RZG2L_ADCR(ch)) & RZG2L_ADCR_AD_MASK; in rzg2l_adc_isr()
295 rzg2l_adc_writel(adc, RZG2L_ADSTS, reg); in rzg2l_adc_isr()
297 complete(&adc->completion); in rzg2l_adc_isr()
302 static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l_adc *adc) in rzg2l_adc_parse_properties() argument
312 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); in rzg2l_adc_parse_properties()
314 return -ENOMEM; in rzg2l_adc_parse_properties()
316 num_channels = device_get_child_node_count(&pdev->dev); in rzg2l_adc_parse_properties()
318 dev_err(&pdev->dev, "no channel children\n"); in rzg2l_adc_parse_properties()
319 return -ENODEV; in rzg2l_adc_parse_properties()
323 dev_err(&pdev->dev, "num of channel children out of range\n"); in rzg2l_adc_parse_properties()
324 return -EINVAL; in rzg2l_adc_parse_properties()
327 chan_array = devm_kcalloc(&pdev->dev, num_channels, sizeof(*chan_array), in rzg2l_adc_parse_properties()
330 return -ENOMEM; in rzg2l_adc_parse_properties()
333 device_for_each_child_node(&pdev->dev, fwnode) { in rzg2l_adc_parse_properties()
342 return -EINVAL; in rzg2l_adc_parse_properties()
353 data->num_channels = num_channels; in rzg2l_adc_parse_properties()
354 data->channels = chan_array; in rzg2l_adc_parse_properties()
355 adc->data = data; in rzg2l_adc_parse_properties()
360 static int rzg2l_adc_hw_init(struct rzg2l_adc *adc) in rzg2l_adc_hw_init() argument
366 ret = clk_prepare_enable(adc->pclk); in rzg2l_adc_hw_init()
371 reg = rzg2l_adc_readl(adc, RZG2L_ADM(0)); in rzg2l_adc_hw_init()
373 rzg2l_adc_writel(adc, RZG2L_ADM(0), reg); in rzg2l_adc_hw_init()
375 while (!(rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_SRESB)) { in rzg2l_adc_hw_init()
377 ret = -EBUSY; in rzg2l_adc_hw_init()
380 timeout--; in rzg2l_adc_hw_init()
385 reg = rzg2l_adc_readl(adc, RZG2L_ADIVC); in rzg2l_adc_hw_init()
388 rzg2l_adc_writel(adc, RZG2L_ADIVC, reg); in rzg2l_adc_hw_init()
392 * ADIL[31:24] - Should be always set to 0 in rzg2l_adc_hw_init()
393 * ADCMP[23:16] - Should be always set to 0xe in rzg2l_adc_hw_init()
394 * ADSMP[15:0] - Set default (0x578) sampling period in rzg2l_adc_hw_init()
396 reg = rzg2l_adc_readl(adc, RZG2L_ADM(3)); in rzg2l_adc_hw_init()
401 rzg2l_adc_writel(adc, RZG2L_ADM(3), reg); in rzg2l_adc_hw_init()
404 clk_disable_unprepare(adc->pclk); in rzg2l_adc_hw_init()
411 struct device *dev = data; in rzg2l_adc_pm_runtime_disable() local
413 pm_runtime_disable(dev->parent); in rzg2l_adc_pm_runtime_disable()
418 struct device *dev = data; in rzg2l_adc_pm_runtime_set_suspended() local
420 pm_runtime_set_suspended(dev->parent); in rzg2l_adc_pm_runtime_set_suspended()
430 struct device *dev = &pdev->dev; in rzg2l_adc_probe() local
432 struct rzg2l_adc *adc; in rzg2l_adc_probe() local
436 indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); in rzg2l_adc_probe()
438 return -ENOMEM; in rzg2l_adc_probe()
440 adc = iio_priv(indio_dev); in rzg2l_adc_probe()
442 ret = rzg2l_adc_parse_properties(pdev, adc); in rzg2l_adc_probe()
446 mutex_init(&adc->lock); in rzg2l_adc_probe()
448 adc->base = devm_platform_ioremap_resource(pdev, 0); in rzg2l_adc_probe()
449 if (IS_ERR(adc->base)) in rzg2l_adc_probe()
450 return PTR_ERR(adc->base); in rzg2l_adc_probe()
452 adc->pclk = devm_clk_get(dev, "pclk"); in rzg2l_adc_probe()
453 if (IS_ERR(adc->pclk)) { in rzg2l_adc_probe()
454 dev_err(dev, "Failed to get pclk"); in rzg2l_adc_probe()
455 return PTR_ERR(adc->pclk); in rzg2l_adc_probe()
458 adc->adclk = devm_clk_get(dev, "adclk"); in rzg2l_adc_probe()
459 if (IS_ERR(adc->adclk)) { in rzg2l_adc_probe()
460 dev_err(dev, "Failed to get adclk"); in rzg2l_adc_probe()
461 return PTR_ERR(adc->adclk); in rzg2l_adc_probe()
464 adc->adrstn = devm_reset_control_get_exclusive(dev, "adrst-n"); in rzg2l_adc_probe()
465 if (IS_ERR(adc->adrstn)) { in rzg2l_adc_probe()
466 dev_err(dev, "failed to get adrstn\n"); in rzg2l_adc_probe()
467 return PTR_ERR(adc->adrstn); in rzg2l_adc_probe()
470 adc->presetn = devm_reset_control_get_exclusive(dev, "presetn"); in rzg2l_adc_probe()
471 if (IS_ERR(adc->presetn)) { in rzg2l_adc_probe()
472 dev_err(dev, "failed to get presetn\n"); in rzg2l_adc_probe()
473 return PTR_ERR(adc->presetn); in rzg2l_adc_probe()
476 ret = reset_control_deassert(adc->adrstn); in rzg2l_adc_probe()
478 dev_err(&pdev->dev, "failed to deassert adrstn pin, %d\n", ret); in rzg2l_adc_probe()
482 ret = devm_add_action_or_reset(&pdev->dev, in rzg2l_adc_probe()
483 rzg2l_adc_reset_assert, adc->adrstn); in rzg2l_adc_probe()
485 dev_err(&pdev->dev, "failed to register adrstn assert devm action, %d\n", in rzg2l_adc_probe()
490 ret = reset_control_deassert(adc->presetn); in rzg2l_adc_probe()
492 dev_err(&pdev->dev, "failed to deassert presetn pin, %d\n", ret); in rzg2l_adc_probe()
496 ret = devm_add_action_or_reset(&pdev->dev, in rzg2l_adc_probe()
497 rzg2l_adc_reset_assert, adc->presetn); in rzg2l_adc_probe()
499 dev_err(&pdev->dev, "failed to register presetn assert devm action, %d\n", in rzg2l_adc_probe()
504 ret = rzg2l_adc_hw_init(adc); in rzg2l_adc_probe()
506 dev_err(&pdev->dev, "failed to initialize ADC HW, %d\n", ret); in rzg2l_adc_probe()
514 ret = devm_request_irq(dev, irq, rzg2l_adc_isr, in rzg2l_adc_probe()
515 0, dev_name(dev), adc); in rzg2l_adc_probe()
519 init_completion(&adc->completion); in rzg2l_adc_probe()
523 indio_dev->name = DRIVER_NAME; in rzg2l_adc_probe()
524 indio_dev->info = &rzg2l_adc_iio_info; in rzg2l_adc_probe()
525 indio_dev->modes = INDIO_DIRECT_MODE; in rzg2l_adc_probe()
526 indio_dev->channels = adc->data->channels; in rzg2l_adc_probe()
527 indio_dev->num_channels = adc->data->num_channels; in rzg2l_adc_probe()
529 pm_runtime_set_suspended(dev); in rzg2l_adc_probe()
530 ret = devm_add_action_or_reset(&pdev->dev, in rzg2l_adc_probe()
531 rzg2l_adc_pm_runtime_set_suspended, &indio_dev->dev); in rzg2l_adc_probe()
535 pm_runtime_enable(dev); in rzg2l_adc_probe()
536 ret = devm_add_action_or_reset(&pdev->dev, in rzg2l_adc_probe()
537 rzg2l_adc_pm_runtime_disable, &indio_dev->dev); in rzg2l_adc_probe()
541 return devm_iio_device_register(dev, indio_dev); in rzg2l_adc_probe()
545 { .compatible = "renesas,rzg2l-adc",},
550 static int __maybe_unused rzg2l_adc_pm_runtime_suspend(struct device *dev) in rzg2l_adc_pm_runtime_suspend() argument
552 struct iio_dev *indio_dev = dev_get_drvdata(dev); in rzg2l_adc_pm_runtime_suspend()
553 struct rzg2l_adc *adc = iio_priv(indio_dev); in rzg2l_adc_pm_runtime_suspend() local
555 rzg2l_adc_pwr(adc, false); in rzg2l_adc_pm_runtime_suspend()
556 clk_disable_unprepare(adc->adclk); in rzg2l_adc_pm_runtime_suspend()
557 clk_disable_unprepare(adc->pclk); in rzg2l_adc_pm_runtime_suspend()
562 static int __maybe_unused rzg2l_adc_pm_runtime_resume(struct device *dev) in rzg2l_adc_pm_runtime_resume() argument
564 struct iio_dev *indio_dev = dev_get_drvdata(dev); in rzg2l_adc_pm_runtime_resume()
565 struct rzg2l_adc *adc = iio_priv(indio_dev); in rzg2l_adc_pm_runtime_resume() local
568 ret = clk_prepare_enable(adc->pclk); in rzg2l_adc_pm_runtime_resume()
572 ret = clk_prepare_enable(adc->adclk); in rzg2l_adc_pm_runtime_resume()
574 clk_disable_unprepare(adc->pclk); in rzg2l_adc_pm_runtime_resume()
578 rzg2l_adc_pwr(adc, true); in rzg2l_adc_pm_runtime_resume()
600 MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
601 MODULE_DESCRIPTION("Renesas RZ/G2L ADC driver");