aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/adc/vf610_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/adc/vf610_adc.c')
-rw-r--r--drivers/iio/adc/vf610_adc.c91
1 files changed, 61 insertions, 30 deletions
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index 8ec353c01d98..e63b8e76d4c3 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -141,9 +141,13 @@ struct vf610_adc {
141 struct regulator *vref; 141 struct regulator *vref;
142 struct vf610_adc_feature adc_feature; 142 struct vf610_adc_feature adc_feature;
143 143
144 u32 sample_freq_avail[5];
145
144 struct completion completion; 146 struct completion completion;
145}; 147};
146 148
149static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
150
147#define VF610_ADC_CHAN(_idx, _chan_type) { \ 151#define VF610_ADC_CHAN(_idx, _chan_type) { \
148 .type = (_chan_type), \ 152 .type = (_chan_type), \
149 .indexed = 1, \ 153 .indexed = 1, \
@@ -180,35 +184,47 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
180 /* sentinel */ 184 /* sentinel */
181}; 185};
182 186
183/* 187static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
184 * ADC sample frequency, unit is ADCK cycles. 188{
185 * ADC clk source is ipg clock, which is the same as bus clock. 189 unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);
186 * 190 int i;
187 * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder) 191
188 * SFCAdder: fixed to 6 ADCK cycles 192 /*
189 * AverageNum: 1, 4, 8, 16, 32 samples for hardware average. 193 * Calculate ADC sample frequencies
190 * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode 194 * Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
191 * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles 195 * which is the same as bus clock.
192 * 196 *
193 * By default, enable 12 bit resolution mode, clock source 197 * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
194 * set to ipg clock, So get below frequency group: 198 * SFCAdder: fixed to 6 ADCK cycles
195 */ 199 * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
196static const u32 vf610_sample_freq_avail[5] = 200 * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
197{1941176, 559332, 286957, 145374, 73171}; 201 * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
202 */
203 adck_rate = ipg_rate / info->adc_feature.clk_div;
204 for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)
205 info->sample_freq_avail[i] =
206 adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3));
207}
198 208
199static inline void vf610_adc_cfg_init(struct vf610_adc *info) 209static inline void vf610_adc_cfg_init(struct vf610_adc *info)
200{ 210{
211 struct vf610_adc_feature *adc_feature = &info->adc_feature;
212
201 /* set default Configuration for ADC controller */ 213 /* set default Configuration for ADC controller */
202 info->adc_feature.clk_sel = VF610_ADCIOC_BUSCLK_SET; 214 adc_feature->clk_sel = VF610_ADCIOC_BUSCLK_SET;
203 info->adc_feature.vol_ref = VF610_ADCIOC_VR_VREF_SET; 215 adc_feature->vol_ref = VF610_ADCIOC_VR_VREF_SET;
216
217 adc_feature->calibration = true;
218 adc_feature->ovwren = true;
219
220 adc_feature->res_mode = 12;
221 adc_feature->sample_rate = 1;
222 adc_feature->lpm = true;
204 223
205 info->adc_feature.calibration = true; 224 /* Use a save ADCK which is below 20MHz on all devices */
206 info->adc_feature.ovwren = true; 225 adc_feature->clk_div = 8;
207 226
208 info->adc_feature.clk_div = 1; 227 vf610_adc_calculate_rates(info);
209 info->adc_feature.res_mode = 12;
210 info->adc_feature.sample_rate = 1;
211 info->adc_feature.lpm = true;
212} 228}
213 229
214static void vf610_adc_cfg_post_set(struct vf610_adc *info) 230static void vf610_adc_cfg_post_set(struct vf610_adc *info)
@@ -290,12 +306,10 @@ static void vf610_adc_cfg_set(struct vf610_adc *info)
290 306
291 cfg_data = readl(info->regs + VF610_REG_ADC_CFG); 307 cfg_data = readl(info->regs + VF610_REG_ADC_CFG);
292 308
293 /* low power configuration */
294 cfg_data &= ~VF610_ADC_ADLPC_EN; 309 cfg_data &= ~VF610_ADC_ADLPC_EN;
295 if (adc_feature->lpm) 310 if (adc_feature->lpm)
296 cfg_data |= VF610_ADC_ADLPC_EN; 311 cfg_data |= VF610_ADC_ADLPC_EN;
297 312
298 /* disable high speed */
299 cfg_data &= ~VF610_ADC_ADHSC_EN; 313 cfg_data &= ~VF610_ADC_ADHSC_EN;
300 314
301 writel(cfg_data, info->regs + VF610_REG_ADC_CFG); 315 writel(cfg_data, info->regs + VF610_REG_ADC_CFG);
@@ -435,10 +449,27 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
435 return IRQ_HANDLED; 449 return IRQ_HANDLED;
436} 450}
437 451
438static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1941176, 559332, 286957, 145374, 73171"); 452static ssize_t vf610_show_samp_freq_avail(struct device *dev,
453 struct device_attribute *attr, char *buf)
454{
455 struct vf610_adc *info = iio_priv(dev_to_iio_dev(dev));
456 size_t len = 0;
457 int i;
458
459 for (i = 0; i < ARRAY_SIZE(info->sample_freq_avail); i++)
460 len += scnprintf(buf + len, PAGE_SIZE - len,
461 "%u ", info->sample_freq_avail[i]);
462
463 /* replace trailing space by newline */
464 buf[len - 1] = '\n';
465
466 return len;
467}
468
469static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(vf610_show_samp_freq_avail);
439 470
440static struct attribute *vf610_attributes[] = { 471static struct attribute *vf610_attributes[] = {
441 &iio_const_attr_sampling_frequency_available.dev_attr.attr, 472 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
442 NULL 473 NULL
443}; 474};
444 475
@@ -502,7 +533,7 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
502 return IIO_VAL_FRACTIONAL_LOG2; 533 return IIO_VAL_FRACTIONAL_LOG2;
503 534
504 case IIO_CHAN_INFO_SAMP_FREQ: 535 case IIO_CHAN_INFO_SAMP_FREQ:
505 *val = vf610_sample_freq_avail[info->adc_feature.sample_rate]; 536 *val = info->sample_freq_avail[info->adc_feature.sample_rate];
506 *val2 = 0; 537 *val2 = 0;
507 return IIO_VAL_INT; 538 return IIO_VAL_INT;
508 539
@@ -525,9 +556,9 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
525 switch (mask) { 556 switch (mask) {
526 case IIO_CHAN_INFO_SAMP_FREQ: 557 case IIO_CHAN_INFO_SAMP_FREQ:
527 for (i = 0; 558 for (i = 0;
528 i < ARRAY_SIZE(vf610_sample_freq_avail); 559 i < ARRAY_SIZE(info->sample_freq_avail);
529 i++) 560 i++)
530 if (val == vf610_sample_freq_avail[i]) { 561 if (val == info->sample_freq_avail[i]) {
531 info->adc_feature.sample_rate = i; 562 info->adc_feature.sample_rate = i;
532 vf610_adc_sample_set(info); 563 vf610_adc_sample_set(info);
533 return 0; 564 return 0;