brintos

brintos / linux-shallow public Read only

0
0
Text · 12.0 KiB · 4ccf481 Raw
486 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * NXP i.MX93 ADC driver4 *5 * Copyright 2023 NXP6 */7 8#include <linux/bitfield.h>9#include <linux/clk.h>10#include <linux/completion.h>11#include <linux/err.h>12#include <linux/iio/iio.h>13#include <linux/interrupt.h>14#include <linux/io.h>15#include <linux/iopoll.h>16#include <linux/mod_devicetable.h>17#include <linux/module.h>18#include <linux/platform_device.h>19#include <linux/pm_runtime.h>20#include <linux/regulator/consumer.h>21 22#define IMX93_ADC_DRIVER_NAME	"imx93-adc"23 24/* Register map definition */25#define IMX93_ADC_MCR		0x0026#define IMX93_ADC_MSR		0x0427#define IMX93_ADC_ISR		0x1028#define IMX93_ADC_IMR		0x2029#define IMX93_ADC_CIMR0		0x2430#define IMX93_ADC_CTR0		0x9431#define IMX93_ADC_NCMR0		0xA432#define IMX93_ADC_PCDR0		0x10033#define IMX93_ADC_PCDR1		0x10434#define IMX93_ADC_PCDR2		0x10835#define IMX93_ADC_PCDR3		0x10c36#define IMX93_ADC_PCDR4		0x11037#define IMX93_ADC_PCDR5		0x11438#define IMX93_ADC_PCDR6		0x11839#define IMX93_ADC_PCDR7		0x11c40#define IMX93_ADC_CALSTAT	0x39C41 42/* ADC bit shift */43#define IMX93_ADC_MCR_MODE_MASK			BIT(29)44#define IMX93_ADC_MCR_NSTART_MASK		BIT(24)45#define IMX93_ADC_MCR_CALSTART_MASK		BIT(14)46#define IMX93_ADC_MCR_ADCLKSE_MASK		BIT(8)47#define IMX93_ADC_MCR_PWDN_MASK			BIT(0)48#define IMX93_ADC_MSR_CALFAIL_MASK		BIT(30)49#define IMX93_ADC_MSR_CALBUSY_MASK		BIT(29)50#define IMX93_ADC_MSR_ADCSTATUS_MASK		GENMASK(2, 0)51#define IMX93_ADC_ISR_ECH_MASK			BIT(0)52#define IMX93_ADC_ISR_EOC_MASK			BIT(1)53#define IMX93_ADC_ISR_EOC_ECH_MASK		(IMX93_ADC_ISR_EOC_MASK | \54						 IMX93_ADC_ISR_ECH_MASK)55#define IMX93_ADC_IMR_JEOC_MASK			BIT(3)56#define IMX93_ADC_IMR_JECH_MASK			BIT(2)57#define IMX93_ADC_IMR_EOC_MASK			BIT(1)58#define IMX93_ADC_IMR_ECH_MASK			BIT(0)59#define IMX93_ADC_PCDR_CDATA_MASK		GENMASK(11, 0)60 61/* ADC status */62#define IMX93_ADC_MSR_ADCSTATUS_IDLE			063#define IMX93_ADC_MSR_ADCSTATUS_POWER_DOWN		164#define IMX93_ADC_MSR_ADCSTATUS_WAIT_STATE		265#define IMX93_ADC_MSR_ADCSTATUS_BUSY_IN_CALIBRATION	366#define IMX93_ADC_MSR_ADCSTATUS_SAMPLE			467#define IMX93_ADC_MSR_ADCSTATUS_CONVERSION		668 69#define IMX93_ADC_TIMEOUT		msecs_to_jiffies(100)70 71struct imx93_adc {72	struct device *dev;73	void __iomem *regs;74	struct clk *ipg_clk;75	int irq;76	struct regulator *vref;77	/* lock to protect against multiple access to the device */78	struct mutex lock;79	struct completion completion;80};81 82#define IMX93_ADC_CHAN(_idx) {					\83	.type = IIO_VOLTAGE,					\84	.indexed = 1,						\85	.channel = (_idx),					\86	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\87	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\88				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\89}90 91static const struct iio_chan_spec imx93_adc_iio_channels[] = {92	IMX93_ADC_CHAN(0),93	IMX93_ADC_CHAN(1),94	IMX93_ADC_CHAN(2),95	IMX93_ADC_CHAN(3),96	IMX93_ADC_CHAN(4),97	IMX93_ADC_CHAN(5),98	IMX93_ADC_CHAN(6),99	IMX93_ADC_CHAN(7),100};101 102static void imx93_adc_power_down(struct imx93_adc *adc)103{104	u32 mcr, msr;105	int ret;106 107	mcr = readl(adc->regs + IMX93_ADC_MCR);108	mcr |= FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);109	writel(mcr, adc->regs + IMX93_ADC_MCR);110 111	ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,112				 ((msr & IMX93_ADC_MSR_ADCSTATUS_MASK) ==113				  IMX93_ADC_MSR_ADCSTATUS_POWER_DOWN),114				 1, 50);115	if (ret == -ETIMEDOUT)116		dev_warn(adc->dev,117			 "ADC do not in power down mode, current MSR is %x\n",118			 msr);119}120 121static void imx93_adc_power_up(struct imx93_adc *adc)122{123	u32 mcr;124 125	/* bring ADC out of power down state, in idle state */126	mcr = readl(adc->regs + IMX93_ADC_MCR);127	mcr &= ~FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);128	writel(mcr, adc->regs + IMX93_ADC_MCR);129}130 131static void imx93_adc_config_ad_clk(struct imx93_adc *adc)132{133	u32 mcr;134 135	/* put adc in power down mode */136	imx93_adc_power_down(adc);137 138	/* config the AD_CLK equal to bus clock */139	mcr = readl(adc->regs + IMX93_ADC_MCR);140	mcr |= FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);141	writel(mcr, adc->regs + IMX93_ADC_MCR);142 143	imx93_adc_power_up(adc);144}145 146static int imx93_adc_calibration(struct imx93_adc *adc)147{148	u32 mcr, msr;149	int ret;150 151	/* make sure ADC in power down mode */152	imx93_adc_power_down(adc);153 154	/* config SAR controller operating clock */155	mcr = readl(adc->regs + IMX93_ADC_MCR);156	mcr &= ~FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);157	writel(mcr, adc->regs + IMX93_ADC_MCR);158 159	imx93_adc_power_up(adc);160 161	/*162	 * TODO: we use the default TSAMP/NRSMPL/AVGEN in MCR,163	 * can add the setting of these bit if need in future.164	 */165 166	/* run calibration */167	mcr = readl(adc->regs + IMX93_ADC_MCR);168	mcr |= FIELD_PREP(IMX93_ADC_MCR_CALSTART_MASK, 1);169	writel(mcr, adc->regs + IMX93_ADC_MCR);170 171	/* wait calibration to be finished */172	ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,173		!(msr & IMX93_ADC_MSR_CALBUSY_MASK), 1000, 2000000);174	if (ret == -ETIMEDOUT) {175		dev_warn(adc->dev, "ADC do not finish calibration in 2 min!\n");176		imx93_adc_power_down(adc);177		return ret;178	}179 180	/* check whether calbration is success or not */181	msr = readl(adc->regs + IMX93_ADC_MSR);182	if (msr & IMX93_ADC_MSR_CALFAIL_MASK) {183		dev_warn(adc->dev, "ADC calibration failed!\n");184		imx93_adc_power_down(adc);185		return -EAGAIN;186	}187 188	return 0;189}190 191static int imx93_adc_read_channel_conversion(struct imx93_adc *adc,192						int channel_number,193						int *result)194{195	u32 channel;196	u32 imr, mcr, pcda;197	long ret;198 199	reinit_completion(&adc->completion);200 201	/* config channel mask register */202	channel = 1 << channel_number;203	writel(channel, adc->regs + IMX93_ADC_NCMR0);204 205	/* TODO: can config desired sample time in CTRn if need */206 207	/* config interrupt mask */208	imr = FIELD_PREP(IMX93_ADC_IMR_EOC_MASK, 1);209	writel(imr, adc->regs + IMX93_ADC_IMR);210	writel(channel, adc->regs + IMX93_ADC_CIMR0);211 212	/* config one-shot mode */213	mcr = readl(adc->regs + IMX93_ADC_MCR);214	mcr &= ~FIELD_PREP(IMX93_ADC_MCR_MODE_MASK, 1);215	writel(mcr, adc->regs + IMX93_ADC_MCR);216 217	/* start normal conversion */218	mcr = readl(adc->regs + IMX93_ADC_MCR);219	mcr |= FIELD_PREP(IMX93_ADC_MCR_NSTART_MASK, 1);220	writel(mcr, adc->regs + IMX93_ADC_MCR);221 222	ret = wait_for_completion_interruptible_timeout(&adc->completion,223							IMX93_ADC_TIMEOUT);224	if (ret == 0)225		return -ETIMEDOUT;226 227	if (ret < 0)228		return ret;229 230	pcda = readl(adc->regs + IMX93_ADC_PCDR0 + channel_number * 4);231 232	*result = FIELD_GET(IMX93_ADC_PCDR_CDATA_MASK, pcda);233 234	return ret;235}236 237static int imx93_adc_read_raw(struct iio_dev *indio_dev,238				struct iio_chan_spec const *chan,239				int *val, int *val2, long mask)240{241	struct imx93_adc *adc = iio_priv(indio_dev);242	struct device *dev = adc->dev;243	int ret;244 245	switch (mask) {246	case IIO_CHAN_INFO_RAW:247		pm_runtime_get_sync(dev);248		mutex_lock(&adc->lock);249		ret = imx93_adc_read_channel_conversion(adc, chan->channel, val);250		mutex_unlock(&adc->lock);251		pm_runtime_mark_last_busy(dev);252		pm_runtime_put_sync_autosuspend(dev);253		if (ret < 0)254			return ret;255 256		return IIO_VAL_INT;257 258	case IIO_CHAN_INFO_SCALE:259		ret = regulator_get_voltage(adc->vref);260		if (ret < 0)261			return ret;262		*val = ret / 1000;263		*val2 = 12;264		return IIO_VAL_FRACTIONAL_LOG2;265 266	case IIO_CHAN_INFO_SAMP_FREQ:267		*val = clk_get_rate(adc->ipg_clk);268		return IIO_VAL_INT;269 270	default:271		return -EINVAL;272	}273}274 275static irqreturn_t imx93_adc_isr(int irq, void *dev_id)276{277	struct imx93_adc *adc = dev_id;278	u32 isr, eoc, unexpected;279 280	isr = readl(adc->regs + IMX93_ADC_ISR);281 282	if (FIELD_GET(IMX93_ADC_ISR_EOC_ECH_MASK, isr)) {283		eoc = isr & IMX93_ADC_ISR_EOC_ECH_MASK;284		writel(eoc, adc->regs + IMX93_ADC_ISR);285		complete(&adc->completion);286	}287 288	unexpected = isr & ~IMX93_ADC_ISR_EOC_ECH_MASK;289	if (unexpected) {290		writel(unexpected, adc->regs + IMX93_ADC_ISR);291		dev_err(adc->dev, "Unexpected interrupt 0x%08x.\n", unexpected);292		return IRQ_NONE;293	}294 295	return IRQ_HANDLED;296}297 298static const struct iio_info imx93_adc_iio_info = {299	.read_raw = &imx93_adc_read_raw,300};301 302static int imx93_adc_probe(struct platform_device *pdev)303{304	struct imx93_adc *adc;305	struct iio_dev *indio_dev;306	struct device *dev = &pdev->dev;307	int ret;308 309	indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));310	if (!indio_dev)311		return dev_err_probe(dev, -ENOMEM,312				     "Failed allocating iio device\n");313 314	adc = iio_priv(indio_dev);315	adc->dev = dev;316 317	mutex_init(&adc->lock);318	adc->regs = devm_platform_ioremap_resource(pdev, 0);319	if (IS_ERR(adc->regs))320		return dev_err_probe(dev, PTR_ERR(adc->regs),321				     "Failed getting ioremap resource\n");322 323	/* The third irq is for ADC conversion usage */324	adc->irq = platform_get_irq(pdev, 2);325	if (adc->irq < 0)326		return adc->irq;327 328	adc->ipg_clk = devm_clk_get(dev, "ipg");329	if (IS_ERR(adc->ipg_clk))330		return dev_err_probe(dev, PTR_ERR(adc->ipg_clk),331				     "Failed getting clock.\n");332 333	adc->vref = devm_regulator_get(dev, "vref");334	if (IS_ERR(adc->vref))335		return dev_err_probe(dev, PTR_ERR(adc->vref),336				     "Failed getting reference voltage.\n");337 338	ret = regulator_enable(adc->vref);339	if (ret)340		return dev_err_probe(dev, ret,341				     "Failed to enable reference voltage.\n");342 343	platform_set_drvdata(pdev, indio_dev);344 345	init_completion(&adc->completion);346 347	indio_dev->name = "imx93-adc";348	indio_dev->info = &imx93_adc_iio_info;349	indio_dev->modes = INDIO_DIRECT_MODE;350	indio_dev->channels = imx93_adc_iio_channels;351	indio_dev->num_channels = ARRAY_SIZE(imx93_adc_iio_channels);352 353	ret = clk_prepare_enable(adc->ipg_clk);354	if (ret) {355		dev_err_probe(dev, ret,356			      "Failed to enable ipg clock.\n");357		goto error_regulator_disable;358	}359 360	ret = request_irq(adc->irq, imx93_adc_isr, 0, IMX93_ADC_DRIVER_NAME, adc);361	if (ret < 0) {362		dev_err_probe(dev, ret,363			      "Failed requesting irq, irq = %d\n", adc->irq);364		goto error_ipg_clk_disable;365	}366 367	ret = imx93_adc_calibration(adc);368	if (ret < 0)369		goto error_free_adc_irq;370 371	imx93_adc_config_ad_clk(adc);372 373	ret = iio_device_register(indio_dev);374	if (ret) {375		dev_err_probe(dev, ret,376			      "Failed to register this iio device.\n");377		goto error_adc_power_down;378	}379 380	pm_runtime_set_active(dev);381	pm_runtime_set_autosuspend_delay(dev, 50);382	pm_runtime_use_autosuspend(dev);383	pm_runtime_enable(dev);384 385	return 0;386 387error_adc_power_down:388	imx93_adc_power_down(adc);389error_free_adc_irq:390	free_irq(adc->irq, adc);391error_ipg_clk_disable:392	clk_disable_unprepare(adc->ipg_clk);393error_regulator_disable:394	regulator_disable(adc->vref);395 396	return ret;397}398 399static void imx93_adc_remove(struct platform_device *pdev)400{401	struct iio_dev *indio_dev = platform_get_drvdata(pdev);402	struct imx93_adc *adc = iio_priv(indio_dev);403	struct device *dev = adc->dev;404 405	/* adc power down need clock on */406	pm_runtime_get_sync(dev);407 408	pm_runtime_disable(dev);409	pm_runtime_dont_use_autosuspend(dev);410	pm_runtime_put_noidle(dev);411 412	iio_device_unregister(indio_dev);413	imx93_adc_power_down(adc);414	free_irq(adc->irq, adc);415	clk_disable_unprepare(adc->ipg_clk);416	regulator_disable(adc->vref);417}418 419static int imx93_adc_runtime_suspend(struct device *dev)420{421	struct iio_dev *indio_dev = dev_get_drvdata(dev);422	struct imx93_adc *adc = iio_priv(indio_dev);423 424	imx93_adc_power_down(adc);425	clk_disable_unprepare(adc->ipg_clk);426	regulator_disable(adc->vref);427 428	return 0;429}430 431static int imx93_adc_runtime_resume(struct device *dev)432{433	struct iio_dev *indio_dev = dev_get_drvdata(dev);434	struct imx93_adc *adc = iio_priv(indio_dev);435	int ret;436 437	ret = regulator_enable(adc->vref);438	if (ret) {439		dev_err(dev,440			"Can't enable adc reference top voltage, err = %d\n",441			ret);442		return ret;443	}444 445	ret = clk_prepare_enable(adc->ipg_clk);446	if (ret) {447		dev_err(dev, "Could not prepare or enable clock.\n");448		goto err_disable_reg;449	}450 451	imx93_adc_power_up(adc);452 453	return 0;454 455err_disable_reg:456	regulator_disable(adc->vref);457 458	return ret;459}460 461static DEFINE_RUNTIME_DEV_PM_OPS(imx93_adc_pm_ops,462				 imx93_adc_runtime_suspend,463				 imx93_adc_runtime_resume, NULL);464 465static const struct of_device_id imx93_adc_match[] = {466	{ .compatible = "nxp,imx93-adc", },467	{ /* sentinel */ }468};469MODULE_DEVICE_TABLE(of, imx93_adc_match);470 471static struct platform_driver imx93_adc_driver = {472	.probe		= imx93_adc_probe,473	.remove_new	= imx93_adc_remove,474	.driver		= {475		.name	= IMX93_ADC_DRIVER_NAME,476		.of_match_table = imx93_adc_match,477		.pm	= pm_ptr(&imx93_adc_pm_ops),478	},479};480 481module_platform_driver(imx93_adc_driver);482 483MODULE_DESCRIPTION("NXP i.MX93 ADC driver");484MODULE_AUTHOR("Haibo Chen <haibo.chen@nxp.com>");485MODULE_LICENSE("GPL");486