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