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