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