Commit b66c7243 authored by Federico Vaga's avatar Federico Vaga

drv: re-write ADC data pattern code in debugfs

Do not use any calibration data while there is a pattern applied
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 230e2ed6
...@@ -137,8 +137,10 @@ static void fa_calib_adc_config_chan(struct fa_dev *fa, unsigned int chan, ...@@ -137,8 +137,10 @@ static void fa_calib_adc_config_chan(struct fa_dev *fa, unsigned int chan,
struct fa_calib_stanza *cal = &fa->calib.adc[range]; struct fa_calib_stanza *cal = &fa->calib.adc[range];
int32_t delta_temp = temperature - cal->temperature; int32_t delta_temp = temperature - cal->temperature;
int offset = cal->offset[chan]; int offset = cal->offset[chan];
int gain = fa_calib_adc_gain_fix(range, cal->gain[chan], int gain = cal->gain[chan];
delta_temp);
if (unlikely(!(fa->flags & FA_DEV_F_PATTERN_DATA)))
gain = fa_calib_adc_gain_fix(range, gain, delta_temp);
dev_dbg(&fa->pdev->dev, "%s: {chan: %d, range: %d, gain: 0x%x, offset: 0x%x}\n", dev_dbg(&fa->pdev->dev, "%s: {chan: %d, range: %d, gain: 0x%x, offset: 0x%x}\n",
__func__, chan, range, gain, offset); __func__, chan, range, gain, offset);
...@@ -213,9 +215,12 @@ static int fa_calib_dac_config_chan(struct fa_dev *fa, unsigned int chan, ...@@ -213,9 +215,12 @@ static int fa_calib_dac_config_chan(struct fa_dev *fa, unsigned int chan,
struct fa_calib_stanza *cal = &fa->calib.dac[range]; struct fa_calib_stanza *cal = &fa->calib.dac[range];
int32_t delta_temp = temperature - cal->temperature; int32_t delta_temp = temperature - cal->temperature;
int offset = cal->offset[chan]; int offset = cal->offset[chan];
int gain = fa_calib_dac_gain_fix(range, cal->gain[chan], delta_temp); int gain = cal->gain[chan];
int hwval; int hwval;
if (unlikely(!(fa->flags & FA_DEV_F_PATTERN_DATA)))
gain = fa_calib_dac_gain_fix(range, gain, delta_temp);
dev_dbg(&fa->pdev->dev, "%s: {chan: %d, range: %d, gain: 0x%x, offset: 0x%x}\n", dev_dbg(&fa->pdev->dev, "%s: {chan: %d, range: %d, gain: 0x%x, offset: 0x%x}\n",
__func__, chan, range, gain, offset); __func__, chan, range, gain, offset);
hwval = fa_dac_offset_raw_calibrate(off_uv_raw, gain, offset); hwval = fa_dac_offset_raw_calibrate(off_uv_raw, gain, offset);
...@@ -479,4 +484,5 @@ out: ...@@ -479,4 +484,5 @@ out:
void fa_calib_exit(struct fa_dev *fa) void fa_calib_exit(struct fa_dev *fa)
{ {
del_timer_sync(&fa->calib_timer); del_timer_sync(&fa->calib_timer);
fa_identity_calib_set(&fa->calib);
} }
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
static int fa_enable_test_data_fpga; static int fa_enable_test_data_fpga;
module_param_named(enable_test_data_fpga, fa_enable_test_data_fpga, int, 0444); module_param_named(enable_test_data_fpga, fa_enable_test_data_fpga, int, 0444);
int fa_enable_test_data_adc = 0;
module_param_named(enable_test_data_adc, fa_enable_test_data_adc, int, 0444);
#define FA_EEPROM_TYPE "at24c64" #define FA_EEPROM_TYPE "at24c64"
...@@ -154,36 +152,6 @@ int zfad_get_chx_index(unsigned long addr, unsigned int chan) ...@@ -154,36 +152,6 @@ int zfad_get_chx_index(unsigned long addr, unsigned int chan)
} }
/**
* It enables or disables the pattern data on the ADC
* @fa The ADC device instance
* @pattern the pattern data to get from the ADC
* @enable 0 to disable, 1 to enable
*/
int zfad_pattern_data_enable(struct fa_dev *fa, uint16_t pattern,
unsigned int enable)
{
uint32_t frame_tx;
int err;
frame_tx = 0x0000; /* write mode */
frame_tx |= 0x0400; /* A4 pattern */
frame_tx |= pattern & 0xFF; /* LSB pattern */
err = fa_spi_xfer(fa, FA_SPI_SS_ADC, 16, frame_tx, NULL);
if (err)
return err;
frame_tx = 0x0000; /* write mode */
frame_tx |= 0x0300; /* A3 pattern + enable */
frame_tx |= (pattern & 0xFF00) >> 8; /* MSB pattern */
frame_tx |= (enable ? 0x80 : 0x00); /* Enable the pattern data */
err = fa_spi_xfer(fa, FA_SPI_SS_ADC, 16, frame_tx, NULL);
if (err)
return err;
return 0;
}
/* /*
* zfad_reset_offset * zfad_reset_offset
* @fa: the fmc-adc descriptor * @fa: the fmc-adc descriptor
...@@ -234,7 +202,8 @@ int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan, ...@@ -234,7 +202,8 @@ int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan,
i = zfad_get_chx_index(ZFA_CHx_CTL_RANGE, chan->index); i = zfad_get_chx_index(ZFA_CHx_CTL_RANGE, chan->index);
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[i], zfad_hw_range[range]); 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) if (range == FA100M14B4C_RANGE_OPEN ||
(fa->flags & FA_DEV_F_PATTERN_DATA))
range = FA100M14B4C_RANGE_1V; range = FA100M14B4C_RANGE_1V;
else if (range >= FA100M14B4C_RANGE_10V_CAL) else if (range >= FA100M14B4C_RANGE_10V_CAL)
range -= FA100M14B4C_RANGE_10V_CAL; range -= FA100M14B4C_RANGE_10V_CAL;
...@@ -287,6 +256,46 @@ static void fa_fpga_data_pattern_set(struct fa_dev *fa, unsigned int enable) ...@@ -287,6 +256,46 @@ static void fa_fpga_data_pattern_set(struct fa_dev *fa, unsigned int enable)
&zfad_regs[ZFA_CTL_TEST_DATA_EN], enable); &zfad_regs[ZFA_CTL_TEST_DATA_EN], enable);
} }
/**
* It enables or disables the pattern data on the ADC
* @fa The ADC device instance
* @pattern the pattern data to get from the ADC
* @enable 0 to disable, 1 to enable
*/
int fa_adc_data_pattern_set(struct fa_dev *fa, uint16_t pattern,
unsigned int enable)
{
uint32_t frame_tx;
int err;
dev_dbg(&fa->pdev->dev, "%s {patter: 0x%04x, enable: %d}\n", __func__, pattern, enable);
spin_lock(&fa->zdev->cset->lock);
frame_tx = 0x0000; /* write mode */
frame_tx |= 0x0400; /* A4 pattern */
frame_tx |= pattern & 0xFF; /* LSB pattern */
err = fa_spi_xfer(fa, FA_SPI_SS_ADC, 16, frame_tx, NULL);
if (err)
goto err;
frame_tx = 0x0000; /* write mode */
frame_tx |= 0x0300; /* A3 pattern + enable */
frame_tx |= (pattern & 0xFF00) >> 8; /* MSB pattern */
frame_tx |= (enable ? 0x80 : 0x00); /* Enable the pattern data */
err = fa_spi_xfer(fa, FA_SPI_SS_ADC, 16, frame_tx, NULL);
if (err)
goto err;
if (enable)
fa->flags |= FA_DEV_F_PATTERN_DATA;
else
fa->flags &= ~FA_DEV_F_PATTERN_DATA;
err:
spin_unlock(&fa->zdev->cset->lock);
return err;
}
/* /*
* zfad_fsm_command * zfad_fsm_command
* @fa: the fmc-adc descriptor * @fa: the fmc-adc descriptor
...@@ -419,6 +428,8 @@ static int __fa_init(struct fa_dev *fa) ...@@ -419,6 +428,8 @@ static int __fa_init(struct fa_dev *fa)
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_SR_UNDER], 1); fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_SR_UNDER], 1);
/* Set test data register */ /* Set test data register */
fa_fpga_data_pattern_set(fa, fa_enable_test_data_fpga); fa_fpga_data_pattern_set(fa, fa_enable_test_data_fpga);
/* disable test pattern data in the ADC */
fa_adc_data_pattern_set(fa, 0, 0);
/* Set to single shot mode by default */ /* Set to single shot mode by default */
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_SHOTS_NB], 1); fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_SHOTS_NB], 1);
......
...@@ -180,6 +180,58 @@ static const struct file_operations fa_trg_sw_ops = { ...@@ -180,6 +180,58 @@ static const struct file_operations fa_trg_sw_ops = {
.write = fa_trg_sw_write, .write = fa_trg_sw_write,
}; };
#define FA_ADC_DATA_PATTERN_CMD_SIZE 16UL
static int fa_data_pattern_adc_write(struct fa_dev *fa, const char __user *buf,
size_t count)
{
char buf_l[FA_ADC_DATA_PATTERN_CMD_SIZE];
int err;
memset(buf_l, 0, FA_ADC_DATA_PATTERN_CMD_SIZE);
err = copy_from_user(buf_l, buf, min(count,
FA_ADC_DATA_PATTERN_CMD_SIZE));
if (err)
return -EFAULT;
if ((count == 1 || count == 2)&& buf_l[0] == '0') {
fa_calib_init(fa);
return fa_adc_data_pattern_set(fa, 0, 0);
} else if (count > 2 && buf_l[0] == '1' && buf_l[1] == ' ') {
uint16_t pattern = 0;
err = kstrtou16(buf_l + 2, 0, &pattern);
if (err)
return err;
fa_calib_exit(fa);
pattern &= 0xFFF;
return fa_adc_data_pattern_set(fa, pattern, 1);
} else {
return -EINVAL;
}
}
static ssize_t fa_data_pattern_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct fa_dev *fa = file->private_data;
if (strncmp(buf, "adc ", 4) == 0) {
int err;
err = fa_data_pattern_adc_write(fa, buf + 4, count - 4);
return err ? err : count;
} else {
dev_err(&fa->pdev->dev, "Unknown command \"%s\"\n", buf);
return -EINVAL;
}
}
static const struct file_operations fa_data_pattern_ops = {
.owner = THIS_MODULE,
.open = simple_open,
.write = fa_data_pattern_write,
};
int fa_debug_init(struct fa_dev *fa) int fa_debug_init(struct fa_dev *fa)
{ {
...@@ -222,6 +274,14 @@ int fa_debug_init(struct fa_dev *fa) ...@@ -222,6 +274,14 @@ int fa_debug_init(struct fa_dev *fa)
"Cannot create software trigger file\n"); "Cannot create software trigger file\n");
} }
fa->dbg_data_pattern = debugfs_create_file("data_pattern", 0200,
fa->dbg_dir, fa,
&fa_data_pattern_ops);
if (IS_ERR_OR_NULL(fa->dbg_data_pattern)) {
dev_warn(&fa->pdev->dev,
"Cannot create ADC data pattern file\n");
}
return 0; return 0;
} }
......
...@@ -123,7 +123,6 @@ static struct zio_attribute zfad_cset_ext_zattr[] = { ...@@ -123,7 +123,6 @@ static struct zio_attribute zfad_cset_ext_zattr[] = {
ZIO_PARAM_EXT("sample-frequency", ZIO_RO_PERM, ZFAT_SAMPLING_HZ, 0), ZIO_PARAM_EXT("sample-frequency", ZIO_RO_PERM, ZFAT_SAMPLING_HZ, 0),
ZIO_PARAM_EXT("max-sample-mshot", ZIO_RO_PERM, ZFA_MULT_MAX_SAMP, 0), ZIO_PARAM_EXT("max-sample-mshot", ZIO_RO_PERM, ZFA_MULT_MAX_SAMP, 0),
ZIO_PARAM_EXT("sample-counter", ZIO_RO_PERM, ZFAT_CNT, 0), ZIO_PARAM_EXT("sample-counter", ZIO_RO_PERM, ZFAT_CNT, 0),
ZIO_PARAM_EXT("test-data-pattern", ZIO_RW_PERM, ZFAT_ADC_TST_PATTERN, 0),
}; };
#if 0 /* FIXME Unused until TLV control will be available */ #if 0 /* FIXME Unused until TLV control will be available */
...@@ -177,7 +176,7 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr, ...@@ -177,7 +176,7 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
struct fa_dev *fa = get_zfadc(dev); struct fa_dev *fa = get_zfadc(dev);
void *baseoff = fa->fa_adc_csr_base; void *baseoff = fa->fa_adc_csr_base;
struct zio_channel *chan; struct zio_channel *chan;
int i, range, err = 0, reg_index; int i, range, reg_index;
reg_index = zattr->id; reg_index = zattr->id;
i = FA100M14B4C_NCHAN; i = FA100M14B4C_NCHAN;
...@@ -313,24 +312,6 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr, ...@@ -313,24 +312,6 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
break; break;
case ZFA_CTL_FMS_CMD: case ZFA_CTL_FMS_CMD:
return zfad_fsm_command(fa, usr_val); return zfad_fsm_command(fa, usr_val);
case ZFAT_ADC_TST_PATTERN:
if (unlikely(fa_enable_test_data_adc)) {
usr_val &= 0xFFF;
err = zfad_pattern_data_enable(fa, usr_val,
fa_enable_test_data_adc);
if (err)
dev_warn(fa->msgdev,
"Failed to set the ADC test data. Continue without\n");
else if (fa_enable_test_data_adc)
dev_info(fa->msgdev,
"the ADC test data (0x%x) is enabled on all channels\n",
usr_val);
return err;
} else {
dev_err(fa->msgdev,
"Cannot set the ADC test data. The driver is not in test mode\n");
return -EPERM;
}
} }
fa_writel(fa, baseoff, &zfad_regs[reg_index], usr_val); fa_writel(fa, baseoff, &zfad_regs[reg_index], usr_val);
...@@ -374,8 +355,6 @@ static int zfad_info_get(struct device *dev, struct zio_attribute *zattr, ...@@ -374,8 +355,6 @@ static int zfad_info_get(struct device *dev, struct zio_attribute *zattr,
case ZFA_CHx_OFFSET: case ZFA_CHx_OFFSET:
*usr_val = fa->user_offset[to_zio_chan(dev)->index]; *usr_val = fa->user_offset[to_zio_chan(dev)->index];
return 0; return 0;
case ZFAT_ADC_TST_PATTERN:
/*fallthrough*/
case ZFA_SW_R_NOADDRES_NBIT: case ZFA_SW_R_NOADDRES_NBIT:
/*fallthrough*/ /*fallthrough*/
case ZFA_SW_R_NOADDERS_AUTO: case ZFA_SW_R_NOADDERS_AUTO:
...@@ -571,10 +550,6 @@ static int zfad_zio_probe(struct zio_device *zdev) ...@@ -571,10 +550,6 @@ static int zfad_zio_probe(struct zio_device *zdev)
/* Save also the pointer to the real zio_device */ /* Save also the pointer to the real zio_device */
fa->zdev = zdev; fa->zdev = zdev;
err = zfad_pattern_data_enable(fa, 0, fa_enable_test_data_adc);
if (err)
return err;
err = device_create_bin_file(&zdev->head.dev, &dev_attr_calibration); err = device_create_bin_file(&zdev->head.dev, &dev_attr_calibration);
if (err) if (err)
return err; return err;
......
...@@ -177,8 +177,6 @@ struct fa_calib { ...@@ -177,8 +177,6 @@ struct fa_calib {
#define DAC_SAT_LOW -5000000 #define DAC_SAT_LOW -5000000
#define DAC_SAT_UP 5000000 #define DAC_SAT_UP 5000000
extern int fa_enable_test_data_adc;
#define ADC_DMA 0 #define ADC_DMA 0
enum fa_irq_resource { enum fa_irq_resource {
...@@ -247,8 +245,6 @@ enum zfadc_dregs_enum { ...@@ -247,8 +245,6 @@ enum zfadc_dregs_enum {
ZFAT_POST, ZFAT_POST,
/* Sample counter */ /* Sample counter */
ZFAT_CNT, ZFAT_CNT,
/* Pattern data for the ADC chip */
ZFAT_ADC_TST_PATTERN,
/* start:declaration block requiring some order */ /* start:declaration block requiring some order */
/* Channel 1 */ /* Channel 1 */
ZFA_CH1_CTL_RANGE, ZFA_CH1_CTL_RANGE,
...@@ -385,6 +381,11 @@ enum fa_irq_adc { ...@@ -385,6 +381,11 @@ enum fa_irq_adc {
mezzanine-specific operations). */ mezzanine-specific operations). */
struct fa_dev; /* forward declaration */ struct fa_dev; /* forward declaration */
/*
* Flag bit set when the ADC uses pattern data
*/
#define FA_DEV_F_PATTERN_DATA BIT(0)
/* /*
* fa_dev: is the descriptor of the FMC ADC mezzanine * fa_dev: is the descriptor of the FMC ADC mezzanine
* *
...@@ -401,6 +402,7 @@ struct fa_dev; /* forward declaration */ ...@@ -401,6 +402,7 @@ struct fa_dev; /* forward declaration */
* @zero_offset: necessary offset to push the channel to zero (micro-Volts) * @zero_offset: necessary offset to push the channel to zero (micro-Volts)
*/ */
struct fa_dev { struct fa_dev {
unsigned long flags;
struct device *msgdev; /**< device used to print messages */ struct device *msgdev; /**< device used to print messages */
/* the pointer to the platform_device generic structure */ /* the pointer to the platform_device generic structure */
struct platform_device *pdev; struct platform_device *pdev;
...@@ -462,6 +464,7 @@ struct fa_dev { ...@@ -462,6 +464,7 @@ struct fa_dev {
struct dentry *dbg_reg; struct dentry *dbg_reg;
struct dentry *dbg_reg_spi; struct dentry *dbg_reg_spi;
struct dentry *dbg_trg_sw; struct dentry *dbg_trg_sw;
struct dentry *dbg_data_pattern;
/* Operations */ /* Operations */
int (*sg_alloc_table_from_pages)(struct sg_table *sgt, int (*sg_alloc_table_from_pages)(struct sg_table *sgt,
...@@ -610,14 +613,14 @@ extern int fa_trigger_software(struct fa_dev *fa); ...@@ -610,14 +613,14 @@ extern int fa_trigger_software(struct fa_dev *fa);
extern int fa_fsm_wait_state(struct fa_dev *fa, extern int fa_fsm_wait_state(struct fa_dev *fa,
enum fa100m14b4c_fsm_state state, enum fa100m14b4c_fsm_state state,
unsigned int timeout_us); unsigned int timeout_us);
extern int fa_adc_data_pattern_set(struct fa_dev *fa, uint16_t pattern,
unsigned int enable);
/* Temporarily, user values are the same as hardware values */ /* Temporarily, user values are the same as hardware values */
extern int zfad_convert_user_range(uint32_t user_val); extern int zfad_convert_user_range(uint32_t user_val);
extern int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan, extern int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan,
int range); int range);
extern int zfad_get_chx_index(unsigned long addr, unsigned int chan); extern int zfad_get_chx_index(unsigned long addr, unsigned int chan);
extern int zfad_pattern_data_enable(struct fa_dev *fa, uint16_t pattern,
unsigned int enable);
/* Function exported by fa-dma.c */ /* Function exported by fa-dma.c */
extern void fa_irq_work(struct work_struct *work); extern void fa_irq_work(struct work_struct *work);
......
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