|
|
|
@@ -141,9 +141,13 @@ struct vf610_adc {
|
|
|
|
|
struct regulator *vref;
|
|
|
|
|
struct vf610_adc_feature adc_feature;
|
|
|
|
|
|
|
|
|
|
u32 sample_freq_avail[5];
|
|
|
|
|
|
|
|
|
|
struct completion completion;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
|
|
|
|
|
|
|
|
|
|
#define VF610_ADC_CHAN(_idx, _chan_type) { \
|
|
|
|
|
.type = (_chan_type), \
|
|
|
|
|
.indexed = 1, \
|
|
|
|
@@ -180,35 +184,47 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
|
|
|
|
|
/* sentinel */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ADC sample frequency, unit is ADCK cycles.
|
|
|
|
|
* ADC clk source is ipg clock, which is the same as bus clock.
|
|
|
|
|
*
|
|
|
|
|
* ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
|
|
|
|
|
* SFCAdder: fixed to 6 ADCK cycles
|
|
|
|
|
* AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
|
|
|
|
|
* BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
|
|
|
|
|
* LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
|
|
|
|
|
*
|
|
|
|
|
* By default, enable 12 bit resolution mode, clock source
|
|
|
|
|
* set to ipg clock, So get below frequency group:
|
|
|
|
|
*/
|
|
|
|
|
static const u32 vf610_sample_freq_avail[5] =
|
|
|
|
|
{1941176, 559332, 286957, 145374, 73171};
|
|
|
|
|
static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
|
|
|
|
|
{
|
|
|
|
|
unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Calculate ADC sample frequencies
|
|
|
|
|
* Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
|
|
|
|
|
* which is the same as bus clock.
|
|
|
|
|
*
|
|
|
|
|
* ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
|
|
|
|
|
* SFCAdder: fixed to 6 ADCK cycles
|
|
|
|
|
* AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
|
|
|
|
|
* BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
|
|
|
|
|
* LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
|
|
|
|
|
*/
|
|
|
|
|
adck_rate = ipg_rate / info->adc_feature.clk_div;
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)
|
|
|
|
|
info->sample_freq_avail[i] =
|
|
|
|
|
adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void vf610_adc_cfg_init(struct vf610_adc *info)
|
|
|
|
|
{
|
|
|
|
|
struct vf610_adc_feature *adc_feature = &info->adc_feature;
|
|
|
|
|
|
|
|
|
|
/* set default Configuration for ADC controller */
|
|
|
|
|
info->adc_feature.clk_sel = VF610_ADCIOC_BUSCLK_SET;
|
|
|
|
|
info->adc_feature.vol_ref = VF610_ADCIOC_VR_VREF_SET;
|
|
|
|
|
adc_feature->clk_sel = VF610_ADCIOC_BUSCLK_SET;
|
|
|
|
|
adc_feature->vol_ref = VF610_ADCIOC_VR_VREF_SET;
|
|
|
|
|
|
|
|
|
|
info->adc_feature.calibration = true;
|
|
|
|
|
info->adc_feature.ovwren = true;
|
|
|
|
|
adc_feature->calibration = true;
|
|
|
|
|
adc_feature->ovwren = true;
|
|
|
|
|
|
|
|
|
|
info->adc_feature.clk_div = 1;
|
|
|
|
|
info->adc_feature.res_mode = 12;
|
|
|
|
|
info->adc_feature.sample_rate = 1;
|
|
|
|
|
info->adc_feature.lpm = true;
|
|
|
|
|
adc_feature->res_mode = 12;
|
|
|
|
|
adc_feature->sample_rate = 1;
|
|
|
|
|
adc_feature->lpm = true;
|
|
|
|
|
|
|
|
|
|
/* Use a save ADCK which is below 20MHz on all devices */
|
|
|
|
|
adc_feature->clk_div = 8;
|
|
|
|
|
|
|
|
|
|
vf610_adc_calculate_rates(info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void vf610_adc_cfg_post_set(struct vf610_adc *info)
|
|
|
|
@@ -287,12 +303,10 @@ static void vf610_adc_cfg_set(struct vf610_adc *info)
|
|
|
|
|
|
|
|
|
|
cfg_data = readl(info->regs + VF610_REG_ADC_CFG);
|
|
|
|
|
|
|
|
|
|
/* low power configuration */
|
|
|
|
|
cfg_data &= ~VF610_ADC_ADLPC_EN;
|
|
|
|
|
if (adc_feature->lpm)
|
|
|
|
|
cfg_data |= VF610_ADC_ADLPC_EN;
|
|
|
|
|
|
|
|
|
|
/* disable high speed */
|
|
|
|
|
cfg_data &= ~VF610_ADC_ADHSC_EN;
|
|
|
|
|
|
|
|
|
|
writel(cfg_data, info->regs + VF610_REG_ADC_CFG);
|
|
|
|
@@ -432,10 +446,27 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1941176, 559332, 286957, 145374, 73171");
|
|
|
|
|
static ssize_t vf610_show_samp_freq_avail(struct device *dev,
|
|
|
|
|
struct device_attribute *attr, char *buf)
|
|
|
|
|
{
|
|
|
|
|
struct vf610_adc *info = iio_priv(dev_to_iio_dev(dev));
|
|
|
|
|
size_t len = 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(info->sample_freq_avail); i++)
|
|
|
|
|
len += scnprintf(buf + len, PAGE_SIZE - len,
|
|
|
|
|
"%u ", info->sample_freq_avail[i]);
|
|
|
|
|
|
|
|
|
|
/* replace trailing space by newline */
|
|
|
|
|
buf[len - 1] = '\n';
|
|
|
|
|
|
|
|
|
|
return len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(vf610_show_samp_freq_avail);
|
|
|
|
|
|
|
|
|
|
static struct attribute *vf610_attributes[] = {
|
|
|
|
|
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
|
|
|
|
|
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -499,7 +530,7 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
|
|
|
|
|
return IIO_VAL_FRACTIONAL_LOG2;
|
|
|
|
|
|
|
|
|
|
case IIO_CHAN_INFO_SAMP_FREQ:
|
|
|
|
|
*val = vf610_sample_freq_avail[info->adc_feature.sample_rate];
|
|
|
|
|
*val = info->sample_freq_avail[info->adc_feature.sample_rate];
|
|
|
|
|
*val2 = 0;
|
|
|
|
|
return IIO_VAL_INT;
|
|
|
|
|
|
|
|
|
@@ -522,9 +553,9 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
|
|
|
|
|
switch (mask) {
|
|
|
|
|
case IIO_CHAN_INFO_SAMP_FREQ:
|
|
|
|
|
for (i = 0;
|
|
|
|
|
i < ARRAY_SIZE(vf610_sample_freq_avail);
|
|
|
|
|
i < ARRAY_SIZE(info->sample_freq_avail);
|
|
|
|
|
i++)
|
|
|
|
|
if (val == vf610_sample_freq_avail[i]) {
|
|
|
|
|
if (val == info->sample_freq_avail[i]) {
|
|
|
|
|
info->adc_feature.sample_rate = i;
|
|
|
|
|
vf610_adc_sample_set(info);
|
|
|
|
|
return 0;
|
|
|
|
|