Commit 23090067 authored by Federico Vaga's avatar Federico Vaga

drv: add offset-zero value

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent bb859ef7
......@@ -131,22 +131,23 @@ static int zfad_offset_to_dac(struct zio_channel *chan,
/*
* zfad_apply_user_offset
* @fa: the fmc-adc descriptor
* @chan: the channel where apply offset
* @usr_val: the offset value to apply, expressed as millivolts (-5000..5000)
*
* Apply user offset to the channel input. Before apply the user offset it must
* be corrected with offset and gain calibration value. An open input does not
* need any correction.
* be corrected with offset and gain calibration value.
*
* Offset values are taken from `struct fa_dev`, so they must be there before
* calling this function
*/
int zfad_apply_user_offset(struct fa_dev *fa, struct zio_channel *chan,
uint32_t usr_val)
int zfad_apply_offset(struct zio_channel *chan)
{
struct fa_dev *fa = get_zfadc(&chan->cset->zdev->head.dev);
uint32_t range_reg;
int32_t uval = (int32_t)usr_val;
int32_t off_uv;
int hwval, i, range;
if (uval < -5000000 || uval > 5000000)
off_uv = fa->user_offset[chan->index] + fa->zero_offset[chan->index];
if (off_uv < -5000000 || off_uv > 5000000)
return -EINVAL;
i = zfad_get_chx_index(ZFA_CHx_CTL_RANGE, chan);
......@@ -159,7 +160,7 @@ int zfad_apply_user_offset(struct fa_dev *fa, struct zio_channel *chan,
if (range == FA100M14B4C_RANGE_OPEN || fa_enable_test_data_adc)
range = FA100M14B4C_RANGE_1V;
hwval = zfad_offset_to_dac(chan, usr_val, range);
hwval = zfad_offset_to_dac(chan, off_uv, range);
return zfad_dac_set(chan, hwval);
}
......@@ -173,8 +174,11 @@ void zfad_reset_offset(struct fa_dev *fa)
{
int i;
for (i = 0; i < FA100M14B4C_NCHAN; ++i)
zfad_apply_user_offset(fa, &fa->zdev->cset->chan[i], 0);
for (i = 0; i < FA100M14B4C_NCHAN; ++i) {
fa->user_offset[i] = 0;
fa->zero_offset[i] = 0;
zfad_apply_offset(&fa->zdev->cset->chan[i]);
}
}
/*
......@@ -210,25 +214,18 @@ int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan,
i = zfad_get_chx_index(ZFA_CHx_CTL_RANGE, chan);
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[i], zfad_hw_range[range]);
if (range == FA100M14B4C_RANGE_OPEN || fa_enable_test_data_adc) {
/*
* With OPEN range we do not use calibration values
*
* In test mode we do not apply the gain/offset because
* this compromises the test pattern
*/
offset = FA_CAL_NO_OFFSET;
gain = FA_CAL_NO_GAIN;
} else {
if (range < 0 || range > ARRAY_SIZE(fa->calib.adc)) {
dev_info(fa->msgdev, "Invalid range %i or ch %i\n",
range, chan->index);
return -EINVAL;
}
offset = fa->calib.adc[range].offset[chan->index];
gain = fa->calib.adc[range].gain[chan->index];
if (range == FA100M14B4C_RANGE_OPEN || fa_enable_test_data_adc)
range = FA100M14B4C_RANGE_1V;
if (range < 0 || range > ARRAY_SIZE(fa->calib.adc)) {
dev_info(fa->msgdev, "Invalid range %i or ch %i\n",
range, chan->index);
return -EINVAL;
}
offset = fa->calib.adc[range].offset[chan->index];
gain = fa->calib.adc[range].gain[chan->index];
i = zfad_get_chx_index(ZFA_CHx_OFFSET, chan);
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[i],
offset & 0xffff /* prevent warning */);
......@@ -236,7 +233,7 @@ int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan,
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[i], gain);
/* recalculate user offset for the new range */
zfad_apply_user_offset(fa, chan, fa->user_offset[chan->index]);
zfad_apply_offset(chan);
return 0;
}
......
......@@ -47,6 +47,11 @@ static struct zio_attribute zfad_cset_ext_zattr[] = {
ZIO_ATTR_EXT("ch2-offset", ZIO_RW_PERM, ZFA_CH3_OFFSET, 0),
ZIO_ATTR_EXT("ch3-offset", ZIO_RW_PERM, ZFA_CH4_OFFSET, 0),
ZIO_ATTR_EXT("ch0-offset-zero", ZIO_RW_PERM, ZFA_SW_CH1_OFFSET_ZERO, 0),
ZIO_ATTR_EXT("ch1-offset-zero", ZIO_RW_PERM, ZFA_SW_CH2_OFFSET_ZERO, 0),
ZIO_ATTR_EXT("ch2-offset-zero", ZIO_RW_PERM, ZFA_SW_CH3_OFFSET_ZERO, 0),
ZIO_ATTR_EXT("ch3-offset-zero", ZIO_RW_PERM, ZFA_SW_CH4_OFFSET_ZERO, 0),
ZIO_ATTR_EXT("ch0-vref", ZIO_RW_PERM, ZFA_CH1_CTL_RANGE, 0),
ZIO_ATTR_EXT("ch1-vref", ZIO_RW_PERM, ZFA_CH2_CTL_RANGE, 0),
ZIO_ATTR_EXT("ch2-vref", ZIO_RW_PERM, ZFA_CH3_CTL_RANGE, 0),
......@@ -168,6 +173,7 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
unsigned int baseoff = fa->fa_adc_csr_base;
struct zio_channel *chan;
int i, range, err = 0, reg_index;
uint32_t off;
reg_index = zattr->id;
i = FA100M14B4C_NCHAN;
......@@ -186,6 +192,21 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
case ZFA_SW_R_NOADDERS_AUTO:
fa->enable_auto_start = usr_val;
return 0;
case ZFA_SW_CH1_OFFSET_ZERO:
i--;
case ZFA_SW_CH2_OFFSET_ZERO:
i--;
case ZFA_SW_CH3_OFFSET_ZERO:
i--;
case ZFA_SW_CH4_OFFSET_ZERO:
i--;
chan = to_zio_cset(dev)->chan + i;
fa->zero_offset[i] = usr_val;
err = zfad_apply_offset(chan);
if (err == -EIO)
fa->zero_offset[chan->index] = 0;
return err;
case ZFA_CHx_SAT:
/* TODO when TLV */
break;
......@@ -209,21 +230,20 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
i--;
case ZFA_CH4_OFFSET:
i--;
chan = to_zio_cset(dev)->chan + i;
err = zfad_apply_user_offset(fa, chan, usr_val);
if (err)
return err;
fa->user_offset[chan->index] = usr_val;
return 0;
err = zfad_apply_offset(chan);
if (err == -EIO)
fa->user_offset[chan->index] = 0;
return err;
case ZFA_CHx_OFFSET:
chan = to_zio_chan(dev),
err = zfad_apply_user_offset(fa, chan, usr_val);
if (err)
return err;
fa->user_offset[chan->index] = usr_val;
return 0;
err = zfad_apply_offset(chan);
if (err == -EIO)
fa->user_offset[chan->index] = 0;
return err;
case ZFA_CTL_DAC_CLR_N:
zfad_reset_offset(fa);
return 0;
......@@ -341,6 +361,16 @@ static int zfad_info_get(struct device *dev, struct zio_attribute *zattr,
*usr_val = fa_read_temp(fa, 0);
*usr_val = (*usr_val * 1000 + 8) / 16;
return 0;
case ZFA_SW_CH1_OFFSET_ZERO:
i--;
case ZFA_SW_CH2_OFFSET_ZERO:
i--;
case ZFA_SW_CH3_OFFSET_ZERO:
i--;
case ZFA_SW_CH4_OFFSET_ZERO:
i--;
*usr_val = fa->zero_offset[i];
return 0;
case ZFA_CHx_SAT:
case ZFA_CHx_CTL_TERM:
case ZFA_CHx_CTL_RANGE:
......
......@@ -303,6 +303,10 @@ enum fa_sw_param_id {
ZFA_SW_R_NOADDRES_TEMP,
ZFA_SW_R_NOADDERS_AUTO,
ZFA_SW_CH1_OFFSET_ZERO,
ZFA_SW_CH2_OFFSET_ZERO,
ZFA_SW_CH3_OFFSET_ZERO,
ZFA_SW_CH4_OFFSET_ZERO,
ZFA_SW_PARAM_COMMON_LAST,
};
......@@ -366,7 +370,8 @@ struct fa_calib {
* @n_fires: number of trigger fire occurred within an acquisition
*
* @n_dma_err: number of errors
*
* @user_offset: user offset (micro-Volts)
* @zero_offset: necessary offset to push the channel to zero (micro-Volts)
*/
struct fa_dev {
struct device *msgdev; /**< device used to print messages */
......@@ -410,8 +415,8 @@ struct fa_dev {
unsigned int n_dma_err;
/* Configuration */
int user_offset[4]; /* one per channel */
int32_t user_offset[4]; /* one per channel */
int32_t zero_offset[FA100M14B4C_NCHAN];
/* one-wire */
uint8_t ds18_id[8];
unsigned long next_t;
......@@ -545,8 +550,7 @@ extern const struct zfa_field_desc zfad_regs[];
/* Functions exported by fa-core.c */
extern int zfad_fsm_command(struct fa_dev *fa, uint32_t command);
extern int zfad_apply_user_offset(struct fa_dev *fa, struct zio_channel *chan,
uint32_t usr_val);
extern int zfad_apply_offset(struct zio_channel *chan);
extern void zfad_reset_offset(struct fa_dev *fa);
extern int zfad_convert_hw_range(uint32_t bitmask);
extern int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan,
......
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