Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd2723f5 authored by Naveen Krishna Chatradhi's avatar Naveen Krishna Chatradhi Committed by Jonathan Cameron
Browse files

iio: exynos_adc: do a soft reset in case of timeout



Do a soft reset software if a timeout happens.
This is applicable only for ADC_V2.

Signed-off-by: default avatarNaveen Krishna Chatradhi <ch.naveen@samsung.com>
Reviewed-by: default avatarDoug Anderson <dianders@chromium.org>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent c780a8c2
Loading
Loading
Loading
Loading
+26 −24
Original line number Diff line number Diff line
@@ -112,6 +112,30 @@ static inline unsigned int exynos_adc_get_version(struct platform_device *pdev)
	return (unsigned int)match->data;
}

static void exynos_adc_hw_init(struct exynos_adc *info)
{
	u32 con1, con2;

	if (info->version == ADC_V2) {
		con1 = ADC_V2_CON1_SOFT_RESET;
		writel(con1, ADC_V2_CON1(info->regs));

		con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
			ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
		writel(con2, ADC_V2_CON2(info->regs));

		/* Enable interrupts */
		writel(1, ADC_V2_INT_EN(info->regs));
	} else {
		/* set default prescaler values and Enable prescaler */
		con1 =  ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;

		/* Enable 12-bit ADC resolution */
		con1 |= ADC_V1_CON_RES;
		writel(con1, ADC_V1_CON(info->regs));
	}
}

static int exynos_read_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan,
				int *val,
@@ -149,6 +173,8 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
	timeout = wait_for_completion_timeout
			(&info->completion, EXYNOS_ADC_TIMEOUT);
	if (timeout == 0) {
		dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
		exynos_adc_hw_init(info);
		ret = -ETIMEDOUT;
	} else {
		*val = info->value;
@@ -230,30 +256,6 @@ static int exynos_adc_remove_devices(struct device *dev, void *c)
	return 0;
}

static void exynos_adc_hw_init(struct exynos_adc *info)
{
	u32 con1, con2;

	if (info->version == ADC_V2) {
		con1 = ADC_V2_CON1_SOFT_RESET;
		writel(con1, ADC_V2_CON1(info->regs));

		con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
			ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
		writel(con2, ADC_V2_CON2(info->regs));

		/* Enable interrupts */
		writel(1, ADC_V2_INT_EN(info->regs));
	} else {
		/* set default prescaler values and Enable prescaler */
		con1 =  ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;

		/* Enable 12-bit ADC resolution */
		con1 |= ADC_V1_CON_RES;
		writel(con1, ADC_V1_CON(info->regs));
	}
}

static int exynos_adc_probe(struct platform_device *pdev)
{
	struct exynos_adc *info = NULL;