summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 5744f1673cba..2b728863a3ff 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -51,12 +51,11 @@
#define AD2S1210_MIN_CLKIN 6144000
#define AD2S1210_MAX_CLKIN 10240000
#define AD2S1210_MIN_EXCIT 2000
+#define AD2S1210_DEF_EXCIT 10000
#define AD2S1210_MAX_EXCIT 20000
#define AD2S1210_MIN_FCW 0x4
#define AD2S1210_MAX_FCW 0x50
-#define AD2S1210_DEF_EXCIT 10000
-
enum ad2s1210_mode {
MOD_POS = 0b00,
MOD_VEL = 0b01,
@@ -189,18 +188,32 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
return 0;
}
-static inline
-int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
+/*
+ * Sets the excitation frequency and performs software reset.
+ *
+ * Must be called with lock held.
+ */
+static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
+ u16 fexcit)
{
- unsigned char fcw;
+ int ret;
+ u8 fcw;
- fcw = (unsigned char)(st->fexcit * (1 << 15) / st->clkin_hz);
- if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW) {
- dev_err(&st->sdev->dev, "ad2s1210: FCW out of range\n");
+ fcw = fexcit * (1 << 15) / st->clkin_hz;
+ if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW)
return -ERANGE;
- }
- return regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
+ ret = regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
+ if (ret < 0)
+ return ret;
+
+ st->fexcit = fexcit;
+
+ /*
+ * 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);
}
static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
@@ -215,11 +228,6 @@ static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
bitmap);
}
-static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
-{
- return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
-}
-
static ssize_t ad2s1210_show_fexcit(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -234,27 +242,24 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned int fexcit;
+ u16 fexcit;
int ret;
- ret = kstrtouint(buf, 10, &fexcit);
- if (ret < 0)
- return ret;
- if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
- dev_err(dev,
- "ad2s1210: excitation frequency out of range\n");
+ ret = kstrtou16(buf, 10, &fexcit);
+ if (ret < 0 || fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT)
return -EINVAL;
- }
+
mutex_lock(&st->lock);
- st->fexcit = fexcit;
- ret = ad2s1210_update_frequency_control_word(st);
+ ret = ad2s1210_reinit_excitation_frequency(st, fexcit);
if (ret < 0)
goto error_ret;
- ret = ad2s1210_soft_reset(st);
+
+ ret = len;
+
error_ret:
mutex_unlock(&st->lock);
- return ret < 0 ? ret : len;
+ return ret;
}
static ssize_t ad2s1210_show_resolution(struct device *dev,
@@ -551,10 +556,8 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
if (ret < 0)
goto error_ret;
- ret = ad2s1210_update_frequency_control_word(st);
- if (ret < 0)
- goto error_ret;
- ret = ad2s1210_soft_reset(st);
+ ret = ad2s1210_reinit_excitation_frequency(st, AD2S1210_DEF_EXCIT);
+
error_ret:
mutex_unlock(&st->lock);
return ret;
@@ -698,7 +701,6 @@ static int ad2s1210_probe(struct spi_device *spi)
st->sdev = spi;
st->hysteresis = true;
st->resolution = 12;
- st->fexcit = AD2S1210_DEF_EXCIT;
ret = ad2s1210_setup_clocks(st);
if (ret < 0)