Skip to content

Commit 5e9972c

Browse files
SanchayanMaityjic23
authored andcommitted
iio: adc: vf610: Determine sampling frequencies by using minimum sample time
The driver currently does not take into account the minimum sample time as per the Figure 6-8 Chapter 9.1.1 12-bit ADC electrical characteristics. We set a static amount of cycles instead of considering the sample time as a given value, which depends on hardware characteristics. Determine sampling frequencies by first reading the device tree property node and then calculating the required Long Sample Time Adder (LSTAdder) value, based on the ADC clock frequency and sample time value obtained from the device tree. This LSTAdder value is then used for calculating the sampling frequencies possible. In case the sample time property is not specified through the device tree, a safe default value of 1000ns is assumed. Signed-off-by: Sanchayan Maity <[email protected]> Acked-by: Stefan Agner <[email protected]> Acked-by: Fugang Duan <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent f686a36 commit 5e9972c

File tree

2 files changed

+80
-4
lines changed

2 files changed

+80
-4
lines changed

Documentation/devicetree/bindings/iio/adc/vf610-adc.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ Recommended properties:
1717
- Frequency in normal mode (ADLPC=0, ADHSC=0)
1818
- Frequency in high-speed mode (ADLPC=0, ADHSC=1)
1919
- Frequency in low-power mode (ADLPC=1, ADHSC=0)
20+
- min-sample-time: Minimum sampling time in nanoseconds. This value has
21+
to be chosen according to the conversion mode and the connected analog
22+
source resistance (R_as) and capacitance (C_as). Refer the datasheet's
23+
operating requirements. A safe default across a wide range of R_as and
24+
C_as as well as conversion modes is 1000ns.
2025

2126
Example:
2227
adc0: adc@4003b000 {

drivers/iio/adc/vf610_adc.c

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868
#define VF610_ADC_CLK_DIV8 0x60
6969
#define VF610_ADC_CLK_MASK 0x60
7070
#define VF610_ADC_ADLSMP_LONG 0x10
71+
#define VF610_ADC_ADSTS_SHORT 0x100
72+
#define VF610_ADC_ADSTS_NORMAL 0x200
73+
#define VF610_ADC_ADSTS_LONG 0x300
7174
#define VF610_ADC_ADSTS_MASK 0x300
7275
#define VF610_ADC_ADLPC_EN 0x80
7376
#define VF610_ADC_ADHSC_EN 0x400
@@ -98,6 +101,8 @@
98101
#define VF610_ADC_CALF 0x2
99102
#define VF610_ADC_TIMEOUT msecs_to_jiffies(100)
100103

104+
#define DEFAULT_SAMPLE_TIME 1000
105+
101106
enum clk_sel {
102107
VF610_ADCIOC_BUSCLK_SET,
103108
VF610_ADCIOC_ALTCLK_SET,
@@ -124,6 +129,17 @@ enum conversion_mode_sel {
124129
VF610_ADC_CONV_LOW_POWER,
125130
};
126131

132+
enum lst_adder_sel {
133+
VF610_ADCK_CYCLES_3,
134+
VF610_ADCK_CYCLES_5,
135+
VF610_ADCK_CYCLES_7,
136+
VF610_ADCK_CYCLES_9,
137+
VF610_ADCK_CYCLES_13,
138+
VF610_ADCK_CYCLES_17,
139+
VF610_ADCK_CYCLES_21,
140+
VF610_ADCK_CYCLES_25,
141+
};
142+
127143
struct vf610_adc_feature {
128144
enum clk_sel clk_sel;
129145
enum vol_ref vol_ref;
@@ -132,6 +148,8 @@ struct vf610_adc_feature {
132148
int clk_div;
133149
int sample_rate;
134150
int res_mode;
151+
u32 lst_adder_index;
152+
u32 default_sample_time;
135153

136154
bool calibration;
137155
bool ovwren;
@@ -155,11 +173,13 @@ struct vf610_adc {
155173
};
156174

157175
static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
176+
static const u32 vf610_lst_adder[] = { 3, 5, 7, 9, 13, 17, 21, 25 };
158177

159178
static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
160179
{
161180
struct vf610_adc_feature *adc_feature = &info->adc_feature;
162181
unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);
182+
u32 adck_period, lst_addr_min;
163183
int divisor, i;
164184

165185
adck_rate = info->max_adck_rate[adc_feature->conv_mode];
@@ -173,6 +193,19 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
173193
adc_feature->clk_div = 8;
174194
}
175195

196+
/*
197+
* Determine the long sample time adder value to be used based
198+
* on the default minimum sample time provided.
199+
*/
200+
adck_period = NSEC_PER_SEC / adck_rate;
201+
lst_addr_min = adc_feature->default_sample_time / adck_period;
202+
for (i = 0; i < ARRAY_SIZE(vf610_lst_adder); i++) {
203+
if (vf610_lst_adder[i] > lst_addr_min) {
204+
adc_feature->lst_adder_index = i;
205+
break;
206+
}
207+
}
208+
176209
/*
177210
* Calculate ADC sample frequencies
178211
* Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
@@ -182,12 +215,13 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
182215
* SFCAdder: fixed to 6 ADCK cycles
183216
* AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
184217
* BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
185-
* LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
218+
* LSTAdder(Long Sample Time): 3, 5, 7, 9, 13, 17, 21, 25 ADCK cycles
186219
*/
187220
adck_rate = ipg_rate / info->adc_feature.clk_div;
188221
for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)
189222
info->sample_freq_avail[i] =
190-
adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3));
223+
adck_rate / (6 + vf610_hw_avgs[i] *
224+
(25 + vf610_lst_adder[adc_feature->lst_adder_index]));
191225
}
192226

193227
static inline void vf610_adc_cfg_init(struct vf610_adc *info)
@@ -347,8 +381,40 @@ static void vf610_adc_sample_set(struct vf610_adc *info)
347381
break;
348382
}
349383

350-
/* Use the short sample mode */
351-
cfg_data &= ~(VF610_ADC_ADLSMP_LONG | VF610_ADC_ADSTS_MASK);
384+
/*
385+
* Set ADLSMP and ADSTS based on the Long Sample Time Adder value
386+
* determined.
387+
*/
388+
switch (adc_feature->lst_adder_index) {
389+
case VF610_ADCK_CYCLES_3:
390+
break;
391+
case VF610_ADCK_CYCLES_5:
392+
cfg_data |= VF610_ADC_ADSTS_SHORT;
393+
break;
394+
case VF610_ADCK_CYCLES_7:
395+
cfg_data |= VF610_ADC_ADSTS_NORMAL;
396+
break;
397+
case VF610_ADCK_CYCLES_9:
398+
cfg_data |= VF610_ADC_ADSTS_LONG;
399+
break;
400+
case VF610_ADCK_CYCLES_13:
401+
cfg_data |= VF610_ADC_ADLSMP_LONG;
402+
break;
403+
case VF610_ADCK_CYCLES_17:
404+
cfg_data |= VF610_ADC_ADLSMP_LONG;
405+
cfg_data |= VF610_ADC_ADSTS_SHORT;
406+
break;
407+
case VF610_ADCK_CYCLES_21:
408+
cfg_data |= VF610_ADC_ADLSMP_LONG;
409+
cfg_data |= VF610_ADC_ADSTS_NORMAL;
410+
break;
411+
case VF610_ADCK_CYCLES_25:
412+
cfg_data |= VF610_ADC_ADLSMP_LONG;
413+
cfg_data |= VF610_ADC_ADSTS_NORMAL;
414+
break;
415+
default:
416+
dev_err(info->dev, "error in sample time select\n");
417+
}
352418

353419
/* update hardware average selection */
354420
cfg_data &= ~VF610_ADC_AVGS_MASK;
@@ -713,6 +779,11 @@ static int vf610_adc_probe(struct platform_device *pdev)
713779
of_property_read_u32_array(pdev->dev.of_node, "fsl,adck-max-frequency",
714780
info->max_adck_rate, 3);
715781

782+
ret = of_property_read_u32(pdev->dev.of_node, "min-sample-time",
783+
&info->adc_feature.default_sample_time);
784+
if (ret)
785+
info->adc_feature.default_sample_time = DEFAULT_SAMPLE_TIME;
786+
716787
platform_set_drvdata(pdev, indio_dev);
717788

718789
init_completion(&info->completion);

0 commit comments

Comments
 (0)