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