21 #define AR9285_CLCAL_REDO_THRESH 1
29 static bool ar9002_hw_is_cal_supported(
struct ath_hw *
ah,
33 bool supported =
false;
52 static void ar9002_hw_setup_calibration(
struct ath_hw *
ah,
61 switch (currCal->
calData->calType) {
65 "starting IQ Mismatch Calibration\n");
69 ath_dbg(common, CALIBRATE,
"starting ADC Gain Calibration\n");
73 ath_dbg(common, CALIBRATE,
"starting ADC DC Calibration\n");
81 static bool ar9002_hw_per_calibration(
struct ath_hw *ah,
87 bool iscaldone =
false;
93 currCal->
calData->calCollect(ah);
97 currCal->
calData->calNumSamples) {
100 if (rxchainmask & (1 << i))
104 currCal->
calData->calPostProc(ah, numChains);
109 ar9002_hw_setup_calibration(ah, currCal);
119 static void ar9002_hw_iqcal_collect(
struct ath_hw *ah)
124 ah->totalPowerMeasI[
i] +=
126 ah->totalPowerMeasQ[
i] +=
128 ah->totalIqCorrMeas[
i] +=
130 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
131 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
133 ah->totalPowerMeasQ[i],
134 ah->totalIqCorrMeas[i]);
138 static void ar9002_hw_adc_gaincal_collect(
struct ath_hw *ah)
143 ah->totalAdcIOddPhase[
i] +=
145 ah->totalAdcIEvenPhase[
i] +=
147 ah->totalAdcQOddPhase[
i] +=
149 ah->totalAdcQEvenPhase[
i] +=
152 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
153 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
155 ah->totalAdcIOddPhase[i],
156 ah->totalAdcIEvenPhase[i],
157 ah->totalAdcQOddPhase[i],
158 ah->totalAdcQEvenPhase[i]);
162 static void ar9002_hw_adc_dccal_collect(
struct ath_hw *ah)
167 ah->totalAdcDcOffsetIOddPhase[
i] +=
169 ah->totalAdcDcOffsetIEvenPhase[
i] +=
171 ah->totalAdcDcOffsetQOddPhase[
i] +=
173 ah->totalAdcDcOffsetQEvenPhase[
i] +=
176 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
177 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
179 ah->totalAdcDcOffsetIOddPhase[i],
180 ah->totalAdcDcOffsetIEvenPhase[i],
181 ah->totalAdcDcOffsetQOddPhase[i],
182 ah->totalAdcDcOffsetQEvenPhase[i]);
186 static void ar9002_hw_iqcalibrate(
struct ath_hw *ah,
u8 numChains)
188 struct ath_common *common = ath9k_hw_common(ah);
189 u32 powerMeasQ, powerMeasI, iqCorrMeas;
190 u32 qCoffDenom, iCoffDenom;
194 for (i = 0; i < numChains; i++) {
195 powerMeasI = ah->totalPowerMeasI[
i];
196 powerMeasQ = ah->totalPowerMeasQ[
i];
197 iqCorrMeas = ah->totalIqCorrMeas[
i];
200 "Starting IQ Cal and Correction for Chain %d\n",
204 "Original: Chn %d iq_corr_meas = 0x%08x\n",
205 i, ah->totalIqCorrMeas[i]);
209 if (iqCorrMeas > 0x80000000) {
210 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
214 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_i = 0x%08x\n",
216 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_q = 0x%08x\n",
218 ath_dbg(common, CALIBRATE,
"iqCorrNeg is 0x%08x\n", iqCorrNeg);
220 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
221 qCoffDenom = powerMeasQ / 64;
223 if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
225 iCoff = iqCorrMeas / iCoffDenom;
226 qCoff = powerMeasI / qCoffDenom - 64;
227 ath_dbg(common, CALIBRATE,
"Chn %d iCoff = 0x%08x\n",
229 ath_dbg(common, CALIBRATE,
"Chn %d qCoff = 0x%08x\n",
232 iCoff = iCoff & 0x3f;
234 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
235 if (iqCorrNeg == 0x0)
236 iCoff = 0x40 - iCoff;
240 else if (qCoff <= -16)
244 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
254 "IQ Cal and Correction done for Chain %d\n",
263 static void ar9002_hw_adc_gaincal_calibrate(
struct ath_hw *ah,
u8 numChains)
265 struct ath_common *common = ath9k_hw_common(ah);
266 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
267 u32 qGainMismatch, iGainMismatch,
val,
i;
269 for (i = 0; i < numChains; i++) {
270 iOddMeasOffset = ah->totalAdcIOddPhase[
i];
271 iEvenMeasOffset = ah->totalAdcIEvenPhase[
i];
272 qOddMeasOffset = ah->totalAdcQOddPhase[
i];
273 qEvenMeasOffset = ah->totalAdcQEvenPhase[
i];
276 "Starting ADC Gain Cal for Chain %d\n", i);
278 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_odd_i = 0x%08x\n",
280 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_even_i = 0x%08x\n",
282 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_odd_q = 0x%08x\n",
284 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_even_q = 0x%08x\n",
287 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
289 ((iEvenMeasOffset * 32) /
290 iOddMeasOffset) & 0x3f;
292 ((qOddMeasOffset * 32) /
293 qEvenMeasOffset) & 0x3f;
296 "Chn %d gain_mismatch_i = 0x%08x\n",
299 "Chn %d gain_mismatch_q = 0x%08x\n",
304 val |= (qGainMismatch) | (iGainMismatch << 6);
308 "ADC Gain Cal done for Chain %d\n", i);
317 static void ar9002_hw_adc_dccal_calibrate(
struct ath_hw *ah,
u8 numChains)
319 struct ath_common *common = ath9k_hw_common(ah);
320 u32 iOddMeasOffset, iEvenMeasOffset,
val,
i;
321 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
327 for (i = 0; i < numChains; i++) {
328 iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[
i];
329 iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[
i];
330 qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[
i];
331 qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[
i];
334 "Starting ADC DC Offset Cal for Chain %d\n", i);
336 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_odd_i = %d\n",
338 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_even_i = %d\n",
340 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_odd_q = %d\n",
342 ath_dbg(common, CALIBRATE,
"Chn %d pwr_meas_even_q = %d\n",
345 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
347 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
351 "Chn %d dc_offset_mismatch_i = 0x%08x\n",
354 "Chn %d dc_offset_mismatch_q = 0x%08x\n",
359 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
363 "ADC DC Offset Cal done for Chain %d\n", i);
371 static void ar9287_hw_olc_temp_compensation(
struct ath_hw *ah)
379 if (ah->
initPDADC == 0 || currPDADC == 0) {
392 delta = ((currPDADC - ah->
initPDADC)*4) / slope;
401 static void ar9280_hw_olc_temp_compensation(
struct ath_hw *ah)
409 if (ah->
initPDADC == 0 || currPDADC == 0)
413 delta = (currPDADC - ah->
initPDADC + 4) / 8;
415 delta = (currPDADC - ah->
initPDADC + 5) / 10;
431 static void ar9271_hw_pa_cal(
struct ath_hw *ah,
bool is_reset)
447 regList[i][1] =
REG_READ(ah, regList[i][0]);
453 regVal |= (0x1 << 27);
495 for (i = 6; i > 0; i--) {
497 regVal |= (1 << (20 +
i));
501 regVal &= (~(0x1 << (20 +
i)));
507 regVal = (regVal >> 20) & 0x7f;
510 if ((!is_reset) && (ah->
pacal_info.prev_offset == regVal)) {
527 regVal &= (~(0x1 << 27));
531 REG_WRITE(ah, regList[i][0], regList[i][1]);
536 static inline void ar9285_hw_pa_cal(
struct ath_hw *ah,
bool is_reset)
538 struct ath_common *common = ath9k_hw_common(ah);
540 int i,
offset, offs_6_1, offs_0;
552 ath_dbg(common, CALIBRATE,
"Running PA Calibration\n");
560 regList[i][1] =
REG_READ(ah, regList[i][0]);
566 regVal |= (0x1 << 27);
589 for (i = 6; i > 0; i--) {
591 regVal |= (1 << (19 +
i));
595 regVal &= (~(0x1 << (19 +
i)));
597 regVal |= (reg_field << (19 +
i));
608 offset = (offs_6_1<<1) | offs_0;
610 offs_6_1 = offset>>1;
631 regVal &= (~(0x1 << 27));
635 REG_WRITE(ah, regList[i][0], regList[i][1]);
640 static void ar9002_hw_pa_cal(
struct ath_hw *ah,
bool is_reset)
644 ar9271_hw_pa_cal(ah, is_reset);
649 ar9285_hw_pa_cal(ah, is_reset);
655 static void ar9002_hw_olc_temp_compensation(
struct ath_hw *ah)
658 ar9287_hw_olc_temp_compensation(ah);
660 ar9280_hw_olc_temp_compensation(ah);
663 static bool ar9002_hw_calibrate(
struct ath_hw *ah,
668 bool iscaldone =
true;
670 bool nfcal, nfcal_pending =
false;
674 nfcal_pending = ah->
caldata->nfcal_pending;
676 if (currCal && !nfcal &&
679 iscaldone = ar9002_hw_per_calibration(ah, chan,
680 rxchainmask, currCal);
692 if (longcal || nfcal_pending) {
710 ar9002_hw_pa_cal(ah,
false);
711 ar9002_hw_olc_temp_compensation(ah);
721 struct ath_common *common = ath9k_hw_common(ah);
734 "offset calibration failed to complete in 1ms; noisy environment?\n");
748 "offset calibration failed to complete in 1ms; noisy environment?\n");
763 u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
771 if (!(ar9285_hw_cl_cal(ah, chan)))
777 for (i = 0; i < (txgain_max+1); i++) {
780 if (!(gain_mask & (1 << clc_gain))) {
781 gain_mask |= (1 << clc_gain);
786 for (i = 0; i < clc_num; i++) {
797 total_num = i0_num + q0_num;
809 retv = ar9285_hw_cl_cal(ah, chan);
817 struct ath_common *common = ath9k_hw_common(ah);
820 if (!ar9285_hw_cl_cal(ah, chan))
823 if (!ar9285_hw_clc(ah, chan))
844 "offset calibration failed to complete in 1ms; noisy environment?\n");
858 ar9002_hw_pa_cal(ah,
true);
861 ah->
caldata->nfcal_pending =
true;
875 if (ar9002_hw_is_cal_supported(ah, chan,
ADC_GAIN_CAL)) {
879 "enabling ADC Gain Calibration\n");
882 if (ar9002_hw_is_cal_supported(ah, chan,
ADC_DC_CAL)) {
886 "enabling ADC DC Calibration\n");
892 ath_dbg(common, CALIBRATE,
"enabling IQ Calibration\n");
911 ar9002_hw_iqcal_collect,
912 ar9002_hw_iqcalibrate
918 ar9002_hw_iqcal_collect,
919 ar9002_hw_iqcalibrate
925 ar9002_hw_adc_gaincal_collect,
926 ar9002_hw_adc_gaincal_calibrate
932 ar9002_hw_adc_gaincal_collect,
933 ar9002_hw_adc_gaincal_calibrate
939 ar9002_hw_adc_dccal_collect,
940 ar9002_hw_adc_dccal_calibrate
946 ar9002_hw_adc_dccal_collect,
947 ar9002_hw_adc_dccal_calibrate
950 static void ar9002_hw_init_cal_settings(
struct ath_hw *ah)
953 ah->
iq_caldata.calData = &iq_cal_multi_sample;
960 ah->
iq_caldata.calData = &iq_cal_single_sample;
962 &adc_gain_cal_single_sample;
964 &adc_dc_cal_single_sample;
966 ah->
iq_caldata.calData = &iq_cal_multi_sample;
968 &adc_gain_cal_multi_sample;
970 &adc_dc_cal_multi_sample;
985 priv_ops->
init_cal = ar9002_hw_init_cal;