[PATCH v5 2/4] staging: iio: resolver: ad2s1210: clear faults after soft reset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When a software reset is performed on the AD2S1210 to make the selected
excitation frequency take effect, it always triggers faults on the
input signals because the output signal is interrupted momentarily.
So we need to clear the faults after the software reset to avoid
triggering fault events the next time a sample is read.

The datasheet specifies a time t[track] in Table 27 that specifies the
settle time in milliseconds after a reset depending on the selected
resolution. This is used in the driver to add an appropriate delay.

Signed-off-by: David Lechner <dlechner@xxxxxxxxxxxx>
---

v5 changes: New patch in v5.

 drivers/staging/iio/resolver/ad2s1210.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 59c273a4b6a9..cf4018434447 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -314,6 +314,9 @@ static void ad2s1210_toggle_sample_line(struct ad2s1210_state *st)
 static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
 						u16 fexcit)
 {
+	/* Map resolution to settle time in milliseconds. */
+	static const int track_time_ms[] = { 10, 20, 25, 60 };
+	unsigned int ignored;
 	int ret;
 	u8 fcw;
 
@@ -329,7 +332,27 @@ static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
 	 * Software reset reinitializes the excitation frequency output.
 	 * It does not reset any of the configuration registers.
 	 */
-	return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
+	ret = regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Soft reset always triggers some faults due the change in the output
+	 * signal so clear the faults too. We need to delay for some time
+	 * (what datasheet calls t[track]) to allow things to settle before
+	 * clearing the faults.
+	 */
+	msleep(track_time_ms[st->resolution] * 8192000 / st->clkin_hz);
+
+	/* Reading the fault register clears the faults. */
+	ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &ignored);
+	if (ret < 0)
+		return ret;
+
+	/* Have to toggle sample line to get fault output pins to reset. */
+	ad2s1210_toggle_sample_line(st);
+
+	return 0;
 }
 
 static void ad2s1210_push_events(struct iio_dev *indio_dev,

-- 
2.42.0





[Index of Archives]     [Linux Driver Development]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux