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