0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "hw.h"
0018 #include "hw-ops.h"
0019 #include "ar9002_phy.h"
0020
0021 #define AR9285_CLCAL_REDO_THRESH 1
0022
0023 #define AR9002_CAL_MAX_TIME 30000
0024
0025 enum ar9002_cal_types {
0026 ADC_GAIN_CAL = BIT(0),
0027 ADC_DC_CAL = BIT(1),
0028 IQ_MISMATCH_CAL = BIT(2),
0029 };
0030
0031 static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
0032 struct ath9k_channel *chan,
0033 enum ar9002_cal_types cal_type)
0034 {
0035 bool supported = false;
0036 switch (ah->supp_cals & cal_type) {
0037 case IQ_MISMATCH_CAL:
0038 supported = true;
0039 break;
0040 case ADC_GAIN_CAL:
0041 case ADC_DC_CAL:
0042
0043 if (IS_CHAN_HT40(chan))
0044 supported = true;
0045 break;
0046 }
0047 return supported;
0048 }
0049
0050 static void ar9002_hw_setup_calibration(struct ath_hw *ah,
0051 struct ath9k_cal_list *currCal)
0052 {
0053 struct ath_common *common = ath9k_hw_common(ah);
0054
0055 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
0056 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
0057 currCal->calData->calCountMax);
0058
0059 switch (currCal->calData->calType) {
0060 case IQ_MISMATCH_CAL:
0061 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
0062 ath_dbg(common, CALIBRATE,
0063 "starting IQ Mismatch Calibration\n");
0064 break;
0065 case ADC_GAIN_CAL:
0066 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
0067 ath_dbg(common, CALIBRATE, "starting ADC Gain Calibration\n");
0068 break;
0069 case ADC_DC_CAL:
0070 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
0071 ath_dbg(common, CALIBRATE, "starting ADC DC Calibration\n");
0072 break;
0073 }
0074
0075 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
0076 AR_PHY_TIMING_CTRL4_DO_CAL);
0077 }
0078
0079 static bool ar9002_hw_per_calibration(struct ath_hw *ah,
0080 struct ath9k_channel *ichan,
0081 u8 rxchainmask,
0082 struct ath9k_cal_list *currCal)
0083 {
0084 struct ath9k_hw_cal_data *caldata = ah->caldata;
0085 bool iscaldone = false;
0086
0087 if (currCal->calState == CAL_RUNNING) {
0088 if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
0089 AR_PHY_TIMING_CTRL4_DO_CAL)) {
0090
0091 currCal->calData->calCollect(ah);
0092 ah->cal_samples++;
0093
0094 if (ah->cal_samples >=
0095 currCal->calData->calNumSamples) {
0096 int i, numChains = 0;
0097 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
0098 if (rxchainmask & (1 << i))
0099 numChains++;
0100 }
0101
0102 currCal->calData->calPostProc(ah, numChains);
0103 caldata->CalValid |= currCal->calData->calType;
0104 currCal->calState = CAL_DONE;
0105 iscaldone = true;
0106 } else {
0107 ar9002_hw_setup_calibration(ah, currCal);
0108 }
0109 } else if (time_after(jiffies, ah->cal_start_time +
0110 msecs_to_jiffies(AR9002_CAL_MAX_TIME))) {
0111 REG_CLR_BIT(ah, AR_PHY_TIMING_CTRL4(0),
0112 AR_PHY_TIMING_CTRL4_DO_CAL);
0113 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
0114 "calibration timeout\n");
0115 currCal->calState = CAL_WAITING;
0116 iscaldone = true;
0117 }
0118 } else if (!(caldata->CalValid & currCal->calData->calType)) {
0119 ath9k_hw_reset_calibration(ah, currCal);
0120 }
0121
0122 return iscaldone;
0123 }
0124
0125 static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
0126 {
0127 int i;
0128
0129 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
0130 ah->totalPowerMeasI[i] +=
0131 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
0132 ah->totalPowerMeasQ[i] +=
0133 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
0134 ah->totalIqCorrMeas[i] +=
0135 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
0136 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
0137 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
0138 ah->cal_samples, i, ah->totalPowerMeasI[i],
0139 ah->totalPowerMeasQ[i],
0140 ah->totalIqCorrMeas[i]);
0141 }
0142 }
0143
0144 static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah)
0145 {
0146 int i;
0147
0148 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
0149 ah->totalAdcIOddPhase[i] +=
0150 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
0151 ah->totalAdcIEvenPhase[i] +=
0152 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
0153 ah->totalAdcQOddPhase[i] +=
0154 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
0155 ah->totalAdcQEvenPhase[i] +=
0156 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
0157
0158 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
0159 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
0160 ah->cal_samples, i,
0161 ah->totalAdcIOddPhase[i],
0162 ah->totalAdcIEvenPhase[i],
0163 ah->totalAdcQOddPhase[i],
0164 ah->totalAdcQEvenPhase[i]);
0165 }
0166 }
0167
0168 static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah)
0169 {
0170 int i;
0171
0172 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
0173 ah->totalAdcDcOffsetIOddPhase[i] +=
0174 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
0175 ah->totalAdcDcOffsetIEvenPhase[i] +=
0176 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
0177 ah->totalAdcDcOffsetQOddPhase[i] +=
0178 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
0179 ah->totalAdcDcOffsetQEvenPhase[i] +=
0180 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
0181
0182 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
0183 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
0184 ah->cal_samples, i,
0185 ah->totalAdcDcOffsetIOddPhase[i],
0186 ah->totalAdcDcOffsetIEvenPhase[i],
0187 ah->totalAdcDcOffsetQOddPhase[i],
0188 ah->totalAdcDcOffsetQEvenPhase[i]);
0189 }
0190 }
0191
0192 static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
0193 {
0194 struct ath_common *common = ath9k_hw_common(ah);
0195 u32 powerMeasQ, powerMeasI, iqCorrMeas;
0196 u32 qCoffDenom, iCoffDenom;
0197 int32_t qCoff, iCoff;
0198 int iqCorrNeg, i;
0199
0200 for (i = 0; i < numChains; i++) {
0201 powerMeasI = ah->totalPowerMeasI[i];
0202 powerMeasQ = ah->totalPowerMeasQ[i];
0203 iqCorrMeas = ah->totalIqCorrMeas[i];
0204
0205 ath_dbg(common, CALIBRATE,
0206 "Starting IQ Cal and Correction for Chain %d\n",
0207 i);
0208
0209 ath_dbg(common, CALIBRATE,
0210 "Original: Chn %d iq_corr_meas = 0x%08x\n",
0211 i, ah->totalIqCorrMeas[i]);
0212
0213 iqCorrNeg = 0;
0214
0215 if (iqCorrMeas > 0x80000000) {
0216 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
0217 iqCorrNeg = 1;
0218 }
0219
0220 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n",
0221 i, powerMeasI);
0222 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n",
0223 i, powerMeasQ);
0224 ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg);
0225
0226 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
0227 qCoffDenom = powerMeasQ / 64;
0228
0229 if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
0230 (qCoffDenom != 0)) {
0231 iCoff = iqCorrMeas / iCoffDenom;
0232 qCoff = powerMeasI / qCoffDenom - 64;
0233 ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n",
0234 i, iCoff);
0235 ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n",
0236 i, qCoff);
0237
0238 iCoff = iCoff & 0x3f;
0239 ath_dbg(common, CALIBRATE,
0240 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
0241 if (iqCorrNeg == 0x0)
0242 iCoff = 0x40 - iCoff;
0243
0244 if (qCoff > 15)
0245 qCoff = 15;
0246 else if (qCoff <= -16)
0247 qCoff = -16;
0248
0249 ath_dbg(common, CALIBRATE,
0250 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
0251 i, iCoff, qCoff);
0252
0253 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
0254 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
0255 iCoff);
0256 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
0257 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
0258 qCoff);
0259 ath_dbg(common, CALIBRATE,
0260 "IQ Cal and Correction done for Chain %d\n",
0261 i);
0262 }
0263 }
0264
0265 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
0266 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
0267 }
0268
0269 static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
0270 {
0271 struct ath_common *common = ath9k_hw_common(ah);
0272 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
0273 u32 qGainMismatch, iGainMismatch, val, i;
0274
0275 for (i = 0; i < numChains; i++) {
0276 iOddMeasOffset = ah->totalAdcIOddPhase[i];
0277 iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
0278 qOddMeasOffset = ah->totalAdcQOddPhase[i];
0279 qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
0280
0281 ath_dbg(common, CALIBRATE,
0282 "Starting ADC Gain Cal for Chain %d\n", i);
0283
0284 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_i = 0x%08x\n",
0285 i, iOddMeasOffset);
0286 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_i = 0x%08x\n",
0287 i, iEvenMeasOffset);
0288 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_q = 0x%08x\n",
0289 i, qOddMeasOffset);
0290 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_q = 0x%08x\n",
0291 i, qEvenMeasOffset);
0292
0293 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
0294 iGainMismatch =
0295 ((iEvenMeasOffset * 32) /
0296 iOddMeasOffset) & 0x3f;
0297 qGainMismatch =
0298 ((qOddMeasOffset * 32) /
0299 qEvenMeasOffset) & 0x3f;
0300
0301 ath_dbg(common, CALIBRATE,
0302 "Chn %d gain_mismatch_i = 0x%08x\n",
0303 i, iGainMismatch);
0304 ath_dbg(common, CALIBRATE,
0305 "Chn %d gain_mismatch_q = 0x%08x\n",
0306 i, qGainMismatch);
0307
0308 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
0309 val &= 0xfffff000;
0310 val |= (qGainMismatch) | (iGainMismatch << 6);
0311 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
0312
0313 ath_dbg(common, CALIBRATE,
0314 "ADC Gain Cal done for Chain %d\n", i);
0315 }
0316 }
0317
0318 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
0319 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
0320 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
0321 }
0322
0323 static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
0324 {
0325 struct ath_common *common = ath9k_hw_common(ah);
0326 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
0327 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
0328 const struct ath9k_percal_data *calData =
0329 ah->cal_list_curr->calData;
0330 u32 numSamples =
0331 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
0332
0333 for (i = 0; i < numChains; i++) {
0334 iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
0335 iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
0336 qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
0337 qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
0338
0339 ath_dbg(common, CALIBRATE,
0340 "Starting ADC DC Offset Cal for Chain %d\n", i);
0341
0342 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_i = %d\n",
0343 i, iOddMeasOffset);
0344 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_i = %d\n",
0345 i, iEvenMeasOffset);
0346 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_q = %d\n",
0347 i, qOddMeasOffset);
0348 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_q = %d\n",
0349 i, qEvenMeasOffset);
0350
0351 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
0352 numSamples) & 0x1ff;
0353 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
0354 numSamples) & 0x1ff;
0355
0356 ath_dbg(common, CALIBRATE,
0357 "Chn %d dc_offset_mismatch_i = 0x%08x\n",
0358 i, iDcMismatch);
0359 ath_dbg(common, CALIBRATE,
0360 "Chn %d dc_offset_mismatch_q = 0x%08x\n",
0361 i, qDcMismatch);
0362
0363 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
0364 val &= 0xc0000fff;
0365 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
0366 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
0367
0368 ath_dbg(common, CALIBRATE,
0369 "ADC DC Offset Cal done for Chain %d\n", i);
0370 }
0371
0372 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
0373 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
0374 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
0375 }
0376
0377 static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
0378 {
0379 u32 rddata;
0380 int32_t delta, currPDADC, slope;
0381
0382 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
0383 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
0384
0385 if (ah->initPDADC == 0 || currPDADC == 0) {
0386
0387
0388
0389
0390
0391 return;
0392 } else {
0393 slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
0394
0395 if (slope == 0) {
0396 delta = 0;
0397 } else {
0398 delta = ((currPDADC - ah->initPDADC)*4) / slope;
0399 }
0400 REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
0401 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
0402 REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
0403 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
0404 }
0405 }
0406
0407 static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
0408 {
0409 u32 rddata, i;
0410 int delta, currPDADC, regval;
0411
0412 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
0413 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
0414
0415 if (ah->initPDADC == 0 || currPDADC == 0)
0416 return;
0417
0418 if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
0419 delta = (currPDADC - ah->initPDADC + 4) / 8;
0420 else
0421 delta = (currPDADC - ah->initPDADC + 5) / 10;
0422
0423 if (delta != ah->PDADCdelta) {
0424 ah->PDADCdelta = delta;
0425 for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
0426 regval = ah->originalGain[i] - delta;
0427 if (regval < 0)
0428 regval = 0;
0429
0430 REG_RMW_FIELD(ah,
0431 AR_PHY_TX_GAIN_TBL1 + i * 4,
0432 AR_PHY_TX_GAIN, regval);
0433 }
0434 }
0435 }
0436
0437 static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
0438 {
0439 u32 regVal;
0440 unsigned int i;
0441 u32 regList[][2] = {
0442 { AR9285_AN_TOP3, 0 },
0443 { AR9285_AN_RXTXBB1, 0 },
0444 { AR9285_AN_RF2G1, 0 },
0445 { AR9285_AN_RF2G2, 0 },
0446 { AR9285_AN_TOP2, 0 },
0447 { AR9285_AN_RF2G8, 0 },
0448 { AR9285_AN_RF2G7, 0 },
0449 { AR9285_AN_RF2G3, 0 },
0450 };
0451
0452 REG_READ_ARRAY(ah, regList, ARRAY_SIZE(regList));
0453
0454 ENABLE_REG_RMW_BUFFER(ah);
0455
0456 REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
0457
0458 REG_SET_BIT(ah, 0x9808, 1 << 27);
0459
0460 REG_SET_BIT(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
0461
0462 REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
0463
0464 REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
0465
0466 REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
0467
0468 REG_CLR_BIT(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
0469
0470 REG_CLR_BIT(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
0471
0472 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
0473
0474 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
0475
0476 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
0477
0478 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
0479
0480 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
0481
0482
0483
0484
0485 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
0486
0487 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
0488 REG_RMW_BUFFER_FLUSH(ah);
0489
0490
0491
0492
0493
0494 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
0495 udelay(30);
0496 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
0497
0498
0499 for (i = 6; i > 0; i--) {
0500 regVal = REG_READ(ah, AR9285_AN_RF2G6);
0501 regVal |= (1 << (20 + i));
0502 REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
0503 udelay(1);
0504
0505 regVal &= (~(0x1 << (20 + i)));
0506 regVal |= (MS(REG_READ(ah, AR9285_AN_RF2G9),
0507 AR9285_AN_RXTXBB1_SPARE9)
0508 << (20 + i));
0509 REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
0510 }
0511
0512 regVal = (regVal >> 20) & 0x7f;
0513
0514
0515 if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
0516 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
0517 ah->pacal_info.max_skipcount =
0518 2 * ah->pacal_info.max_skipcount;
0519 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
0520 } else {
0521 ah->pacal_info.max_skipcount = 1;
0522 ah->pacal_info.skipcount = 0;
0523 ah->pacal_info.prev_offset = regVal;
0524 }
0525
0526
0527 ENABLE_REG_RMW_BUFFER(ah);
0528
0529 REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
0530
0531 REG_CLR_BIT(ah, 0x9808, 1 << 27);
0532 REG_RMW_BUFFER_FLUSH(ah);
0533
0534 ENABLE_REGWRITE_BUFFER(ah);
0535 for (i = 0; i < ARRAY_SIZE(regList); i++)
0536 REG_WRITE(ah, regList[i][0], regList[i][1]);
0537
0538 REGWRITE_BUFFER_FLUSH(ah);
0539 }
0540
0541 static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
0542 {
0543 struct ath_common *common = ath9k_hw_common(ah);
0544 u32 regVal;
0545 int i, offset, offs_6_1, offs_0;
0546 u32 ccomp_org, reg_field;
0547 u32 regList[][2] = {
0548 { 0x786c, 0 },
0549 { 0x7854, 0 },
0550 { 0x7820, 0 },
0551 { 0x7824, 0 },
0552 { 0x7868, 0 },
0553 { 0x783c, 0 },
0554 { 0x7838, 0 },
0555 };
0556
0557 ath_dbg(common, CALIBRATE, "Running PA Calibration\n");
0558
0559
0560 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
0561 AR5416_EEP_TXGAIN_HIGH_POWER)
0562 return;
0563
0564 for (i = 0; i < ARRAY_SIZE(regList); i++)
0565 regList[i][1] = REG_READ(ah, regList[i][0]);
0566
0567 regVal = REG_READ(ah, 0x7834);
0568 regVal &= (~(0x1));
0569 REG_WRITE(ah, 0x7834, regVal);
0570 regVal = REG_READ(ah, 0x9808);
0571 regVal |= (0x1 << 27);
0572 REG_WRITE(ah, 0x9808, regVal);
0573
0574 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
0575 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
0576 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
0577 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
0578 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
0579 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
0580 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
0581 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
0582 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
0583 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
0584 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
0585 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
0586 ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
0587 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
0588
0589 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
0590 udelay(30);
0591 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
0592 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
0593
0594 for (i = 6; i > 0; i--) {
0595 regVal = REG_READ(ah, 0x7834);
0596 regVal |= (1 << (19 + i));
0597 REG_WRITE(ah, 0x7834, regVal);
0598 udelay(1);
0599 regVal = REG_READ(ah, 0x7834);
0600 regVal &= (~(0x1 << (19 + i)));
0601 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
0602 regVal |= (reg_field << (19 + i));
0603 REG_WRITE(ah, 0x7834, regVal);
0604 }
0605
0606 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
0607 udelay(1);
0608 reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
0609 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
0610 offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
0611 offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
0612
0613 offset = (offs_6_1<<1) | offs_0;
0614 offset = offset - 0;
0615 offs_6_1 = offset>>1;
0616 offs_0 = offset & 1;
0617
0618 if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
0619 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
0620 ah->pacal_info.max_skipcount =
0621 2 * ah->pacal_info.max_skipcount;
0622 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
0623 } else {
0624 ah->pacal_info.max_skipcount = 1;
0625 ah->pacal_info.skipcount = 0;
0626 ah->pacal_info.prev_offset = offset;
0627 }
0628
0629 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
0630 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
0631
0632 regVal = REG_READ(ah, 0x7834);
0633 regVal |= 0x1;
0634 REG_WRITE(ah, 0x7834, regVal);
0635 regVal = REG_READ(ah, 0x9808);
0636 regVal &= (~(0x1 << 27));
0637 REG_WRITE(ah, 0x9808, regVal);
0638
0639 for (i = 0; i < ARRAY_SIZE(regList); i++)
0640 REG_WRITE(ah, regList[i][0], regList[i][1]);
0641
0642 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
0643 }
0644
0645 static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
0646 {
0647 if (AR_SREV_9271(ah)) {
0648 if (is_reset || !ah->pacal_info.skipcount)
0649 ar9271_hw_pa_cal(ah, is_reset);
0650 else
0651 ah->pacal_info.skipcount--;
0652 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
0653 if (is_reset || !ah->pacal_info.skipcount)
0654 ar9285_hw_pa_cal(ah, is_reset);
0655 else
0656 ah->pacal_info.skipcount--;
0657 }
0658 }
0659
0660 static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
0661 {
0662 if (OLC_FOR_AR9287_10_LATER)
0663 ar9287_hw_olc_temp_compensation(ah);
0664 else if (OLC_FOR_AR9280_20_LATER)
0665 ar9280_hw_olc_temp_compensation(ah);
0666 }
0667
0668 static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
0669 u8 rxchainmask, bool longcal)
0670 {
0671 struct ath9k_cal_list *currCal = ah->cal_list_curr;
0672 bool nfcal, nfcal_pending = false, percal_pending;
0673 int ret;
0674
0675 nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
0676 if (ah->caldata) {
0677 nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags);
0678 if (longcal)
0679 set_bit(LONGCAL_PENDING, &ah->caldata->cal_flags);
0680 else if (test_bit(LONGCAL_PENDING, &ah->caldata->cal_flags))
0681 longcal = true;
0682 }
0683
0684 percal_pending = (currCal &&
0685 (currCal->calState == CAL_RUNNING ||
0686 currCal->calState == CAL_WAITING));
0687
0688 if (percal_pending && !nfcal) {
0689 if (!ar9002_hw_per_calibration(ah, chan, rxchainmask, currCal))
0690 return 0;
0691
0692
0693 for (currCal = currCal->calNext; currCal != ah->cal_list_curr;
0694 currCal = currCal->calNext) {
0695 if (currCal->calState == CAL_WAITING)
0696 break;
0697 }
0698 if (currCal->calState == CAL_WAITING) {
0699 percal_pending = true;
0700 ah->cal_list_curr = currCal;
0701 } else {
0702 percal_pending = false;
0703 ah->cal_list_curr = ah->cal_list;
0704 }
0705 }
0706
0707
0708 if (percal_pending && !nfcal && !longcal) {
0709 ath9k_hw_reset_calibration(ah, currCal);
0710
0711 return 0;
0712 }
0713
0714
0715 if (longcal || nfcal_pending) {
0716
0717
0718
0719
0720 if (ath9k_hw_getnf(ah, chan)) {
0721
0722
0723
0724
0725
0726
0727 ret = ath9k_hw_loadnf(ah, ah->curchan);
0728 if (ret < 0)
0729 return ret;
0730 }
0731
0732 if (longcal) {
0733 if (ah->caldata)
0734 clear_bit(LONGCAL_PENDING,
0735 &ah->caldata->cal_flags);
0736 ath9k_hw_start_nfcal(ah, false);
0737
0738 ar9002_hw_pa_cal(ah, false);
0739 ar9002_hw_olc_temp_compensation(ah);
0740 }
0741 }
0742
0743 return !percal_pending;
0744 }
0745
0746
0747 static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
0748 {
0749 struct ath_common *common = ath9k_hw_common(ah);
0750
0751 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
0752 if (IS_CHAN_HT20(chan)) {
0753 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
0754 REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
0755 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
0756 AR_PHY_AGC_CONTROL_FLTR_CAL);
0757 REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
0758 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
0759 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
0760 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
0761 ath_dbg(common, CALIBRATE,
0762 "offset calibration failed to complete in %d ms; noisy environment?\n",
0763 AH_WAIT_TIMEOUT / 1000);
0764 return false;
0765 }
0766 REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
0767 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
0768 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
0769 }
0770 REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
0771 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
0772 REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
0773 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
0774 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0775 0, AH_WAIT_TIMEOUT)) {
0776 ath_dbg(common, CALIBRATE,
0777 "offset calibration failed to complete in %d ms; noisy environment?\n",
0778 AH_WAIT_TIMEOUT / 1000);
0779 return false;
0780 }
0781
0782 REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
0783 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
0784 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
0785
0786 return true;
0787 }
0788
0789 static bool ar9285_hw_clc(struct ath_hw *ah, struct ath9k_channel *chan)
0790 {
0791 int i;
0792 u_int32_t txgain_max;
0793 u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
0794 u_int32_t reg_clc_I0, reg_clc_Q0;
0795 u_int32_t i0_num = 0;
0796 u_int32_t q0_num = 0;
0797 u_int32_t total_num = 0;
0798 u_int32_t reg_rf2g5_org;
0799 bool retv = true;
0800
0801 if (!(ar9285_hw_cl_cal(ah, chan)))
0802 return false;
0803
0804 txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
0805 AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
0806
0807 for (i = 0; i < (txgain_max+1); i++) {
0808 clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
0809 AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
0810 if (!(gain_mask & (1 << clc_gain))) {
0811 gain_mask |= (1 << clc_gain);
0812 clc_num++;
0813 }
0814 }
0815
0816 for (i = 0; i < clc_num; i++) {
0817 reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
0818 & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
0819 reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
0820 & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
0821 if (reg_clc_I0 == 0)
0822 i0_num++;
0823
0824 if (reg_clc_Q0 == 0)
0825 q0_num++;
0826 }
0827 total_num = i0_num + q0_num;
0828 if (total_num > AR9285_CLCAL_REDO_THRESH) {
0829 reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
0830 if (AR_SREV_9285E_20(ah)) {
0831 REG_WRITE(ah, AR9285_RF2G5,
0832 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
0833 AR9285_RF2G5_IC50TX_XE_SET);
0834 } else {
0835 REG_WRITE(ah, AR9285_RF2G5,
0836 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
0837 AR9285_RF2G5_IC50TX_SET);
0838 }
0839 retv = ar9285_hw_cl_cal(ah, chan);
0840 REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
0841 }
0842 return retv;
0843 }
0844
0845 static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
0846 {
0847 struct ath_common *common = ath9k_hw_common(ah);
0848
0849 if (AR_SREV_9271(ah)) {
0850 if (!ar9285_hw_cl_cal(ah, chan))
0851 return false;
0852 } else if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
0853 if (!ar9285_hw_clc(ah, chan))
0854 return false;
0855 } else {
0856 if (AR_SREV_9280_20_OR_LATER(ah)) {
0857 if (!AR_SREV_9287_11_OR_LATER(ah))
0858 REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
0859 AR_PHY_ADC_CTL_OFF_PWDADC);
0860 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
0861 AR_PHY_AGC_CONTROL_FLTR_CAL);
0862 }
0863
0864
0865 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
0866 REG_READ(ah, AR_PHY_AGC_CONTROL) |
0867 AR_PHY_AGC_CONTROL_CAL);
0868
0869
0870 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
0871 AR_PHY_AGC_CONTROL_CAL,
0872 0, AH_WAIT_TIMEOUT)) {
0873 ath_dbg(common, CALIBRATE,
0874 "offset calibration failed to complete in %d ms; noisy environment?\n",
0875 AH_WAIT_TIMEOUT / 1000);
0876 return false;
0877 }
0878
0879 if (AR_SREV_9280_20_OR_LATER(ah)) {
0880 if (!AR_SREV_9287_11_OR_LATER(ah))
0881 REG_SET_BIT(ah, AR_PHY_ADC_CTL,
0882 AR_PHY_ADC_CTL_OFF_PWDADC);
0883 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
0884 AR_PHY_AGC_CONTROL_FLTR_CAL);
0885 }
0886 }
0887
0888
0889 ar9002_hw_pa_cal(ah, true);
0890 ath9k_hw_loadnf(ah, chan);
0891 ath9k_hw_start_nfcal(ah, true);
0892
0893 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
0894
0895
0896 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
0897 ah->supp_cals = IQ_MISMATCH_CAL;
0898
0899 if (AR_SREV_9160_10_OR_LATER(ah))
0900 ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
0901
0902 if (AR_SREV_9287(ah))
0903 ah->supp_cals &= ~ADC_GAIN_CAL;
0904
0905 if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) {
0906 INIT_CAL(&ah->adcgain_caldata);
0907 INSERT_CAL(ah, &ah->adcgain_caldata);
0908 ath_dbg(common, CALIBRATE,
0909 "enabling ADC Gain Calibration\n");
0910 }
0911
0912 if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) {
0913 INIT_CAL(&ah->adcdc_caldata);
0914 INSERT_CAL(ah, &ah->adcdc_caldata);
0915 ath_dbg(common, CALIBRATE,
0916 "enabling ADC DC Calibration\n");
0917 }
0918
0919 if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) {
0920 INIT_CAL(&ah->iq_caldata);
0921 INSERT_CAL(ah, &ah->iq_caldata);
0922 ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
0923 }
0924
0925 ah->cal_list_curr = ah->cal_list;
0926
0927 if (ah->cal_list_curr)
0928 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
0929 }
0930
0931 if (ah->caldata)
0932 ah->caldata->CalValid = 0;
0933
0934 return true;
0935 }
0936
0937 static const struct ath9k_percal_data iq_cal_multi_sample = {
0938 IQ_MISMATCH_CAL,
0939 MAX_CAL_SAMPLES,
0940 PER_MIN_LOG_COUNT,
0941 ar9002_hw_iqcal_collect,
0942 ar9002_hw_iqcalibrate
0943 };
0944 static const struct ath9k_percal_data iq_cal_single_sample = {
0945 IQ_MISMATCH_CAL,
0946 MIN_CAL_SAMPLES,
0947 PER_MAX_LOG_COUNT,
0948 ar9002_hw_iqcal_collect,
0949 ar9002_hw_iqcalibrate
0950 };
0951 static const struct ath9k_percal_data adc_gain_cal_multi_sample = {
0952 ADC_GAIN_CAL,
0953 MAX_CAL_SAMPLES,
0954 PER_MIN_LOG_COUNT,
0955 ar9002_hw_adc_gaincal_collect,
0956 ar9002_hw_adc_gaincal_calibrate
0957 };
0958 static const struct ath9k_percal_data adc_gain_cal_single_sample = {
0959 ADC_GAIN_CAL,
0960 MIN_CAL_SAMPLES,
0961 PER_MAX_LOG_COUNT,
0962 ar9002_hw_adc_gaincal_collect,
0963 ar9002_hw_adc_gaincal_calibrate
0964 };
0965 static const struct ath9k_percal_data adc_dc_cal_multi_sample = {
0966 ADC_DC_CAL,
0967 MAX_CAL_SAMPLES,
0968 PER_MIN_LOG_COUNT,
0969 ar9002_hw_adc_dccal_collect,
0970 ar9002_hw_adc_dccal_calibrate
0971 };
0972 static const struct ath9k_percal_data adc_dc_cal_single_sample = {
0973 ADC_DC_CAL,
0974 MIN_CAL_SAMPLES,
0975 PER_MAX_LOG_COUNT,
0976 ar9002_hw_adc_dccal_collect,
0977 ar9002_hw_adc_dccal_calibrate
0978 };
0979
0980 static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
0981 {
0982 if (AR_SREV_9100(ah)) {
0983 ah->iq_caldata.calData = &iq_cal_multi_sample;
0984 ah->supp_cals = IQ_MISMATCH_CAL;
0985 return;
0986 }
0987
0988 if (AR_SREV_9160_10_OR_LATER(ah)) {
0989 if (AR_SREV_9280_20_OR_LATER(ah)) {
0990 ah->iq_caldata.calData = &iq_cal_single_sample;
0991 ah->adcgain_caldata.calData =
0992 &adc_gain_cal_single_sample;
0993 ah->adcdc_caldata.calData =
0994 &adc_dc_cal_single_sample;
0995 } else {
0996 ah->iq_caldata.calData = &iq_cal_multi_sample;
0997 ah->adcgain_caldata.calData =
0998 &adc_gain_cal_multi_sample;
0999 ah->adcdc_caldata.calData =
1000 &adc_dc_cal_multi_sample;
1001 }
1002 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
1003
1004 if (AR_SREV_9287(ah))
1005 ah->supp_cals &= ~ADC_GAIN_CAL;
1006 }
1007 }
1008
1009 void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
1010 {
1011 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1012 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1013
1014 priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
1015 priv_ops->init_cal = ar9002_hw_init_cal;
1016 priv_ops->setup_calibration = ar9002_hw_setup_calibration;
1017
1018 ops->calibrate = ar9002_hw_calibrate;
1019 }