root/drivers/net/wireless/ath/ath9k/ar9002_calib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ar9002_hw_is_cal_supported
  2. ar9002_hw_setup_calibration
  3. ar9002_hw_per_calibration
  4. ar9002_hw_iqcal_collect
  5. ar9002_hw_adc_gaincal_collect
  6. ar9002_hw_adc_dccal_collect
  7. ar9002_hw_iqcalibrate
  8. ar9002_hw_adc_gaincal_calibrate
  9. ar9002_hw_adc_dccal_calibrate
  10. ar9287_hw_olc_temp_compensation
  11. ar9280_hw_olc_temp_compensation
  12. ar9271_hw_pa_cal
  13. ar9285_hw_pa_cal
  14. ar9002_hw_pa_cal
  15. ar9002_hw_olc_temp_compensation
  16. ar9002_hw_calibrate
  17. ar9285_hw_cl_cal
  18. ar9285_hw_clc
  19. ar9002_hw_init_cal
  20. ar9002_hw_init_cal_settings
  21. ar9002_hw_attach_calib_ops

   1 /*
   2  * Copyright (c) 2008-2011 Atheros Communications Inc.
   3  *
   4  * Permission to use, copy, modify, and/or distribute this software for any
   5  * purpose with or without fee is hereby granted, provided that the above
   6  * copyright notice and this permission notice appear in all copies.
   7  *
   8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15  */
  16 
  17 #include "hw.h"
  18 #include "hw-ops.h"
  19 #include "ar9002_phy.h"
  20 
  21 #define AR9285_CLCAL_REDO_THRESH    1
  22 
  23 enum ar9002_cal_types {
  24         ADC_GAIN_CAL = BIT(0),
  25         ADC_DC_CAL = BIT(1),
  26         IQ_MISMATCH_CAL = BIT(2),
  27 };
  28 
  29 static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
  30                                 struct ath9k_channel *chan,
  31                                 enum ar9002_cal_types cal_type)
  32 {
  33         bool supported = false;
  34         switch (ah->supp_cals & cal_type) {
  35         case IQ_MISMATCH_CAL:
  36                 supported = true;
  37                 break;
  38         case ADC_GAIN_CAL:
  39         case ADC_DC_CAL:
  40                 /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
  41                 if (!((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) &&
  42                       IS_CHAN_HT20(chan)))
  43                         supported = true;
  44                 break;
  45         }
  46         return supported;
  47 }
  48 
  49 static void ar9002_hw_setup_calibration(struct ath_hw *ah,
  50                                         struct ath9k_cal_list *currCal)
  51 {
  52         struct ath_common *common = ath9k_hw_common(ah);
  53 
  54         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
  55                       AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
  56                       currCal->calData->calCountMax);
  57 
  58         switch (currCal->calData->calType) {
  59         case IQ_MISMATCH_CAL:
  60                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
  61                 ath_dbg(common, CALIBRATE,
  62                         "starting IQ Mismatch Calibration\n");
  63                 break;
  64         case ADC_GAIN_CAL:
  65                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
  66                 ath_dbg(common, CALIBRATE, "starting ADC Gain Calibration\n");
  67                 break;
  68         case ADC_DC_CAL:
  69                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
  70                 ath_dbg(common, CALIBRATE, "starting ADC DC Calibration\n");
  71                 break;
  72         }
  73 
  74         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
  75                     AR_PHY_TIMING_CTRL4_DO_CAL);
  76 }
  77 
  78 static bool ar9002_hw_per_calibration(struct ath_hw *ah,
  79                                       struct ath9k_channel *ichan,
  80                                       u8 rxchainmask,
  81                                       struct ath9k_cal_list *currCal)
  82 {
  83         struct ath9k_hw_cal_data *caldata = ah->caldata;
  84         bool iscaldone = false;
  85 
  86         if (currCal->calState == CAL_RUNNING) {
  87                 if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
  88                       AR_PHY_TIMING_CTRL4_DO_CAL)) {
  89 
  90                         currCal->calData->calCollect(ah);
  91                         ah->cal_samples++;
  92 
  93                         if (ah->cal_samples >=
  94                             currCal->calData->calNumSamples) {
  95                                 int i, numChains = 0;
  96                                 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
  97                                         if (rxchainmask & (1 << i))
  98                                                 numChains++;
  99                                 }
 100 
 101                                 currCal->calData->calPostProc(ah, numChains);
 102                                 caldata->CalValid |= currCal->calData->calType;
 103                                 currCal->calState = CAL_DONE;
 104                                 iscaldone = true;
 105                         } else {
 106                                 ar9002_hw_setup_calibration(ah, currCal);
 107                         }
 108                 }
 109         } else if (!(caldata->CalValid & currCal->calData->calType)) {
 110                 ath9k_hw_reset_calibration(ah, currCal);
 111         }
 112 
 113         return iscaldone;
 114 }
 115 
 116 static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
 117 {
 118         int i;
 119 
 120         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 121                 ah->totalPowerMeasI[i] +=
 122                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
 123                 ah->totalPowerMeasQ[i] +=
 124                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 125                 ah->totalIqCorrMeas[i] +=
 126                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
 127                 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
 128                         "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
 129                         ah->cal_samples, i, ah->totalPowerMeasI[i],
 130                         ah->totalPowerMeasQ[i],
 131                         ah->totalIqCorrMeas[i]);
 132         }
 133 }
 134 
 135 static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah)
 136 {
 137         int i;
 138 
 139         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 140                 ah->totalAdcIOddPhase[i] +=
 141                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
 142                 ah->totalAdcIEvenPhase[i] +=
 143                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 144                 ah->totalAdcQOddPhase[i] +=
 145                         REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
 146                 ah->totalAdcQEvenPhase[i] +=
 147                         REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
 148 
 149                 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
 150                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
 151                         ah->cal_samples, i,
 152                         ah->totalAdcIOddPhase[i],
 153                         ah->totalAdcIEvenPhase[i],
 154                         ah->totalAdcQOddPhase[i],
 155                         ah->totalAdcQEvenPhase[i]);
 156         }
 157 }
 158 
 159 static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah)
 160 {
 161         int i;
 162 
 163         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 164                 ah->totalAdcDcOffsetIOddPhase[i] +=
 165                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
 166                 ah->totalAdcDcOffsetIEvenPhase[i] +=
 167                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 168                 ah->totalAdcDcOffsetQOddPhase[i] +=
 169                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
 170                 ah->totalAdcDcOffsetQEvenPhase[i] +=
 171                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
 172 
 173                 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
 174                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
 175                         ah->cal_samples, i,
 176                         ah->totalAdcDcOffsetIOddPhase[i],
 177                         ah->totalAdcDcOffsetIEvenPhase[i],
 178                         ah->totalAdcDcOffsetQOddPhase[i],
 179                         ah->totalAdcDcOffsetQEvenPhase[i]);
 180         }
 181 }
 182 
 183 static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
 184 {
 185         struct ath_common *common = ath9k_hw_common(ah);
 186         u32 powerMeasQ, powerMeasI, iqCorrMeas;
 187         u32 qCoffDenom, iCoffDenom;
 188         int32_t qCoff, iCoff;
 189         int iqCorrNeg, i;
 190 
 191         for (i = 0; i < numChains; i++) {
 192                 powerMeasI = ah->totalPowerMeasI[i];
 193                 powerMeasQ = ah->totalPowerMeasQ[i];
 194                 iqCorrMeas = ah->totalIqCorrMeas[i];
 195 
 196                 ath_dbg(common, CALIBRATE,
 197                         "Starting IQ Cal and Correction for Chain %d\n",
 198                         i);
 199 
 200                 ath_dbg(common, CALIBRATE,
 201                         "Original: Chn %d iq_corr_meas = 0x%08x\n",
 202                         i, ah->totalIqCorrMeas[i]);
 203 
 204                 iqCorrNeg = 0;
 205 
 206                 if (iqCorrMeas > 0x80000000) {
 207                         iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
 208                         iqCorrNeg = 1;
 209                 }
 210 
 211                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n",
 212                         i, powerMeasI);
 213                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n",
 214                         i, powerMeasQ);
 215                 ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg);
 216 
 217                 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
 218                 qCoffDenom = powerMeasQ / 64;
 219 
 220                 if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
 221                     (qCoffDenom != 0)) {
 222                         iCoff = iqCorrMeas / iCoffDenom;
 223                         qCoff = powerMeasI / qCoffDenom - 64;
 224                         ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n",
 225                                 i, iCoff);
 226                         ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n",
 227                                 i, qCoff);
 228 
 229                         iCoff = iCoff & 0x3f;
 230                         ath_dbg(common, CALIBRATE,
 231                                 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
 232                         if (iqCorrNeg == 0x0)
 233                                 iCoff = 0x40 - iCoff;
 234 
 235                         if (qCoff > 15)
 236                                 qCoff = 15;
 237                         else if (qCoff <= -16)
 238                                 qCoff = -16;
 239 
 240                         ath_dbg(common, CALIBRATE,
 241                                 "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
 242                                 i, iCoff, qCoff);
 243 
 244                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
 245                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
 246                                       iCoff);
 247                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
 248                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
 249                                       qCoff);
 250                         ath_dbg(common, CALIBRATE,
 251                                 "IQ Cal and Correction done for Chain %d\n",
 252                                 i);
 253                 }
 254         }
 255 
 256         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
 257                     AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
 258 }
 259 
 260 static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
 261 {
 262         struct ath_common *common = ath9k_hw_common(ah);
 263         u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
 264         u32 qGainMismatch, iGainMismatch, val, i;
 265 
 266         for (i = 0; i < numChains; i++) {
 267                 iOddMeasOffset = ah->totalAdcIOddPhase[i];
 268                 iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
 269                 qOddMeasOffset = ah->totalAdcQOddPhase[i];
 270                 qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
 271 
 272                 ath_dbg(common, CALIBRATE,
 273                         "Starting ADC Gain Cal for Chain %d\n", i);
 274 
 275                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_i = 0x%08x\n",
 276                         i, iOddMeasOffset);
 277                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_i = 0x%08x\n",
 278                         i, iEvenMeasOffset);
 279                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_q = 0x%08x\n",
 280                         i, qOddMeasOffset);
 281                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_q = 0x%08x\n",
 282                         i, qEvenMeasOffset);
 283 
 284                 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
 285                         iGainMismatch =
 286                                 ((iEvenMeasOffset * 32) /
 287                                  iOddMeasOffset) & 0x3f;
 288                         qGainMismatch =
 289                                 ((qOddMeasOffset * 32) /
 290                                  qEvenMeasOffset) & 0x3f;
 291 
 292                         ath_dbg(common, CALIBRATE,
 293                                 "Chn %d gain_mismatch_i = 0x%08x\n",
 294                                 i, iGainMismatch);
 295                         ath_dbg(common, CALIBRATE,
 296                                 "Chn %d gain_mismatch_q = 0x%08x\n",
 297                                 i, qGainMismatch);
 298 
 299                         val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
 300                         val &= 0xfffff000;
 301                         val |= (qGainMismatch) | (iGainMismatch << 6);
 302                         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
 303 
 304                         ath_dbg(common, CALIBRATE,
 305                                 "ADC Gain Cal done for Chain %d\n", i);
 306                 }
 307         }
 308 
 309         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
 310                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
 311                   AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
 312 }
 313 
 314 static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
 315 {
 316         struct ath_common *common = ath9k_hw_common(ah);
 317         u32 iOddMeasOffset, iEvenMeasOffset, val, i;
 318         int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
 319         const struct ath9k_percal_data *calData =
 320                 ah->cal_list_curr->calData;
 321         u32 numSamples =
 322                 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
 323 
 324         for (i = 0; i < numChains; i++) {
 325                 iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
 326                 iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
 327                 qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
 328                 qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
 329 
 330                 ath_dbg(common, CALIBRATE,
 331                         "Starting ADC DC Offset Cal for Chain %d\n", i);
 332 
 333                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_i = %d\n",
 334                         i, iOddMeasOffset);
 335                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_i = %d\n",
 336                         i, iEvenMeasOffset);
 337                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_q = %d\n",
 338                         i, qOddMeasOffset);
 339                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_q = %d\n",
 340                         i, qEvenMeasOffset);
 341 
 342                 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
 343                                numSamples) & 0x1ff;
 344                 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
 345                                numSamples) & 0x1ff;
 346 
 347                 ath_dbg(common, CALIBRATE,
 348                         "Chn %d dc_offset_mismatch_i = 0x%08x\n",
 349                         i, iDcMismatch);
 350                 ath_dbg(common, CALIBRATE,
 351                         "Chn %d dc_offset_mismatch_q = 0x%08x\n",
 352                         i, qDcMismatch);
 353 
 354                 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
 355                 val &= 0xc0000fff;
 356                 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
 357                 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
 358 
 359                 ath_dbg(common, CALIBRATE,
 360                         "ADC DC Offset Cal done for Chain %d\n", i);
 361         }
 362 
 363         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
 364                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
 365                   AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
 366 }
 367 
 368 static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
 369 {
 370         u32 rddata;
 371         int32_t delta, currPDADC, slope;
 372 
 373         rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
 374         currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
 375 
 376         if (ah->initPDADC == 0 || currPDADC == 0) {
 377                 /*
 378                  * Zero value indicates that no frames have been transmitted
 379                  * yet, can't do temperature compensation until frames are
 380                  * transmitted.
 381                  */
 382                 return;
 383         } else {
 384                 slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
 385 
 386                 if (slope == 0) { /* to avoid divide by zero case */
 387                         delta = 0;
 388                 } else {
 389                         delta = ((currPDADC - ah->initPDADC)*4) / slope;
 390                 }
 391                 REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
 392                               AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
 393                 REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
 394                               AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
 395         }
 396 }
 397 
 398 static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
 399 {
 400         u32 rddata, i;
 401         int delta, currPDADC, regval;
 402 
 403         rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
 404         currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
 405 
 406         if (ah->initPDADC == 0 || currPDADC == 0)
 407                 return;
 408 
 409         if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
 410                 delta = (currPDADC - ah->initPDADC + 4) / 8;
 411         else
 412                 delta = (currPDADC - ah->initPDADC + 5) / 10;
 413 
 414         if (delta != ah->PDADCdelta) {
 415                 ah->PDADCdelta = delta;
 416                 for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
 417                         regval = ah->originalGain[i] - delta;
 418                         if (regval < 0)
 419                                 regval = 0;
 420 
 421                         REG_RMW_FIELD(ah,
 422                                       AR_PHY_TX_GAIN_TBL1 + i * 4,
 423                                       AR_PHY_TX_GAIN, regval);
 424                 }
 425         }
 426 }
 427 
 428 static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 429 {
 430         u32 regVal;
 431         unsigned int i;
 432         u32 regList[][2] = {
 433                 { AR9285_AN_TOP3, 0 },
 434                 { AR9285_AN_RXTXBB1, 0 },
 435                 { AR9285_AN_RF2G1, 0 },
 436                 { AR9285_AN_RF2G2, 0 },
 437                 { AR9285_AN_TOP2, 0 },
 438                 { AR9285_AN_RF2G8, 0 },
 439                 { AR9285_AN_RF2G7, 0 },
 440                 { AR9285_AN_RF2G3, 0 },
 441         };
 442 
 443         REG_READ_ARRAY(ah, regList, ARRAY_SIZE(regList));
 444 
 445         ENABLE_REG_RMW_BUFFER(ah);
 446         /* 7834, b1=0 */
 447         REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
 448         /* 9808, b27=1 */
 449         REG_SET_BIT(ah, 0x9808, 1 << 27);
 450         /* 786c,b23,1, pwddac=1 */
 451         REG_SET_BIT(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
 452         /* 7854, b5,1, pdrxtxbb=1 */
 453         REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
 454         /* 7854, b7,1, pdv2i=1 */
 455         REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
 456         /* 7854, b8,1, pddacinterface=1 */
 457         REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
 458         /* 7824,b12,0, offcal=0 */
 459         REG_CLR_BIT(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
 460         /* 7838, b1,0, pwddb=0 */
 461         REG_CLR_BIT(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
 462         /* 7820,b11,0, enpacal=0 */
 463         REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
 464         /* 7820,b25,1, pdpadrv1=0 */
 465         REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
 466         /* 7820,b24,0, pdpadrv2=0 */
 467         REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
 468         /* 7820,b23,0, pdpaout=0 */
 469         REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
 470         /* 783c,b14-16,7, padrvgn2tab_0=7 */
 471         REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
 472         /*
 473          * 7838,b29-31,0, padrvgn1tab_0=0
 474          * does not matter since we turn it off
 475          */
 476         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
 477         /* 7828, b0-11, ccom=fff */
 478         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
 479         REG_RMW_BUFFER_FLUSH(ah);
 480 
 481         /* Set:
 482          * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
 483          * txon=1,paon=1,oscon=1,synthon_force=1
 484          */
 485         REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
 486         udelay(30);
 487         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
 488 
 489         /* find off_6_1; */
 490         for (i = 6; i > 0; i--) {
 491                 regVal = REG_READ(ah, AR9285_AN_RF2G6);
 492                 regVal |= (1 << (20 + i));
 493                 REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 494                 udelay(1);
 495                 /* regVal = REG_READ(ah, 0x7834); */
 496                 regVal &= (~(0x1 << (20 + i)));
 497                 regVal |= (MS(REG_READ(ah, AR9285_AN_RF2G9),
 498                               AR9285_AN_RXTXBB1_SPARE9)
 499                             << (20 + i));
 500                 REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 501         }
 502 
 503         regVal = (regVal >> 20) & 0x7f;
 504 
 505         /* Update PA cal info */
 506         if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
 507                 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
 508                         ah->pacal_info.max_skipcount =
 509                                 2 * ah->pacal_info.max_skipcount;
 510                 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
 511         } else {
 512                 ah->pacal_info.max_skipcount = 1;
 513                 ah->pacal_info.skipcount = 0;
 514                 ah->pacal_info.prev_offset = regVal;
 515         }
 516 
 517 
 518         ENABLE_REG_RMW_BUFFER(ah);
 519         /* 7834, b1=1 */
 520         REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
 521         /* 9808, b27=0 */
 522         REG_CLR_BIT(ah, 0x9808, 1 << 27);
 523         REG_RMW_BUFFER_FLUSH(ah);
 524 
 525         ENABLE_REGWRITE_BUFFER(ah);
 526         for (i = 0; i < ARRAY_SIZE(regList); i++)
 527                 REG_WRITE(ah, regList[i][0], regList[i][1]);
 528 
 529         REGWRITE_BUFFER_FLUSH(ah);
 530 }
 531 
 532 static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 533 {
 534         struct ath_common *common = ath9k_hw_common(ah);
 535         u32 regVal;
 536         int i, offset, offs_6_1, offs_0;
 537         u32 ccomp_org, reg_field;
 538         u32 regList[][2] = {
 539                 { 0x786c, 0 },
 540                 { 0x7854, 0 },
 541                 { 0x7820, 0 },
 542                 { 0x7824, 0 },
 543                 { 0x7868, 0 },
 544                 { 0x783c, 0 },
 545                 { 0x7838, 0 },
 546         };
 547 
 548         ath_dbg(common, CALIBRATE, "Running PA Calibration\n");
 549 
 550         /* PA CAL is not needed for high power solution */
 551         if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
 552             AR5416_EEP_TXGAIN_HIGH_POWER)
 553                 return;
 554 
 555         for (i = 0; i < ARRAY_SIZE(regList); i++)
 556                 regList[i][1] = REG_READ(ah, regList[i][0]);
 557 
 558         regVal = REG_READ(ah, 0x7834);
 559         regVal &= (~(0x1));
 560         REG_WRITE(ah, 0x7834, regVal);
 561         regVal = REG_READ(ah, 0x9808);
 562         regVal |= (0x1 << 27);
 563         REG_WRITE(ah, 0x9808, regVal);
 564 
 565         REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
 566         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
 567         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
 568         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
 569         REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
 570         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
 571         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
 572         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
 573         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
 574         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
 575         REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
 576         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
 577         ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
 578         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
 579 
 580         REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
 581         udelay(30);
 582         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
 583         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
 584 
 585         for (i = 6; i > 0; i--) {
 586                 regVal = REG_READ(ah, 0x7834);
 587                 regVal |= (1 << (19 + i));
 588                 REG_WRITE(ah, 0x7834, regVal);
 589                 udelay(1);
 590                 regVal = REG_READ(ah, 0x7834);
 591                 regVal &= (~(0x1 << (19 + i)));
 592                 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
 593                 regVal |= (reg_field << (19 + i));
 594                 REG_WRITE(ah, 0x7834, regVal);
 595         }
 596 
 597         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
 598         udelay(1);
 599         reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
 600         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
 601         offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
 602         offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
 603 
 604         offset = (offs_6_1<<1) | offs_0;
 605         offset = offset - 0;
 606         offs_6_1 = offset>>1;
 607         offs_0 = offset & 1;
 608 
 609         if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
 610                 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
 611                         ah->pacal_info.max_skipcount =
 612                                 2 * ah->pacal_info.max_skipcount;
 613                 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
 614         } else {
 615                 ah->pacal_info.max_skipcount = 1;
 616                 ah->pacal_info.skipcount = 0;
 617                 ah->pacal_info.prev_offset = offset;
 618         }
 619 
 620         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
 621         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
 622 
 623         regVal = REG_READ(ah, 0x7834);
 624         regVal |= 0x1;
 625         REG_WRITE(ah, 0x7834, regVal);
 626         regVal = REG_READ(ah, 0x9808);
 627         regVal &= (~(0x1 << 27));
 628         REG_WRITE(ah, 0x9808, regVal);
 629 
 630         for (i = 0; i < ARRAY_SIZE(regList); i++)
 631                 REG_WRITE(ah, regList[i][0], regList[i][1]);
 632 
 633         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
 634 }
 635 
 636 static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 637 {
 638         if (AR_SREV_9271(ah)) {
 639                 if (is_reset || !ah->pacal_info.skipcount)
 640                         ar9271_hw_pa_cal(ah, is_reset);
 641                 else
 642                         ah->pacal_info.skipcount--;
 643         } else if (AR_SREV_9285_12_OR_LATER(ah)) {
 644                 if (is_reset || !ah->pacal_info.skipcount)
 645                         ar9285_hw_pa_cal(ah, is_reset);
 646                 else
 647                         ah->pacal_info.skipcount--;
 648         }
 649 }
 650 
 651 static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
 652 {
 653         if (OLC_FOR_AR9287_10_LATER)
 654                 ar9287_hw_olc_temp_compensation(ah);
 655         else if (OLC_FOR_AR9280_20_LATER)
 656                 ar9280_hw_olc_temp_compensation(ah);
 657 }
 658 
 659 static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 660                                u8 rxchainmask, bool longcal)
 661 {
 662         struct ath9k_cal_list *currCal = ah->cal_list_curr;
 663         bool nfcal, nfcal_pending = false, percal_pending;
 664         int ret;
 665 
 666         nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
 667         if (ah->caldata)
 668                 nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags);
 669 
 670         percal_pending = (currCal &&
 671                           (currCal->calState == CAL_RUNNING ||
 672                            currCal->calState == CAL_WAITING));
 673 
 674         if (percal_pending && !nfcal) {
 675                 if (!ar9002_hw_per_calibration(ah, chan, rxchainmask, currCal))
 676                         return 0;
 677 
 678                 ah->cal_list_curr = currCal = currCal->calNext;
 679                 if (currCal->calState == CAL_WAITING)
 680                         ath9k_hw_reset_calibration(ah, currCal);
 681 
 682                 return 0;
 683         }
 684 
 685         /* Do NF cal only at longer intervals */
 686         if (longcal || nfcal_pending) {
 687                 /*
 688                  * Get the value from the previous NF cal and update
 689                  * history buffer.
 690                  */
 691                 if (ath9k_hw_getnf(ah, chan)) {
 692                         /*
 693                          * Load the NF from history buffer of the current
 694                          * channel.
 695                          * NF is slow time-variant, so it is OK to use a
 696                          * historical value.
 697                          */
 698                         ret = ath9k_hw_loadnf(ah, ah->curchan);
 699                         if (ret < 0)
 700                                 return ret;
 701                 }
 702 
 703                 if (longcal) {
 704                         ath9k_hw_start_nfcal(ah, false);
 705                         /* Do periodic PAOffset Cal */
 706                         ar9002_hw_pa_cal(ah, false);
 707                         ar9002_hw_olc_temp_compensation(ah);
 708                 }
 709         }
 710 
 711         return !percal_pending;
 712 }
 713 
 714 /* Carrier leakage Calibration fix */
 715 static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
 716 {
 717         struct ath_common *common = ath9k_hw_common(ah);
 718 
 719         REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
 720         if (IS_CHAN_HT20(chan)) {
 721                 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
 722                 REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
 723                 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 724                             AR_PHY_AGC_CONTROL_FLTR_CAL);
 725                 REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
 726                 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
 727                 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
 728                                   AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
 729                         ath_dbg(common, CALIBRATE,
 730                                 "offset calibration failed to complete in %d ms; noisy environment?\n",
 731                                 AH_WAIT_TIMEOUT / 1000);
 732                         return false;
 733                 }
 734                 REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
 735                 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
 736                 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
 737         }
 738         REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
 739         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
 740         REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
 741         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
 742         if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
 743                           0, AH_WAIT_TIMEOUT)) {
 744                 ath_dbg(common, CALIBRATE,
 745                         "offset calibration failed to complete in %d ms; noisy environment?\n",
 746                         AH_WAIT_TIMEOUT / 1000);
 747                 return false;
 748         }
 749 
 750         REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
 751         REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
 752         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
 753 
 754         return true;
 755 }
 756 
 757 static bool ar9285_hw_clc(struct ath_hw *ah, struct ath9k_channel *chan)
 758 {
 759         int i;
 760         u_int32_t txgain_max;
 761         u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
 762         u_int32_t reg_clc_I0, reg_clc_Q0;
 763         u_int32_t i0_num = 0;
 764         u_int32_t q0_num = 0;
 765         u_int32_t total_num = 0;
 766         u_int32_t reg_rf2g5_org;
 767         bool retv = true;
 768 
 769         if (!(ar9285_hw_cl_cal(ah, chan)))
 770                 return false;
 771 
 772         txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
 773                         AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
 774 
 775         for (i = 0; i < (txgain_max+1); i++) {
 776                 clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
 777                            AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
 778                 if (!(gain_mask & (1 << clc_gain))) {
 779                         gain_mask |= (1 << clc_gain);
 780                         clc_num++;
 781                 }
 782         }
 783 
 784         for (i = 0; i < clc_num; i++) {
 785                 reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
 786                               & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
 787                 reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
 788                               & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
 789                 if (reg_clc_I0 == 0)
 790                         i0_num++;
 791 
 792                 if (reg_clc_Q0 == 0)
 793                         q0_num++;
 794         }
 795         total_num = i0_num + q0_num;
 796         if (total_num > AR9285_CLCAL_REDO_THRESH) {
 797                 reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
 798                 if (AR_SREV_9285E_20(ah)) {
 799                         REG_WRITE(ah, AR9285_RF2G5,
 800                                   (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
 801                                   AR9285_RF2G5_IC50TX_XE_SET);
 802                 } else {
 803                         REG_WRITE(ah, AR9285_RF2G5,
 804                                   (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
 805                                   AR9285_RF2G5_IC50TX_SET);
 806                 }
 807                 retv = ar9285_hw_cl_cal(ah, chan);
 808                 REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
 809         }
 810         return retv;
 811 }
 812 
 813 static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
 814 {
 815         struct ath_common *common = ath9k_hw_common(ah);
 816 
 817         if (AR_SREV_9271(ah)) {
 818                 if (!ar9285_hw_cl_cal(ah, chan))
 819                         return false;
 820         } else if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
 821                 if (!ar9285_hw_clc(ah, chan))
 822                         return false;
 823         } else {
 824                 if (AR_SREV_9280_20_OR_LATER(ah)) {
 825                         if (!AR_SREV_9287_11_OR_LATER(ah))
 826                                 REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
 827                                             AR_PHY_ADC_CTL_OFF_PWDADC);
 828                         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
 829                                     AR_PHY_AGC_CONTROL_FLTR_CAL);
 830                 }
 831 
 832                 /* Calibrate the AGC */
 833                 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
 834                           REG_READ(ah, AR_PHY_AGC_CONTROL) |
 835                           AR_PHY_AGC_CONTROL_CAL);
 836 
 837                 /* Poll for offset calibration complete */
 838                 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
 839                                    AR_PHY_AGC_CONTROL_CAL,
 840                                    0, AH_WAIT_TIMEOUT)) {
 841                         ath_dbg(common, CALIBRATE,
 842                                 "offset calibration failed to complete in %d ms; noisy environment?\n",
 843                                 AH_WAIT_TIMEOUT / 1000);
 844                         return false;
 845                 }
 846 
 847                 if (AR_SREV_9280_20_OR_LATER(ah)) {
 848                         if (!AR_SREV_9287_11_OR_LATER(ah))
 849                                 REG_SET_BIT(ah, AR_PHY_ADC_CTL,
 850                                             AR_PHY_ADC_CTL_OFF_PWDADC);
 851                         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 852                                     AR_PHY_AGC_CONTROL_FLTR_CAL);
 853                 }
 854         }
 855 
 856         /* Do PA Calibration */
 857         ar9002_hw_pa_cal(ah, true);
 858         ath9k_hw_loadnf(ah, chan);
 859         ath9k_hw_start_nfcal(ah, true);
 860 
 861         if (ah->caldata)
 862                 set_bit(NFCAL_PENDING, &ah->caldata->cal_flags);
 863 
 864         ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
 865 
 866         /* Enable IQ, ADC Gain and ADC DC offset CALs */
 867         if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
 868                 ah->supp_cals = IQ_MISMATCH_CAL;
 869 
 870                 if (AR_SREV_9160_10_OR_LATER(ah))
 871                         ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
 872 
 873                 if (AR_SREV_9287(ah))
 874                         ah->supp_cals &= ~ADC_GAIN_CAL;
 875 
 876                 if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) {
 877                         INIT_CAL(&ah->adcgain_caldata);
 878                         INSERT_CAL(ah, &ah->adcgain_caldata);
 879                         ath_dbg(common, CALIBRATE,
 880                                         "enabling ADC Gain Calibration\n");
 881                 }
 882 
 883                 if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) {
 884                         INIT_CAL(&ah->adcdc_caldata);
 885                         INSERT_CAL(ah, &ah->adcdc_caldata);
 886                         ath_dbg(common, CALIBRATE,
 887                                         "enabling ADC DC Calibration\n");
 888                 }
 889 
 890                 if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) {
 891                         INIT_CAL(&ah->iq_caldata);
 892                         INSERT_CAL(ah, &ah->iq_caldata);
 893                         ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
 894                 }
 895 
 896                 ah->cal_list_curr = ah->cal_list;
 897 
 898                 if (ah->cal_list_curr)
 899                         ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
 900         }
 901 
 902         if (ah->caldata)
 903                 ah->caldata->CalValid = 0;
 904 
 905         return true;
 906 }
 907 
 908 static const struct ath9k_percal_data iq_cal_multi_sample = {
 909         IQ_MISMATCH_CAL,
 910         MAX_CAL_SAMPLES,
 911         PER_MIN_LOG_COUNT,
 912         ar9002_hw_iqcal_collect,
 913         ar9002_hw_iqcalibrate
 914 };
 915 static const struct ath9k_percal_data iq_cal_single_sample = {
 916         IQ_MISMATCH_CAL,
 917         MIN_CAL_SAMPLES,
 918         PER_MAX_LOG_COUNT,
 919         ar9002_hw_iqcal_collect,
 920         ar9002_hw_iqcalibrate
 921 };
 922 static const struct ath9k_percal_data adc_gain_cal_multi_sample = {
 923         ADC_GAIN_CAL,
 924         MAX_CAL_SAMPLES,
 925         PER_MIN_LOG_COUNT,
 926         ar9002_hw_adc_gaincal_collect,
 927         ar9002_hw_adc_gaincal_calibrate
 928 };
 929 static const struct ath9k_percal_data adc_gain_cal_single_sample = {
 930         ADC_GAIN_CAL,
 931         MIN_CAL_SAMPLES,
 932         PER_MAX_LOG_COUNT,
 933         ar9002_hw_adc_gaincal_collect,
 934         ar9002_hw_adc_gaincal_calibrate
 935 };
 936 static const struct ath9k_percal_data adc_dc_cal_multi_sample = {
 937         ADC_DC_CAL,
 938         MAX_CAL_SAMPLES,
 939         PER_MIN_LOG_COUNT,
 940         ar9002_hw_adc_dccal_collect,
 941         ar9002_hw_adc_dccal_calibrate
 942 };
 943 static const struct ath9k_percal_data adc_dc_cal_single_sample = {
 944         ADC_DC_CAL,
 945         MIN_CAL_SAMPLES,
 946         PER_MAX_LOG_COUNT,
 947         ar9002_hw_adc_dccal_collect,
 948         ar9002_hw_adc_dccal_calibrate
 949 };
 950 
 951 static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
 952 {
 953         if (AR_SREV_9100(ah)) {
 954                 ah->iq_caldata.calData = &iq_cal_multi_sample;
 955                 ah->supp_cals = IQ_MISMATCH_CAL;
 956                 return;
 957         }
 958 
 959         if (AR_SREV_9160_10_OR_LATER(ah)) {
 960                 if (AR_SREV_9280_20_OR_LATER(ah)) {
 961                         ah->iq_caldata.calData = &iq_cal_single_sample;
 962                         ah->adcgain_caldata.calData =
 963                                 &adc_gain_cal_single_sample;
 964                         ah->adcdc_caldata.calData =
 965                                 &adc_dc_cal_single_sample;
 966                 } else {
 967                         ah->iq_caldata.calData = &iq_cal_multi_sample;
 968                         ah->adcgain_caldata.calData =
 969                                 &adc_gain_cal_multi_sample;
 970                         ah->adcdc_caldata.calData =
 971                                 &adc_dc_cal_multi_sample;
 972                 }
 973                 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
 974 
 975                 if (AR_SREV_9287(ah))
 976                         ah->supp_cals &= ~ADC_GAIN_CAL;
 977         }
 978 }
 979 
 980 void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
 981 {
 982         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
 983         struct ath_hw_ops *ops = ath9k_hw_ops(ah);
 984 
 985         priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
 986         priv_ops->init_cal = ar9002_hw_init_cal;
 987         priv_ops->setup_calibration = ar9002_hw_setup_calibration;
 988 
 989         ops->calibrate = ar9002_hw_calibrate;
 990 }

/* [<][>][^][v][top][bottom][index][help] */