Commit 4c2b3167 authored by Federico Vaga's avatar Federico Vaga

drv: fix range-set/calibration synchronization

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent cc51948a
...@@ -130,19 +130,22 @@ static int fa_calib_dac_gain_fix(int range, uint32_t gain_c, ...@@ -130,19 +130,22 @@ static int fa_calib_dac_gain_fix(int range, uint32_t gain_c,
return gain_c - error; return gain_c - error;
} }
/**
* Calibrate a ADC channel
* @fa ADC instance
* @chan channel number
* @temperature temperature
*
* You must hold &fa->zdev->cset->lock while calling this function
*/
void fa_calib_adc_config_chan(struct fa_dev *fa, unsigned int chan, void fa_calib_adc_config_chan(struct fa_dev *fa, unsigned int chan,
int32_t temperature) int32_t temperature)
{ {
struct fa_calib_stanza *cal; int range = fa->range[chan];
int range; struct fa_calib_stanza *cal = &fa->calib.dac[range];
int gain; int gain;
int err; int err;
spin_lock(&fa->zdev->cset->lock);
range = fa->range[chan];
spin_unlock(&fa->zdev->cset->lock);
cal = &fa->calib.dac[range];
if (temperature == 0xFFFFFFFF) if (temperature == 0xFFFFFFFF)
temperature = fa_temperature_read(fa); temperature = fa_temperature_read(fa);
if (unlikely((fa->flags & FA_DEV_F_PATTERN_DATA))) if (unlikely((fa->flags & FA_DEV_F_PATTERN_DATA)))
...@@ -219,21 +222,24 @@ static int fa_dac_offset_get(struct fa_dev *fa, unsigned int chan) ...@@ -219,21 +222,24 @@ static int fa_dac_offset_get(struct fa_dev *fa, unsigned int chan)
return off_uv; return off_uv;
} }
/**
* Calibrate a DAC channel
* @fa ADC instance
* @chan channel number
* @temperature temperature
*
* You must hold &fa->zdev->cset->lock while calling this function
*/
int fa_calib_dac_config_chan(struct fa_dev *fa, unsigned int chan, int fa_calib_dac_config_chan(struct fa_dev *fa, unsigned int chan,
int32_t temperature) int32_t temperature)
{ {
int32_t off_uv = fa_dac_offset_get(fa, chan); int32_t off_uv = fa_dac_offset_get(fa, chan);
int32_t off_uv_raw = fa_dac_offset_raw_get(off_uv); int32_t off_uv_raw = fa_dac_offset_raw_get(off_uv);
struct fa_calib_stanza *cal; int range = fa->range[chan];
int range; struct fa_calib_stanza *cal = &fa->calib.dac[range];
int gain; int gain;
int hwval; int hwval;
spin_lock(&fa->zdev->cset->lock);
range = fa->range[chan];
spin_unlock(&fa->zdev->cset->lock);
cal = &fa->calib.dac[range];
if (temperature == 0xFFFFFFFF) if (temperature == 0xFFFFFFFF)
temperature = fa_temperature_read(fa); temperature = fa_temperature_read(fa);
...@@ -258,10 +264,12 @@ void fa_calib_config(struct fa_dev *fa) ...@@ -258,10 +264,12 @@ void fa_calib_config(struct fa_dev *fa)
int i; int i;
temperature = fa_temperature_read(fa); temperature = fa_temperature_read(fa);
spin_lock(&fa->zdev->cset->lock);
for (i = 0; i < FA100M14B4C_NCHAN; ++i) { for (i = 0; i < FA100M14B4C_NCHAN; ++i) {
fa_calib_adc_config_chan(fa, i, temperature); fa_calib_adc_config_chan(fa, i, temperature);
fa_calib_dac_config_chan(fa, i, temperature); fa_calib_dac_config_chan(fa, i, temperature);
} }
spin_unlock(&fa->zdev->cset->lock);
} }
/** /**
* Periodically update gain calibration values * Periodically update gain calibration values
......
...@@ -162,11 +162,13 @@ void zfad_reset_offset(struct fa_dev *fa) ...@@ -162,11 +162,13 @@ void zfad_reset_offset(struct fa_dev *fa)
{ {
int i; int i;
spin_lock(&fa->zdev->cset->lock);
for (i = 0; i < FA100M14B4C_NCHAN; ++i) { for (i = 0; i < FA100M14B4C_NCHAN; ++i) {
fa->user_offset[i] = 0; fa->user_offset[i] = 0;
fa->zero_offset[i] = 0; fa->zero_offset[i] = 0;
fa_calib_dac_config_chan(fa, i, ~0); fa_calib_dac_config_chan(fa, i, ~0);
} }
spin_unlock(&fa->zdev->cset->lock);
} }
/* /*
......
...@@ -213,8 +213,8 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr, ...@@ -213,8 +213,8 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
return -EINVAL; return -EINVAL;
spin_lock(&fa->zdev->cset->lock); spin_lock(&fa->zdev->cset->lock);
fa->zero_offset[i] = usr_val; fa->zero_offset[i] = usr_val;
spin_unlock(&fa->zdev->cset->lock);
fa_calib_dac_config_chan(fa, i, ~0); fa_calib_dac_config_chan(fa, i, ~0);
spin_unlock(&fa->zdev->cset->lock);
return 0; return 0;
case ZFA_CHx_SAT: case ZFA_CHx_SAT:
/* TODO when TLV */ /* TODO when TLV */
...@@ -248,14 +248,16 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr, ...@@ -248,14 +248,16 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
return -EINVAL; return -EINVAL;
spin_lock(&fa->zdev->cset->lock); spin_lock(&fa->zdev->cset->lock);
fa->user_offset[chan->index] = usr_val; fa->user_offset[chan->index] = usr_val;
err = fa_calib_dac_config_chan(fa, i, ~0);
spin_unlock(&fa->zdev->cset->lock); spin_unlock(&fa->zdev->cset->lock);
return fa_calib_dac_config_chan(fa, i, ~0); return err;
case ZFA_CHx_OFFSET: case ZFA_CHx_OFFSET:
chan = to_zio_chan(dev); chan = to_zio_chan(dev);
spin_lock(&fa->zdev->cset->lock); spin_lock(&fa->zdev->cset->lock);
fa->user_offset[chan->index] = usr_val; fa->user_offset[chan->index] = usr_val;
err = fa_calib_dac_config_chan(fa, chan->index, ~0);
spin_unlock(&fa->zdev->cset->lock); spin_unlock(&fa->zdev->cset->lock);
return fa_calib_dac_config_chan(fa, chan->index, ~0); return err;
case ZFA_CTL_DAC_CLR_N: case ZFA_CTL_DAC_CLR_N:
zfad_reset_offset(fa); zfad_reset_offset(fa);
return 0; return 0;
...@@ -295,8 +297,10 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr, ...@@ -295,8 +297,10 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
err = fa_adc_range_set(fa, &to_zio_cset(dev)->chan[i], range); err = fa_adc_range_set(fa, &to_zio_cset(dev)->chan[i], range);
if (err) if (err)
return err; return err;
spin_lock(&fa->zdev->cset->lock);
fa_calib_adc_config_chan(fa, i, ~0); fa_calib_adc_config_chan(fa, i, ~0);
fa_calib_dac_config_chan(fa, i, ~0); fa_calib_dac_config_chan(fa, i, ~0);
spin_unlock(&fa->zdev->cset->lock);
return 0; return 0;
case ZFA_CHx_CTL_RANGE: case ZFA_CHx_CTL_RANGE:
...@@ -306,8 +310,10 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr, ...@@ -306,8 +310,10 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
err = fa_adc_range_set(fa, &to_zio_cset(dev)->chan[i], range); err = fa_adc_range_set(fa, &to_zio_cset(dev)->chan[i], range);
if (err) if (err)
return err; return err;
spin_lock(&fa->zdev->cset->lock);
fa_calib_adc_config_chan(fa, i, ~0); fa_calib_adc_config_chan(fa, i, ~0);
fa_calib_dac_config_chan(fa, i, ~0); fa_calib_dac_config_chan(fa, i, ~0);
spin_unlock(&fa->zdev->cset->lock);
return 0; return 0;
case ZFA_UTC_COARSE: case ZFA_UTC_COARSE:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment