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