OSDN Git Service

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