@@ -141,9 +141,13 @@ struct vf610_adc {
141141 struct regulator * vref ;
142142 struct vf610_adc_feature adc_feature ;
143143
144+ u32 sample_freq_avail [5 ];
145+
144146 struct completion completion ;
145147};
146148
149+ static const u32 vf610_hw_avgs [] = { 1 , 4 , 8 , 16 , 32 };
150+
147151#define VF610_ADC_CHAN (_idx , _chan_type ) { \
148152 .type = (_chan_type), \
149153 .indexed = 1, \
@@ -180,35 +184,47 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
180184 /* sentinel */
181185};
182186
183- /*
184- * ADC sample frequency, unit is ADCK cycles.
185- * ADC clk source is ipg clock, which is the same as bus clock.
186- *
187- * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
188- * SFCAdder: fixed to 6 ADCK cycles
189- * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
190- * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
191- * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
192- *
193- * By default, enable 12 bit resolution mode, clock source
194- * set to ipg clock, So get below frequency group:
195- */
196- static const u32 vf610_sample_freq_avail [5 ] =
197- {1941176 , 559332 , 286957 , 145374 , 73171 };
187+ static inline void vf610_adc_calculate_rates (struct vf610_adc * info )
188+ {
189+ unsigned long adck_rate , ipg_rate = clk_get_rate (info -> clk );
190+ int i ;
191+
192+ /*
193+ * Calculate ADC sample frequencies
194+ * Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
195+ * which is the same as bus clock.
196+ *
197+ * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
198+ * SFCAdder: fixed to 6 ADCK cycles
199+ * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
200+ * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
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+ }
198208
199209static inline void vf610_adc_cfg_init (struct vf610_adc * info )
200210{
211+ struct vf610_adc_feature * adc_feature = & info -> adc_feature ;
212+
201213 /* set default Configuration for ADC controller */
202- info -> adc_feature .clk_sel = VF610_ADCIOC_BUSCLK_SET ;
203- info -> adc_feature .vol_ref = VF610_ADCIOC_VR_VREF_SET ;
214+ adc_feature -> clk_sel = VF610_ADCIOC_BUSCLK_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;
204223
205- info -> adc_feature . calibration = true;
206- info -> adc_feature . ovwren = true ;
224+ /* Use a save ADCK which is below 20MHz on all devices */
225+ adc_feature -> clk_div = 8 ;
207226
208- info -> adc_feature .clk_div = 1 ;
209- info -> adc_feature .res_mode = 12 ;
210- info -> adc_feature .sample_rate = 1 ;
211- info -> adc_feature .lpm = true;
227+ vf610_adc_calculate_rates (info );
212228}
213229
214230static void vf610_adc_cfg_post_set (struct vf610_adc * info )
@@ -290,12 +306,10 @@ static void vf610_adc_cfg_set(struct vf610_adc *info)
290306
291307 cfg_data = readl (info -> regs + VF610_REG_ADC_CFG );
292308
293- /* low power configuration */
294309 cfg_data &= ~VF610_ADC_ADLPC_EN ;
295310 if (adc_feature -> lpm )
296311 cfg_data |= VF610_ADC_ADLPC_EN ;
297312
298- /* disable high speed */
299313 cfg_data &= ~VF610_ADC_ADHSC_EN ;
300314
301315 writel (cfg_data , info -> regs + VF610_REG_ADC_CFG );
@@ -435,10 +449,27 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
435449 return IRQ_HANDLED ;
436450}
437451
438- static IIO_CONST_ATTR_SAMP_FREQ_AVAIL ("1941176, 559332, 286957, 145374, 73171" );
452+ static 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+
469+ static IIO_DEV_ATTR_SAMP_FREQ_AVAIL (vf610_show_samp_freq_avail );
439470
440471static struct attribute * vf610_attributes [] = {
441- & iio_const_attr_sampling_frequency_available .dev_attr .attr ,
472+ & iio_dev_attr_sampling_frequency_available .dev_attr .attr ,
442473 NULL
443474};
444475
@@ -502,7 +533,7 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
502533 return IIO_VAL_FRACTIONAL_LOG2 ;
503534
504535 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 ];
506537 * val2 = 0 ;
507538 return IIO_VAL_INT ;
508539
@@ -525,9 +556,9 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
525556 switch (mask ) {
526557 case IIO_CHAN_INFO_SAMP_FREQ :
527558 for (i = 0 ;
528- i < ARRAY_SIZE (vf610_sample_freq_avail );
559+ i < ARRAY_SIZE (info -> sample_freq_avail );
529560 i ++ )
530- if (val == vf610_sample_freq_avail [i ]) {
561+ if (val == info -> sample_freq_avail [i ]) {
531562 info -> adc_feature .sample_rate = i ;
532563 vf610_adc_sample_set (info );
533564 return 0 ;
0 commit comments