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