]> Pileus Git - ~andy/linux/blob - drivers/staging/winbond/phy_calibration.c
08cec74bdad7bbe9be5d34d06063fce4494e0d76
[~andy/linux] / drivers / staging / winbond / phy_calibration.c
1 /*
2  * phy_302_calibration.c
3  *
4  * Copyright (C) 2002, 2005  Winbond Electronics Corp.
5  *
6  * modification history
7  * ---------------------------------------------------------------------------
8  * 0.01.001, 2003-04-16, Kevin      created
9  *
10  */
11
12 /****************** INCLUDE FILES SECTION ***********************************/
13 #include "sysdef.h"
14 #include "phy_calibration.h"
15 #include "wbhal_s.h"
16 #include "wb35reg_f.h"
17 #include "core.h"
18
19
20 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
21
22 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
23 #define LOOP_TIMES      20
24 #define US              1000/* MICROSECOND*/
25
26 #define AG_CONST        0.6072529350
27 #define FIXED(X)        ((s32)((X) * 32768.0))
28 #define DEG2RAD(X)      0.017453 * (X)
29
30 static const s32 Angles[] = {
31     FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),   FIXED(DEG2RAD(14.0362)),
32     FIXED(DEG2RAD(7.12502)),  FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
33     FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
34     FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
35 };
36
37 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
38
39 /*
40  * void    _phy_rf_write_delay(struct hw_data *phw_data);
41  * void    phy_init_rf(struct hw_data *phw_data);
42  */
43
44 /****************** FUNCTION DEFINITION SECTION *****************************/
45
46 s32 _s13_to_s32(u32 data)
47 {
48     u32     val;
49
50     val = (data & 0x0FFF);
51
52     if ((data & BIT(12)) != 0)
53         val |= 0xFFFFF000;
54
55     return ((s32) val);
56 }
57
58 u32 _s32_to_s13(s32 data)
59 {
60     u32     val;
61
62     if (data > 4095)
63         data = 4095;
64     else if (data < -4096)
65         data = -4096;
66
67     val = data & 0x1FFF;
68
69     return val;
70 }
71
72 /****************************************************************************/
73 s32 _s4_to_s32(u32 data)
74 {
75     s32     val;
76
77     val = (data & 0x0007);
78
79     if ((data & BIT(3)) != 0)
80         val |= 0xFFFFFFF8;
81
82     return val;
83 }
84
85 u32 _s32_to_s4(s32 data)
86 {
87     u32     val;
88
89     if (data > 7)
90         data = 7;
91     else if (data < -8)
92         data = -8;
93
94     val = data & 0x000F;
95
96     return val;
97 }
98
99 /****************************************************************************/
100 s32 _s5_to_s32(u32 data)
101 {
102     s32     val;
103
104     val = (data & 0x000F);
105
106     if ((data & BIT(4)) != 0)
107         val |= 0xFFFFFFF0;
108
109     return val;
110 }
111
112 u32 _s32_to_s5(s32 data)
113 {
114     u32     val;
115
116     if (data > 15)
117         data = 15;
118     else if (data < -16)
119         data = -16;
120
121     val = data & 0x001F;
122
123     return val;
124 }
125
126 /****************************************************************************/
127 s32 _s6_to_s32(u32 data)
128 {
129     s32     val;
130
131     val = (data & 0x001F);
132
133     if ((data & BIT(5)) != 0)
134         val |= 0xFFFFFFE0;
135
136     return val;
137 }
138
139 u32 _s32_to_s6(s32 data)
140 {
141     u32     val;
142
143     if (data > 31)
144         data = 31;
145     else if (data < -32)
146         data = -32;
147
148     val = data & 0x003F;
149
150     return val;
151 }
152
153 /****************************************************************************/
154 s32 _s9_to_s32(u32 data)
155 {
156     s32     val;
157
158     val = data & 0x00FF;
159
160     if ((data & BIT(8)) != 0)
161         val |= 0xFFFFFF00;
162
163     return val;
164 }
165
166 u32 _s32_to_s9(s32 data)
167 {
168     u32     val;
169
170     if (data > 255)
171         data = 255;
172     else if (data < -256)
173         data = -256;
174
175     val = data & 0x01FF;
176
177     return val;
178 }
179
180 /****************************************************************************/
181 s32 _floor(s32 n)
182 {
183     if (n > 0)
184         n += 5;
185     else
186         n -= 5;
187
188     return (n/10);
189 }
190
191 /****************************************************************************/
192 /*
193  * The following code is sqare-root function.
194  * sqsum is the input and the output is sq_rt;
195  * The maximum of sqsum = 2^27 -1;
196  */
197 u32 _sqrt(u32 sqsum)
198 {
199     u32     sq_rt;
200
201     int     g0, g1, g2, g3, g4;
202     int     seed;
203     int     next;
204     int     step;
205
206     g4 =  sqsum / 100000000;
207     g3 = (sqsum - g4*100000000) / 1000000;
208     g2 = (sqsum - g4*100000000 - g3*1000000) / 10000;
209     g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100;
210     g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
211
212     next = g4;
213     step = 0;
214     seed = 0;
215     while (((seed+1)*(step+1)) <= next) {
216         step++;
217         seed++;
218     }
219
220     sq_rt = seed * 10000;
221     next = (next-(seed*step))*100 + g3;
222
223     step = 0;
224     seed = 2 * seed * 10;
225     while (((seed+1)*(step+1)) <= next) {
226         step++;
227         seed++;
228     }
229
230     sq_rt = sq_rt + step * 1000;
231     next = (next - seed * step) * 100 + g2;
232     seed = (seed + step) * 10;
233     step = 0;
234     while (((seed+1)*(step+1)) <= next) {
235         step++;
236         seed++;
237     }
238
239     sq_rt = sq_rt + step * 100;
240     next = (next - seed * step) * 100 + g1;
241     seed = (seed + step) * 10;
242     step = 0;
243
244     while (((seed+1)*(step+1)) <= next) {
245         step++;
246         seed++;
247     }
248
249     sq_rt = sq_rt + step * 10;
250     next = (next - seed * step) * 100 + g0;
251     seed = (seed + step) * 10;
252     step = 0;
253
254     while (((seed+1)*(step+1)) <= next) {
255         step++;
256         seed++;
257     }
258
259     sq_rt = sq_rt + step;
260
261     return sq_rt;
262 }
263
264 /****************************************************************************/
265 void _sin_cos(s32 angle, s32 *sin, s32 *cos)
266 {
267     s32 X, Y, TargetAngle, CurrAngle;
268     unsigned    Step;
269
270     X = FIXED(AG_CONST);      /* AG_CONST * cos(0) */
271     Y = 0;                    /* AG_CONST * sin(0) */
272     TargetAngle = abs(angle);
273     CurrAngle = 0;
274
275     for (Step = 0; Step < 12; Step++) {
276         s32 NewX;
277
278         if (TargetAngle > CurrAngle) {
279             NewX = X - (Y >> Step);
280             Y = (X >> Step) + Y;
281             X = NewX;
282             CurrAngle += Angles[Step];
283         } else {
284             NewX = X + (Y >> Step);
285             Y = -(X >> Step) + Y;
286             X = NewX;
287             CurrAngle -= Angles[Step];
288         }
289     }
290
291     if (angle > 0) {
292         *cos = X;
293         *sin = Y;
294     } else {
295         *cos = X;
296         *sin = -Y;
297     }
298 }
299
300 static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue)
301 {
302         if (number < 0x1000)
303                 number += 0x1000;
304         return Wb35Reg_ReadSync(pHwData, number, pValue);
305 }
306 #define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
307
308 static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
309 {
310         unsigned char ret;
311
312         if (number < 0x1000)
313                 number += 0x1000;
314         ret = Wb35Reg_WriteSync(pHwData, number, value);
315         return ret;
316 }
317 #define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
318
319
320 void _reset_rx_cal(struct hw_data *phw_data)
321 {
322         u32     val;
323
324         hw_get_dxx_reg(phw_data, 0x54, &val);
325
326         if (phw_data->revision == 0x2002) /* 1st-cut */
327                 val &= 0xFFFF0000;
328         else /* 2nd-cut */
329                 val &= 0x000003FF;
330
331         hw_set_dxx_reg(phw_data, 0x54, val);
332 }
333
334
335 /**************for winbond calibration*********/
336
337
338
339 /**********************************************/
340 void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
341 {
342     u32     reg_agc_ctrl3;
343     u32     reg_a_acq_ctrl;
344     u32     reg_b_acq_ctrl;
345     u32     val;
346
347     PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
348     phy_init_rf(phw_data);
349
350     /* set calibration channel */
351     if ((RF_WB_242 == phw_data->phy_type) ||
352                 (RF_WB_242_1 == phw_data->phy_type)) /* 20060619.5 Add */{
353         if ((frequency >= 2412) && (frequency <= 2484)) {
354             /* w89rf242 change frequency to 2390Mhz */
355             PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
356                         phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
357
358         }
359     } else {
360
361         }
362
363         /* reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
364         hw_get_dxx_reg(phw_data, 0x5C, &val);
365         val &= ~(0x03FF);
366         hw_set_dxx_reg(phw_data, 0x5C, val);
367
368         /* reset the TX and RX IQ calibration data */
369         hw_set_dxx_reg(phw_data, 0x3C, 0);
370         hw_set_dxx_reg(phw_data, 0x54, 0);
371
372         hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
373
374         /* a. Disable AGC */
375         hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
376         reg_agc_ctrl3 &= ~BIT(2);
377         reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
378         hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
379
380         hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
381         val |= MASK_AGC_FIX_GAIN;
382         hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
383
384         /* b. Turn off BB RX */
385         hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
386         reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
387         hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
388
389         hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl);
390         reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
391         hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
392
393         /* c. Make sure MAC is in receiving mode
394          * d. Turn ON ADC calibration
395          *    - ADC calibrator is triggered by this signal rising from 0 to 1 */
396         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
397         val &= ~MASK_ADC_DC_CAL_STR;
398         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
399
400         val |= MASK_ADC_DC_CAL_STR;
401         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
402
403         /* e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */
404 #ifdef _DEBUG
405         hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val);
406         PHY_DEBUG(("[CAL]    REG_OFFSET_READ = 0x%08X\n", val));
407
408         PHY_DEBUG(("[CAL]    ** adc_dc_cal_i = %d (0x%04X)\n",
409                            _s9_to_s32(val&0x000001FF), val&0x000001FF));
410         PHY_DEBUG(("[CAL]    ** adc_dc_cal_q = %d (0x%04X)\n",
411                            _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9));
412 #endif
413
414         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
415         val &= ~MASK_ADC_DC_CAL_STR;
416         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
417
418         /* f. Turn on BB RX */
419         /* hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl); */
420         reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG;
421         hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
422
423         /* hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl); */
424         reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG;
425         hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
426
427         /* g. Enable AGC */
428         /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
429         reg_agc_ctrl3 |= BIT(2);
430         reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
431         hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
432 }
433
434 /****************************************************************/
435 void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
436 {
437         u32     reg_agc_ctrl3;
438         u32     reg_mode_ctrl;
439         u32     reg_dc_cancel;
440         s32     iqcal_image_i;
441         s32     iqcal_image_q;
442         u32     sqsum;
443         s32     mag_0;
444         s32     mag_1;
445         s32     fix_cancel_dc_i = 0;
446         u32     val;
447         int     loop;
448
449         PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
450
451         /* a. Set to "TX calibration mode" */
452
453         /* 0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
454         phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
455         /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
456         phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
457         /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
458         phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
459         /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
460         phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
461         /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
462         phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
463
464         hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
465
466         /* a. Disable AGC */
467         hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
468         reg_agc_ctrl3 &= ~BIT(2);
469         reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
470         hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
471
472         hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
473         val |= MASK_AGC_FIX_GAIN;
474         hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
475
476         /* b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 */
477         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
478
479         PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
480         reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
481
482         /* mode=2, tone=0 */
483         /* reg_mode_ctrl |= (MASK_CALIB_START|2); */
484
485         /* mode=2, tone=1 */
486         /* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */
487
488         /* mode=2, tone=2 */
489         reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2));
490         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
491         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
492
493         hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
494         PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
495
496         for (loop = 0; loop < LOOP_TIMES; loop++) {
497                 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
498
499                 /* c. reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
500                 reg_dc_cancel &= ~(0x03FF);
501                 PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
502                 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
503
504                 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
505                 PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
506
507                 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
508                 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
509                 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
510                 mag_0 = (s32) _sqrt(sqsum);
511                 PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
512                                    mag_0, iqcal_image_i, iqcal_image_q));
513
514                 /* d. */
515                 reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
516                 PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
517                 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
518
519                 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
520                 PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
521
522                 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
523                 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
524                 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
525                 mag_1 = (s32) _sqrt(sqsum);
526                 PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
527                                    mag_1, iqcal_image_i, iqcal_image_q));
528
529                 /* e. Calculate the correct DC offset cancellation value for I */
530                 if (mag_0 != mag_1)
531                         fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
532                 else {
533                         if (mag_0 == mag_1)
534                                 PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
535                         fix_cancel_dc_i = 0;
536                 }
537
538                 PHY_DEBUG(("[CAL]    ** fix_cancel_dc_i = %d (0x%04X)\n",
539                                    fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
540
541                 if ((abs(mag_1-mag_0)*6) > mag_0)
542                         break;
543         }
544
545         if (loop >= 19)
546            fix_cancel_dc_i = 0;
547
548         reg_dc_cancel &= ~(0x03FF);
549         reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT);
550         hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
551         PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
552
553         /* g. */
554         reg_mode_ctrl &= ~MASK_CALIB_START;
555         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
556         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
557 }
558
559 /*****************************************************/
560 void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
561 {
562         u32     reg_agc_ctrl3;
563         u32     reg_mode_ctrl;
564         u32     reg_dc_cancel;
565         s32     iqcal_image_i;
566         s32     iqcal_image_q;
567         u32     sqsum;
568         s32     mag_0;
569         s32     mag_1;
570         s32     fix_cancel_dc_q = 0;
571         u32     val;
572         int     loop;
573
574         PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
575         /*0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
576         phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
577         /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
578         phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
579         /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
580         phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
581         /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
582         phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
583         /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
584         phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
585
586         hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
587
588         /* a. Disable AGC */
589         hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
590         reg_agc_ctrl3 &= ~BIT(2);
591         reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
592         hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
593
594         hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
595         val |= MASK_AGC_FIX_GAIN;
596         hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
597
598         /* a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 */
599         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
600         PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
601
602         /* reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); */
603         reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
604         reg_mode_ctrl |= (MASK_CALIB_START|3);
605         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
606         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
607
608         hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
609         PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
610
611         for (loop = 0; loop < LOOP_TIMES; loop++) {
612                 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
613
614                 /* b. reset cancel_dc_q[4:0] in register DC_Cancel */
615                 reg_dc_cancel &= ~(0x001F);
616                 PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
617                 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
618
619                 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
620                 PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
621
622                 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
623                 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
624                 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
625                 mag_0 = _sqrt(sqsum);
626                 PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
627                                    mag_0, iqcal_image_i, iqcal_image_q));
628
629                 /* c. */
630                 reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
631                 PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
632                 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
633
634                 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
635                 PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
636
637                 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
638                 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
639                 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
640                 mag_1 = _sqrt(sqsum);
641                 PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
642                                    mag_1, iqcal_image_i, iqcal_image_q));
643
644                 /* d. Calculate the correct DC offset cancellation value for I */
645                 if (mag_0 != mag_1)
646                         fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
647                 else {
648                         if (mag_0 == mag_1)
649                                 PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
650                         fix_cancel_dc_q = 0;
651                 }
652
653                 PHY_DEBUG(("[CAL]    ** fix_cancel_dc_q = %d (0x%04X)\n",
654                                    fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
655
656                 if ((abs(mag_1-mag_0)*6) > mag_0)
657                         break;
658         }
659
660         if (loop >= 19)
661            fix_cancel_dc_q = 0;
662
663         reg_dc_cancel &= ~(0x001F);
664         reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT);
665         hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
666         PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
667
668
669         /* f. */
670         reg_mode_ctrl &= ~MASK_CALIB_START;
671         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
672         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
673 }
674
675 /* 20060612.1.a 20060718.1 Modify */
676 u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
677                                                    s32 a_2_threshold,
678                                                    s32 b_2_threshold)
679 {
680         u32     reg_mode_ctrl;
681         s32     iq_mag_0_tx;
682         s32     iqcal_tone_i0;
683         s32     iqcal_tone_q0;
684         s32     iqcal_tone_i;
685         s32     iqcal_tone_q;
686         u32     sqsum;
687         s32     rot_i_b;
688         s32     rot_q_b;
689         s32     tx_cal_flt_b[4];
690         s32     tx_cal[4];
691         s32     tx_cal_reg[4];
692         s32     a_2, b_2;
693         s32     sin_b, sin_2b;
694         s32     cos_b, cos_2b;
695         s32     divisor;
696         s32     temp1, temp2;
697         u32     val;
698         u16     loop;
699         s32     iqcal_tone_i_avg, iqcal_tone_q_avg;
700         u8      verify_count;
701         int capture_time;
702
703         PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
704         PHY_DEBUG(("[CAL]    ** a_2_threshold = %d\n", a_2_threshold));
705         PHY_DEBUG(("[CAL]    ** b_2_threshold = %d\n", b_2_threshold));
706
707         verify_count = 0;
708
709         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
710         PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
711
712         loop = LOOP_TIMES;
713
714         while (loop > 0) {
715                 PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
716
717                 iqcal_tone_i_avg = 0;
718                 iqcal_tone_q_avg = 0;
719                 if (!hw_set_dxx_reg(phw_data, 0x3C, 0x00)) /* 20060718.1 modify */
720                         return 0;
721                 for (capture_time = 0; capture_time < 10; capture_time++) {
722                         /*
723                          * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
724                          *    enable "IQ alibration Mode II"
725                          */
726                         reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
727                         reg_mode_ctrl &= ~MASK_IQCAL_MODE;
728                         reg_mode_ctrl |= (MASK_CALIB_START|0x02);
729                         reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
730                         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
731                         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
732
733                         /* b. */
734                         hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
735                         PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
736
737                         iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
738                         iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
739                         PHY_DEBUG(("[CAL]    ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
740                                    iqcal_tone_i0, iqcal_tone_q0));
741
742                         sqsum = iqcal_tone_i0*iqcal_tone_i0 +
743                         iqcal_tone_q0*iqcal_tone_q0;
744                         iq_mag_0_tx = (s32) _sqrt(sqsum);
745                         PHY_DEBUG(("[CAL]    ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
746
747                         /* c. Set "calib_start" to 0x0 */
748                         reg_mode_ctrl &= ~MASK_CALIB_START;
749                         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
750                         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
751
752                         /*
753                          * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
754                          *    enable "IQ alibration Mode II"
755                          */
756                         /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
757                         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
758                         reg_mode_ctrl &= ~MASK_IQCAL_MODE;
759                         reg_mode_ctrl |= (MASK_CALIB_START|0x03);
760                         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
761                         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
762
763                         /* e. */
764                         hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
765                         PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
766
767                         iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
768                         iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
769                         PHY_DEBUG(("[CAL]    ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
770                         iqcal_tone_i, iqcal_tone_q));
771                         if (capture_time == 0)
772                                 continue;
773                         else {
774                                 iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
775                                 iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
776                         }
777                 }
778
779                 iqcal_tone_i = iqcal_tone_i_avg;
780                 iqcal_tone_q = iqcal_tone_q_avg;
781
782
783                 rot_i_b = (iqcal_tone_i * iqcal_tone_i0 +
784                                    iqcal_tone_q * iqcal_tone_q0) / 1024;
785                 rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) +
786                                    iqcal_tone_q * iqcal_tone_i0) / 1024;
787                 PHY_DEBUG(("[CAL]    ** rot_i_b = %d, rot_q_b = %d\n",
788                                    rot_i_b, rot_q_b));
789
790                 /* f. */
791                 divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
792
793                 if (divisor == 0) {
794                         PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
795                         PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
796                         PHY_DEBUG(("[CAL] ******************************************\n"));
797                         break;
798                 }
799
800                 a_2 = (rot_i_b * 32768) / divisor;
801                 b_2 = (rot_q_b * (-32768)) / divisor;
802                 PHY_DEBUG(("[CAL]    ***** EPSILON/2 = %d\n", a_2));
803                 PHY_DEBUG(("[CAL]    ***** THETA/2   = %d\n", b_2));
804
805                 phw_data->iq_rsdl_gain_tx_d2 = a_2;
806                 phw_data->iq_rsdl_phase_tx_d2 = b_2;
807
808                 /* if ((abs(a_2) < 150) && (abs(b_2) < 100)) */
809                 /* if ((abs(a_2) < 200) && (abs(b_2) < 200)) */
810                 if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold)) {
811                         verify_count++;
812
813                         PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
814                         PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
815                         PHY_DEBUG(("[CAL] ******************************************\n"));
816
817                         if (verify_count > 2) {
818                                 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
819                                 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
820                                 PHY_DEBUG(("[CAL] **************************************\n"));
821                                 return 0;
822                         }
823
824                         continue;
825                 } else
826                         verify_count = 0;
827
828                 _sin_cos(b_2, &sin_b, &cos_b);
829                 _sin_cos(b_2*2, &sin_2b, &cos_2b);
830                 PHY_DEBUG(("[CAL]    ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
831                 PHY_DEBUG(("[CAL]    ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
832
833                 if (cos_2b == 0) {
834                         PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
835                         PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
836                         PHY_DEBUG(("[CAL] ******************************************\n"));
837                         break;
838                 }
839
840                 /* 1280 * 32768 = 41943040 */
841                 temp1 = (41943040/cos_2b)*cos_b;
842
843                 /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
844                 if (phw_data->revision == 0x2002) /* 1st-cut */
845                         temp2 = (41943040/cos_2b)*sin_b*(-1);
846                 else /* 2nd-cut */
847                         temp2 = (41943040*4/cos_2b)*sin_b*(-1);
848
849                 tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
850                 tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
851                 tx_cal_flt_b[2] = _floor(temp2/(32768-a_2));
852                 tx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
853                 PHY_DEBUG(("[CAL]    ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0]));
854                 PHY_DEBUG(("[CAL]       tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1]));
855                 PHY_DEBUG(("[CAL]       tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2]));
856                 PHY_DEBUG(("[CAL]       tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
857
858                 tx_cal[2] = tx_cal_flt_b[2];
859                 tx_cal[2] = tx_cal[2] + 3;
860                 tx_cal[1] = tx_cal[2];
861                 tx_cal[3] = tx_cal_flt_b[3] - 128;
862                 tx_cal[0] = -tx_cal[3] + 1;
863
864                 PHY_DEBUG(("[CAL]       tx_cal[0] = %d\n", tx_cal[0]));
865                 PHY_DEBUG(("[CAL]       tx_cal[1] = %d\n", tx_cal[1]));
866                 PHY_DEBUG(("[CAL]       tx_cal[2] = %d\n", tx_cal[2]));
867                 PHY_DEBUG(("[CAL]       tx_cal[3] = %d\n", tx_cal[3]));
868
869                 /* if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
870                       (tx_cal[2] == 0) && (tx_cal[3] == 0))
871                   { */
872                 /*    PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
873                  *    PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
874                  *    PHY_DEBUG(("[CAL] ******************************************\n"));
875                  *    return 0;
876                   } */
877
878                 /* g. */
879                 if (phw_data->revision == 0x2002) /* 1st-cut */{
880                         hw_get_dxx_reg(phw_data, 0x54, &val);
881                         PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
882                         tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
883                         tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
884                         tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
885                         tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
886                 } else /* 2nd-cut */{
887                         hw_get_dxx_reg(phw_data, 0x3C, &val);
888                         PHY_DEBUG(("[CAL]    ** 0x3C = 0x%08X\n", val));
889                         tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
890                         tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
891                         tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
892                         tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
893
894                 }
895
896                 PHY_DEBUG(("[CAL]    ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
897                 PHY_DEBUG(("[CAL]       tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
898                 PHY_DEBUG(("[CAL]       tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
899                 PHY_DEBUG(("[CAL]       tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
900
901                 if (phw_data->revision == 0x2002) /* 1st-cut */{
902                         if (((tx_cal_reg[0] == 7) || (tx_cal_reg[0] == (-8))) &&
903                                 ((tx_cal_reg[3] == 7) || (tx_cal_reg[3] == (-8)))) {
904                                 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
905                                 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
906                                 PHY_DEBUG(("[CAL] **************************************\n"));
907                                 break;
908                         }
909                 } else /* 2nd-cut */{
910                         if (((tx_cal_reg[0] == 31) || (tx_cal_reg[0] == (-32))) &&
911                                 ((tx_cal_reg[3] == 31) || (tx_cal_reg[3] == (-32)))) {
912                                 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
913                                 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
914                                 PHY_DEBUG(("[CAL] **************************************\n"));
915                                 break;
916                         }
917                 }
918
919                 tx_cal[0] = tx_cal[0] + tx_cal_reg[0];
920                 tx_cal[1] = tx_cal[1] + tx_cal_reg[1];
921                 tx_cal[2] = tx_cal[2] + tx_cal_reg[2];
922                 tx_cal[3] = tx_cal[3] + tx_cal_reg[3];
923                 PHY_DEBUG(("[CAL]    ** apply tx_cal[0] = %d\n", tx_cal[0]));
924                 PHY_DEBUG(("[CAL]       apply tx_cal[1] = %d\n", tx_cal[1]));
925                 PHY_DEBUG(("[CAL]       apply tx_cal[2] = %d\n", tx_cal[2]));
926                 PHY_DEBUG(("[CAL]       apply tx_cal[3] = %d\n", tx_cal[3]));
927
928                 if (phw_data->revision == 0x2002) /* 1st-cut */{
929                         val &= 0x0000FFFF;
930                         val |= ((_s32_to_s4(tx_cal[0]) << 28)|
931                                         (_s32_to_s4(tx_cal[1]) << 24)|
932                                         (_s32_to_s4(tx_cal[2]) << 20)|
933                                         (_s32_to_s4(tx_cal[3]) << 16));
934                         hw_set_dxx_reg(phw_data, 0x54, val);
935                         PHY_DEBUG(("[CAL]    ** CALIB_DATA = 0x%08X\n", val));
936                         return 0;
937                 } else /* 2nd-cut */{
938                         val &= 0x000003FF;
939                         val |= ((_s32_to_s5(tx_cal[0]) << 27)|
940                                         (_s32_to_s6(tx_cal[1]) << 21)|
941                                         (_s32_to_s6(tx_cal[2]) << 15)|
942                                         (_s32_to_s5(tx_cal[3]) << 10));
943                         hw_set_dxx_reg(phw_data, 0x3C, val);
944                         PHY_DEBUG(("[CAL]    ** TX_IQ_CALIBRATION = 0x%08X\n", val));
945                         return 0;
946                 }
947
948                 /* i. Set "calib_start" to 0x0 */
949                 reg_mode_ctrl &= ~MASK_CALIB_START;
950                 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
951                 PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
952
953                 loop--;
954         }
955
956         return 1;
957 }
958
959 void _tx_iq_calibration_winbond(struct hw_data *phw_data)
960 {
961         u32     reg_agc_ctrl3;
962 #ifdef _DEBUG
963         s32     tx_cal_reg[4];
964
965 #endif
966         u32     reg_mode_ctrl;
967         u32     val;
968         u8      result;
969
970         PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
971
972         /* 0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
973         phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
974         /* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
975         phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); /* 20060612.1.a 0x1905D6); */
976         /* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
977         phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); /* 0x24C60A (high temperature) */
978         /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
979         phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); /* 20060612.1.a 0x06890C); */
980         /* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
981         phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
982         /* ; [BB-chip]: Calibration (6f).Send test pattern */
983         /* ; [BB-chip]: Calibration (6g). Search RXGCL optimal value */
984         /* ; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table */
985         /* phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); */
986
987         msleep(30); /* 20060612.1.a 30ms delay. Add the follow 2 lines */
988         /* To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750 */
989         adjust_TXVGA_for_iq_mag(phw_data);
990
991         /* a. Disable AGC */
992         hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
993         reg_agc_ctrl3 &= ~BIT(2);
994         reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
995         hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
996
997         hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
998         val |= MASK_AGC_FIX_GAIN;
999         hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
1000
1001         result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
1002
1003         if (result > 0) {
1004                 if (phw_data->revision == 0x2002) /* 1st-cut */{
1005                         hw_get_dxx_reg(phw_data, 0x54, &val);
1006                         val &= 0x0000FFFF;
1007                         hw_set_dxx_reg(phw_data, 0x54, val);
1008                 } else /* 2nd-cut*/{
1009                         hw_get_dxx_reg(phw_data, 0x3C, &val);
1010                         val &= 0x000003FF;
1011                         hw_set_dxx_reg(phw_data, 0x3C, val);
1012                 }
1013
1014                 result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
1015
1016                 if (result > 0) {
1017                         if (phw_data->revision == 0x2002) /* 1st-cut */{
1018                                 hw_get_dxx_reg(phw_data, 0x54, &val);
1019                                 val &= 0x0000FFFF;
1020                                 hw_set_dxx_reg(phw_data, 0x54, val);
1021                         } else /* 2nd-cut*/{
1022                                 hw_get_dxx_reg(phw_data, 0x3C, &val);
1023                                 val &= 0x000003FF;
1024                                 hw_set_dxx_reg(phw_data, 0x3C, val);
1025                         }
1026
1027                         result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
1028                         if (result > 0) {
1029                                 if (phw_data->revision == 0x2002) /* 1st-cut */{
1030                                         hw_get_dxx_reg(phw_data, 0x54, &val);
1031                                         val &= 0x0000FFFF;
1032                                         hw_set_dxx_reg(phw_data, 0x54, val);
1033                                 } else /* 2nd-cut */{
1034                                         hw_get_dxx_reg(phw_data, 0x3C, &val);
1035                                         val &= 0x000003FF;
1036                                         hw_set_dxx_reg(phw_data, 0x3C, val);
1037                                 }
1038
1039
1040                                 result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
1041
1042                                 if (result > 0) {
1043                                         PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
1044                                         PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
1045                                         PHY_DEBUG(("[CAL] **************************************\n"));
1046
1047                                         if (phw_data->revision == 0x2002) /* 1st-cut */{
1048                                                 hw_get_dxx_reg(phw_data, 0x54, &val);
1049                                                 val &= 0x0000FFFF;
1050                                                 hw_set_dxx_reg(phw_data, 0x54, val);
1051                                         } else /* 2nd-cut */{
1052                                                 hw_get_dxx_reg(phw_data, 0x3C, &val);
1053                                                 val &= 0x000003FF;
1054                                                 hw_set_dxx_reg(phw_data, 0x3C, val);
1055                                         }
1056                                 }
1057                         }
1058                 }
1059         }
1060
1061         /* i. Set "calib_start" to 0x0 */
1062         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1063         reg_mode_ctrl &= ~MASK_CALIB_START;
1064         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1065         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1066
1067         /* g. Enable AGC */
1068         /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
1069         reg_agc_ctrl3 |= BIT(2);
1070         reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
1071         hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
1072
1073 #ifdef _DEBUG
1074         if (phw_data->revision == 0x2002) /* 1st-cut */{
1075                 hw_get_dxx_reg(phw_data, 0x54, &val);
1076                 PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
1077                 tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
1078                 tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
1079                 tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
1080                 tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
1081         } else /* 2nd-cut */ {
1082                 hw_get_dxx_reg(phw_data, 0x3C, &val);
1083                 PHY_DEBUG(("[CAL]    ** 0x3C = 0x%08X\n", val));
1084                 tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1085                 tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1086                 tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1087                 tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1088
1089         }
1090
1091         PHY_DEBUG(("[CAL]    ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
1092         PHY_DEBUG(("[CAL]       tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
1093         PHY_DEBUG(("[CAL]       tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
1094         PHY_DEBUG(("[CAL]       tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
1095 #endif
1096
1097
1098         /*
1099          * for test - BEN
1100          * RF Control Override
1101          */
1102 }
1103
1104 /*****************************************************/
1105 u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
1106 {
1107         u32     reg_mode_ctrl;
1108         s32     iqcal_tone_i;
1109         s32     iqcal_tone_q;
1110         s32     iqcal_image_i;
1111         s32     iqcal_image_q;
1112         s32     rot_tone_i_b;
1113         s32     rot_tone_q_b;
1114         s32     rot_image_i_b;
1115         s32     rot_image_q_b;
1116         s32     rx_cal_flt_b[4];
1117         s32     rx_cal[4];
1118         s32     rx_cal_reg[4];
1119         s32     a_2, b_2;
1120         s32     sin_b, sin_2b;
1121         s32     cos_b, cos_2b;
1122         s32     temp1, temp2;
1123         u32     val;
1124         u16     loop;
1125
1126         u32     pwr_tone;
1127         u32     pwr_image;
1128         u8      verify_count;
1129
1130         s32     iqcal_tone_i_avg, iqcal_tone_q_avg;
1131         s32     iqcal_image_i_avg, iqcal_image_q_avg;
1132         u16     capture_time;
1133
1134         PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
1135         PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
1136
1137         hw_set_dxx_reg(phw_data, 0x58, 0x44444444); /* IQ_Alpha */
1138
1139         /* b. */
1140
1141         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1142         PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1143
1144         verify_count = 0;
1145
1146         /* for (loop = 0; loop < 1; loop++) */
1147         /* for (loop = 0; loop < LOOP_TIMES; loop++) */
1148         loop = LOOP_TIMES;
1149         while (loop > 0) {
1150                 PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
1151                 iqcal_tone_i_avg = 0;
1152                 iqcal_tone_q_avg = 0;
1153                 iqcal_image_i_avg = 0;
1154                 iqcal_image_q_avg = 0;
1155                 capture_time = 0;
1156
1157                 for (capture_time = 0; capture_time < 10; capture_time++) {
1158                 /* i. Set "calib_start" to 0x0 */
1159                 reg_mode_ctrl &= ~MASK_CALIB_START;
1160                 if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */
1161                         return 0;
1162                 PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1163
1164                 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1165                 reg_mode_ctrl |= (MASK_CALIB_START|0x1);
1166                 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1167                 PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1168
1169                 /* c. */
1170                 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1171                 PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
1172
1173                 iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
1174                 iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1175                 PHY_DEBUG(("[CAL]    ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
1176                                    iqcal_tone_i, iqcal_tone_q));
1177
1178                 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
1179                 PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
1180
1181                 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
1182                 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1183                 PHY_DEBUG(("[CAL]    ** iqcal_image_i = %d, iqcal_image_q = %d\n",
1184                                    iqcal_image_i, iqcal_image_q));
1185                         if (capture_time == 0)
1186                                 continue;
1187                         else {
1188                                 iqcal_image_i_avg = (iqcal_image_i_avg*(capture_time-1) + iqcal_image_i)/capture_time;
1189                                 iqcal_image_q_avg = (iqcal_image_q_avg*(capture_time-1) + iqcal_image_q)/capture_time;
1190                                 iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
1191                                 iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
1192                         }
1193                 }
1194
1195
1196                 iqcal_image_i = iqcal_image_i_avg;
1197                 iqcal_image_q = iqcal_image_q_avg;
1198                 iqcal_tone_i = iqcal_tone_i_avg;
1199                 iqcal_tone_q = iqcal_tone_q_avg;
1200
1201                 /* d. */
1202                 rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
1203                                                 iqcal_tone_q * iqcal_tone_q) / 1024;
1204                 rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
1205                                                 iqcal_tone_q * iqcal_tone_i) / 1024;
1206                 rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
1207                                                  iqcal_image_q * iqcal_tone_q) / 1024;
1208                 rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
1209                                                  iqcal_image_q * iqcal_tone_i) / 1024;
1210
1211                 PHY_DEBUG(("[CAL]    ** rot_tone_i_b  = %d\n", rot_tone_i_b));
1212                 PHY_DEBUG(("[CAL]    ** rot_tone_q_b  = %d\n", rot_tone_q_b));
1213                 PHY_DEBUG(("[CAL]    ** rot_image_i_b = %d\n", rot_image_i_b));
1214                 PHY_DEBUG(("[CAL]    ** rot_image_q_b = %d\n", rot_image_q_b));
1215
1216                 /* f. */
1217                 if (rot_tone_i_b == 0) {
1218                         PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1219                         PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
1220                         PHY_DEBUG(("[CAL] ******************************************\n"));
1221                         break;
1222                 }
1223
1224                 a_2 = (rot_image_i_b * 32768) / rot_tone_i_b -
1225                         phw_data->iq_rsdl_gain_tx_d2;
1226                 b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
1227                         phw_data->iq_rsdl_phase_tx_d2;
1228
1229                 PHY_DEBUG(("[CAL]    ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
1230                 PHY_DEBUG(("[CAL]    ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
1231                 PHY_DEBUG(("[CAL]    ***** EPSILON/2 = %d\n", a_2));
1232                 PHY_DEBUG(("[CAL]    ***** THETA/2   = %d\n", b_2));
1233
1234                 _sin_cos(b_2, &sin_b, &cos_b);
1235                 _sin_cos(b_2*2, &sin_2b, &cos_2b);
1236                 PHY_DEBUG(("[CAL]    ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
1237                 PHY_DEBUG(("[CAL]    ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
1238
1239                 if (cos_2b == 0) {
1240                         PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1241                         PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
1242                         PHY_DEBUG(("[CAL] ******************************************\n"));
1243                         break;
1244                 }
1245
1246                 /* 1280 * 32768 = 41943040 */
1247                 temp1 = (41943040/cos_2b)*cos_b;
1248
1249                 /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
1250                 if (phw_data->revision == 0x2002)/* 1st-cut */
1251                         temp2 = (41943040/cos_2b)*sin_b*(-1);
1252                 else/* 2nd-cut */
1253                         temp2 = (41943040*4/cos_2b)*sin_b*(-1);
1254
1255                 rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
1256                 rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
1257                 rx_cal_flt_b[2] = _floor(temp2/(32768+a_2));
1258                 rx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
1259
1260                 PHY_DEBUG(("[CAL]    ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0]));
1261                 PHY_DEBUG(("[CAL]       rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1]));
1262                 PHY_DEBUG(("[CAL]       rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2]));
1263                 PHY_DEBUG(("[CAL]       rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3]));
1264
1265                 rx_cal[0] = rx_cal_flt_b[0] - 128;
1266                 rx_cal[1] = rx_cal_flt_b[1];
1267                 rx_cal[2] = rx_cal_flt_b[2];
1268                 rx_cal[3] = rx_cal_flt_b[3] - 128;
1269                 PHY_DEBUG(("[CAL]    ** rx_cal[0] = %d\n", rx_cal[0]));
1270                 PHY_DEBUG(("[CAL]       rx_cal[1] = %d\n", rx_cal[1]));
1271                 PHY_DEBUG(("[CAL]       rx_cal[2] = %d\n", rx_cal[2]));
1272                 PHY_DEBUG(("[CAL]       rx_cal[3] = %d\n", rx_cal[3]));
1273
1274                 /* e. */
1275                 pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
1276                 pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
1277
1278                 PHY_DEBUG(("[CAL]    ** pwr_tone  = %d\n", pwr_tone));
1279                 PHY_DEBUG(("[CAL]    ** pwr_image  = %d\n", pwr_image));
1280
1281                 if (pwr_tone > pwr_image) {
1282                         verify_count++;
1283
1284                         PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
1285                         PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
1286                         PHY_DEBUG(("[CAL] ******************************************\n"));
1287
1288                         if (verify_count > 2) {
1289                                 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1290                                 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
1291                                 PHY_DEBUG(("[CAL] **************************************\n"));
1292                                 return 0;
1293                         }
1294
1295                         continue;
1296                 }
1297                 /* g. */
1298                 hw_get_dxx_reg(phw_data, 0x54, &val);
1299                 PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
1300
1301                 if (phw_data->revision == 0x2002) /* 1st-cut */{
1302                         rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1303                         rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >>  8);
1304                         rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >>  4);
1305                         rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1306                 } else /* 2nd-cut */{
1307                         rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1308                         rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1309                         rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1310                         rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1311                 }
1312
1313                 PHY_DEBUG(("[CAL]    ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1314                 PHY_DEBUG(("[CAL]       rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1315                 PHY_DEBUG(("[CAL]       rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1316                 PHY_DEBUG(("[CAL]       rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1317
1318                 if (phw_data->revision == 0x2002) /* 1st-cut */{
1319                         if (((rx_cal_reg[0] == 7) || (rx_cal_reg[0] == (-8))) &&
1320                                 ((rx_cal_reg[3] == 7) || (rx_cal_reg[3] == (-8)))) {
1321                                 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1322                                 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1323                                 PHY_DEBUG(("[CAL] **************************************\n"));
1324                                 break;
1325                         }
1326                 } else /* 2nd-cut */{
1327                         if (((rx_cal_reg[0] == 31) || (rx_cal_reg[0] == (-32))) &&
1328                                 ((rx_cal_reg[3] == 31) || (rx_cal_reg[3] == (-32)))) {
1329                                 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1330                                 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1331                                 PHY_DEBUG(("[CAL] **************************************\n"));
1332                                 break;
1333                         }
1334                 }
1335
1336                 rx_cal[0] = rx_cal[0] + rx_cal_reg[0];
1337                 rx_cal[1] = rx_cal[1] + rx_cal_reg[1];
1338                 rx_cal[2] = rx_cal[2] + rx_cal_reg[2];
1339                 rx_cal[3] = rx_cal[3] + rx_cal_reg[3];
1340                 PHY_DEBUG(("[CAL]    ** apply rx_cal[0] = %d\n", rx_cal[0]));
1341                 PHY_DEBUG(("[CAL]       apply rx_cal[1] = %d\n", rx_cal[1]));
1342                 PHY_DEBUG(("[CAL]       apply rx_cal[2] = %d\n", rx_cal[2]));
1343                 PHY_DEBUG(("[CAL]       apply rx_cal[3] = %d\n", rx_cal[3]));
1344
1345                 hw_get_dxx_reg(phw_data, 0x54, &val);
1346                 if (phw_data->revision == 0x2002) /* 1st-cut */{
1347                         val &= 0x0000FFFF;
1348                         val |= ((_s32_to_s4(rx_cal[0]) << 12)|
1349                                         (_s32_to_s4(rx_cal[1]) <<  8)|
1350                                         (_s32_to_s4(rx_cal[2]) <<  4)|
1351                                         (_s32_to_s4(rx_cal[3])));
1352                         hw_set_dxx_reg(phw_data, 0x54, val);
1353                 } else /* 2nd-cut */{
1354                         val &= 0x000003FF;
1355                         val |= ((_s32_to_s5(rx_cal[0]) << 27)|
1356                                         (_s32_to_s6(rx_cal[1]) << 21)|
1357                                         (_s32_to_s6(rx_cal[2]) << 15)|
1358                                         (_s32_to_s5(rx_cal[3]) << 10));
1359                         hw_set_dxx_reg(phw_data, 0x54, val);
1360
1361                         if (loop == 3)
1362                         return 0;
1363                 }
1364                 PHY_DEBUG(("[CAL]    ** CALIB_DATA = 0x%08X\n", val));
1365
1366                 loop--;
1367         }
1368
1369         return 1;
1370 }
1371
1372 /*************************************************/
1373
1374 /***************************************************************/
1375 void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1376 {
1377 /* figo 20050523 marked this flag for can't compile for relesase */
1378 #ifdef _DEBUG
1379         s32     rx_cal_reg[4];
1380         u32     val;
1381 #endif
1382
1383         u8      result;
1384
1385         PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
1386 /* a. Set RFIC to "RX calibration mode" */
1387         /* ; ----- Calibration (7). RX path IQ imbalance calibration loop */
1388         /*      0x01 0xFFBFC2  ; 3FEFF  ; Calibration (7a). enable RX IQ calibration loop circuits */
1389         phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
1390         /*      0x0B 0x1A01D6  ; 06817  ; Calibration (7b). enable RX I/Q cal loop SW1 circuits */
1391         phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
1392         /* 0x05 0x24848A  ; 09212  ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized */
1393         phy_set_rf_data(phw_data, 5, (5<<24) | phw_data->txvga_setting_for_cal);
1394         /* 0x06 0x06840C  ; 01A10  ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized */
1395         phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
1396         /* 0x00 0xFFF1C0  ; 3F7C7  ; Calibration (7e). turn on IQ imbalance/Test mode */
1397         phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
1398
1399         /*  ; [BB-chip]: Calibration (7f). Send test pattern */
1400         /*      ; [BB-chip]: Calibration (7g). Search RXGCL optimal value */
1401         /*      ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table */
1402
1403         result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
1404
1405         if (result > 0) {
1406                 _reset_rx_cal(phw_data);
1407                 result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
1408
1409                 if (result > 0) {
1410                         _reset_rx_cal(phw_data);
1411                         result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
1412
1413                         if (result > 0) {
1414                                 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
1415                                 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
1416                                 PHY_DEBUG(("[CAL] **************************************\n"));
1417                                 _reset_rx_cal(phw_data);
1418                         }
1419                 }
1420         }
1421
1422 #ifdef _DEBUG
1423         hw_get_dxx_reg(phw_data, 0x54, &val);
1424         PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
1425
1426         if (phw_data->revision == 0x2002) /* 1st-cut */{
1427                 rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1428                 rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >>  8);
1429                 rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >>  4);
1430                 rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1431         } else /* 2nd-cut */{
1432                 rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1433                 rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1434                 rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1435                 rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1436         }
1437
1438         PHY_DEBUG(("[CAL]    ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1439         PHY_DEBUG(("[CAL]       rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1440         PHY_DEBUG(("[CAL]       rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1441         PHY_DEBUG(("[CAL]       rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1442 #endif
1443
1444 }
1445
1446 /*******************************************************/
1447 void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1448 {
1449         u32     reg_mode_ctrl;
1450         u32     iq_alpha;
1451
1452         PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
1453
1454         hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
1455
1456         _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
1457         /* _txidac_dc_offset_cancellation_winbond(phw_data); */
1458         /* _txqdac_dc_offset_cacellation_winbond(phw_data); */
1459
1460         _tx_iq_calibration_winbond(phw_data);
1461         _rx_iq_calibration_winbond(phw_data, frequency);
1462
1463         /*********************************************************************/
1464         hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1465         reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); /* set when finish */
1466         hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1467         PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1468
1469         /* i. Set RFIC to "Normal mode" */
1470         hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
1471
1472         /*********************************************************************/
1473         phy_init_rf(phw_data);
1474
1475 }
1476
1477 /******************/
1478 void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value)
1479 {
1480    u32 ltmp = 0;
1481
1482     switch (pHwData->phy_type) {
1483     case RF_MAXIM_2825:
1484     case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */
1485             ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1486             break;
1487
1488     case RF_MAXIM_2827:
1489             ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1490             break;
1491
1492     case RF_MAXIM_2828:
1493             ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1494             break;
1495
1496     case RF_MAXIM_2829:
1497             ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1498             break;
1499
1500     case RF_AIROHA_2230:
1501     case RF_AIROHA_2230S: /* 20060420 Add this */
1502             ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20);
1503             break;
1504
1505     case RF_AIROHA_7230:
1506             ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
1507             break;
1508
1509     case RF_WB_242:
1510     case RF_WB_242_1:/* 20060619.5 Add */
1511             ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24);
1512             break;
1513     }
1514
1515         Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
1516 }
1517
1518 /* 20060717 modify as Bruce's mail */
1519 unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
1520 {
1521         int init_txvga = 0;
1522         u32     reg_mode_ctrl;
1523         u32     val;
1524         s32     iqcal_tone_i0;
1525         s32     iqcal_tone_q0;
1526         u32     sqsum;
1527         s32     iq_mag_0_tx;
1528         u8      reg_state;
1529         int     current_txvga;
1530
1531
1532         reg_state = 0;
1533         for (init_txvga = 0; init_txvga < 10; init_txvga++) {
1534                 current_txvga = (0x24C40A|(init_txvga<<6));
1535                 phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga));
1536                 phw_data->txvga_setting_for_cal = current_txvga;
1537
1538                 msleep(30);/* 20060612.1.a */
1539
1540                 if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl))/* 20060718.1 modify */
1541                         return false;
1542
1543                 PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1544
1545                 /*
1546                  * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1547                  *    enable "IQ alibration Mode II"
1548                  */
1549                 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
1550                 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1551                 reg_mode_ctrl |= (MASK_CALIB_START|0x02);
1552                 reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
1553                 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1554                 PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1555
1556                 udelay(1);/* 20060612.1.a */
1557
1558                 udelay(300);/* 20060612.1.a */
1559
1560                 /* b. */
1561                 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1562
1563                 PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
1564                 udelay(300);/* 20060612.1.a */
1565
1566                 iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
1567                 iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
1568                 PHY_DEBUG(("[CAL]    ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
1569                                    iqcal_tone_i0, iqcal_tone_q0));
1570
1571                 sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
1572                 iq_mag_0_tx = (s32) _sqrt(sqsum);
1573                 PHY_DEBUG(("[CAL]    ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
1574
1575                 if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1576                         break;
1577                 else if (iq_mag_0_tx > 1750) {
1578                         init_txvga = -2;
1579                         continue;
1580                 } else
1581                         continue;
1582
1583         }
1584
1585         if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1586                 return true;
1587         else
1588                 return false;
1589 }