Staging: add w35und wifi driver
[linux-2.6/mini2440.git] / drivers / staging / winbond / phy_calibration.c
blob272a65066aba050523b8780e5fd4b424d36fd44d
1 /*
2 * phy_302_calibration.c
4 * Copyright (C) 2002, 2005 Winbond Electronics Corp.
6 * modification history
7 * ---------------------------------------------------------------------------
8 * 0.01.001, 2003-04-16, Kevin created
12 /****************** INCLUDE FILES SECTION ***********************************/
13 #include "os_common.h"
14 #include "phy_calibration.h"
17 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
19 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
20 #define LOOP_TIMES 20
21 #define US 1000//MICROSECOND
23 #define AG_CONST 0.6072529350
24 #define FIXED(X) ((s32)((X) * 32768.0))
25 #define DEG2RAD(X) 0.017453 * (X)
27 /****************** LOCAL TYPE DEFINITION SECTION ***************************/
28 typedef s32 fixed; /* 16.16 fixed-point */
30 static const fixed Angles[]=
32 FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)),
33 FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
34 FIXED(DEG2RAD(0.895174)),FIXED(DEG2RAD(0.447614)),FIXED(DEG2RAD(0.223811)),
35 FIXED(DEG2RAD(0.111906)),FIXED(DEG2RAD(0.055953)),FIXED(DEG2RAD(0.027977))
38 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
39 //void _phy_rf_write_delay(hw_data_t *phw_data);
40 //void phy_init_rf(hw_data_t *phw_data);
42 /****************** FUNCTION DEFINITION SECTION *****************************/
44 s32 _s13_to_s32(u32 data)
46 u32 val;
48 val = (data & 0x0FFF);
50 if ((data & BIT(12)) != 0)
52 val |= 0xFFFFF000;
55 return ((s32) val);
58 u32 _s32_to_s13(s32 data)
60 u32 val;
62 if (data > 4095)
64 data = 4095;
66 else if (data < -4096)
68 data = -4096;
71 val = data & 0x1FFF;
73 return val;
76 /****************************************************************************/
77 s32 _s4_to_s32(u32 data)
79 s32 val;
81 val = (data & 0x0007);
83 if ((data & BIT(3)) != 0)
85 val |= 0xFFFFFFF8;
88 return val;
91 u32 _s32_to_s4(s32 data)
93 u32 val;
95 if (data > 7)
97 data = 7;
99 else if (data < -8)
101 data = -8;
104 val = data & 0x000F;
106 return val;
109 /****************************************************************************/
110 s32 _s5_to_s32(u32 data)
112 s32 val;
114 val = (data & 0x000F);
116 if ((data & BIT(4)) != 0)
118 val |= 0xFFFFFFF0;
121 return val;
124 u32 _s32_to_s5(s32 data)
126 u32 val;
128 if (data > 15)
130 data = 15;
132 else if (data < -16)
134 data = -16;
137 val = data & 0x001F;
139 return val;
142 /****************************************************************************/
143 s32 _s6_to_s32(u32 data)
145 s32 val;
147 val = (data & 0x001F);
149 if ((data & BIT(5)) != 0)
151 val |= 0xFFFFFFE0;
154 return val;
157 u32 _s32_to_s6(s32 data)
159 u32 val;
161 if (data > 31)
163 data = 31;
165 else if (data < -32)
167 data = -32;
170 val = data & 0x003F;
172 return val;
175 /****************************************************************************/
176 s32 _s9_to_s32(u32 data)
178 s32 val;
180 val = data & 0x00FF;
182 if ((data & BIT(8)) != 0)
184 val |= 0xFFFFFF00;
187 return val;
190 u32 _s32_to_s9(s32 data)
192 u32 val;
194 if (data > 255)
196 data = 255;
198 else if (data < -256)
200 data = -256;
203 val = data & 0x01FF;
205 return val;
208 /****************************************************************************/
209 s32 _floor(s32 n)
211 if (n > 0)
213 n += 5;
215 else
217 n -= 5;
220 return (n/10);
223 /****************************************************************************/
224 // The following code is sqare-root function.
225 // sqsum is the input and the output is sq_rt;
226 // The maximum of sqsum = 2^27 -1;
227 u32 _sqrt(u32 sqsum)
229 u32 sq_rt;
231 int g0, g1, g2, g3, g4;
232 int seed;
233 int next;
234 int step;
236 g4 = sqsum / 100000000;
237 g3 = (sqsum - g4*100000000) /1000000;
238 g2 = (sqsum - g4*100000000 - g3*1000000) /10000;
239 g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) /100;
240 g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
242 next = g4;
243 step = 0;
244 seed = 0;
245 while (((seed+1)*(step+1)) <= next)
247 step++;
248 seed++;
251 sq_rt = seed * 10000;
252 next = (next-(seed*step))*100 + g3;
254 step = 0;
255 seed = 2 * seed * 10;
256 while (((seed+1)*(step+1)) <= next)
258 step++;
259 seed++;
262 sq_rt = sq_rt + step * 1000;
263 next = (next - seed * step) * 100 + g2;
264 seed = (seed + step) * 10;
265 step = 0;
266 while (((seed+1)*(step+1)) <= next)
268 step++;
269 seed++;
272 sq_rt = sq_rt + step * 100;
273 next = (next - seed * step) * 100 + g1;
274 seed = (seed + step) * 10;
275 step = 0;
277 while (((seed+1)*(step+1)) <= next)
279 step++;
280 seed++;
283 sq_rt = sq_rt + step * 10;
284 next = (next - seed* step) * 100 + g0;
285 seed = (seed + step) * 10;
286 step = 0;
288 while (((seed+1)*(step+1)) <= next)
290 step++;
291 seed++;
294 sq_rt = sq_rt + step;
296 return sq_rt;
299 /****************************************************************************/
300 void _sin_cos(s32 angle, s32 *sin, s32 *cos)
302 fixed X, Y, TargetAngle, CurrAngle;
303 unsigned Step;
305 X=FIXED(AG_CONST); // AG_CONST * cos(0)
306 Y=0; // AG_CONST * sin(0)
307 TargetAngle=abs(angle);
308 CurrAngle=0;
310 for (Step=0; Step < 12; Step++)
312 fixed NewX;
314 if(TargetAngle > CurrAngle)
316 NewX=X - (Y >> Step);
317 Y=(X >> Step) + Y;
318 X=NewX;
319 CurrAngle += Angles[Step];
321 else
323 NewX=X + (Y >> Step);
324 Y=-(X >> Step) + Y;
325 X=NewX;
326 CurrAngle -= Angles[Step];
330 if (angle > 0)
332 *cos = X;
333 *sin = Y;
335 else
337 *cos = X;
338 *sin = -Y;
343 void _reset_rx_cal(hw_data_t *phw_data)
345 u32 val;
347 hw_get_dxx_reg(phw_data, 0x54, &val);
349 if (phw_data->revision == 0x2002) // 1st-cut
351 val &= 0xFFFF0000;
353 else // 2nd-cut
355 val &= 0x000003FF;
358 hw_set_dxx_reg(phw_data, 0x54, val);
362 // ************for winbond calibration*********
367 // *********************************************
368 void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
370 u32 reg_agc_ctrl3;
371 u32 reg_a_acq_ctrl;
372 u32 reg_b_acq_ctrl;
373 u32 val;
375 PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
376 phy_init_rf(phw_data);
378 // set calibration channel
379 if( (RF_WB_242 == phw_data->phy_type) ||
380 (RF_WB_242_1 == phw_data->phy_type) ) // 20060619.5 Add
382 if ((frequency >= 2412) && (frequency <= 2484))
384 // w89rf242 change frequency to 2390Mhz
385 PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
386 phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
390 else
395 // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
396 hw_get_dxx_reg(phw_data, 0x5C, &val);
397 val &= ~(0x03FF);
398 hw_set_dxx_reg(phw_data, 0x5C, val);
400 // reset the TX and RX IQ calibration data
401 hw_set_dxx_reg(phw_data, 0x3C, 0);
402 hw_set_dxx_reg(phw_data, 0x54, 0);
404 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
406 // a. Disable AGC
407 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
408 reg_agc_ctrl3 &= ~BIT(2);
409 reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
410 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
412 hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
413 val |= MASK_AGC_FIX_GAIN;
414 hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
416 // b. Turn off BB RX
417 hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
418 reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
419 hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
421 hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl);
422 reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
423 hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
425 // c. Make sure MAC is in receiving mode
426 // d. Turn ON ADC calibration
427 // - ADC calibrator is triggered by this signal rising from 0 to 1
428 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
429 val &= ~MASK_ADC_DC_CAL_STR;
430 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
432 val |= MASK_ADC_DC_CAL_STR;
433 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
434 pa_stall_execution(US); // *MUST* wait for a while
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));
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
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);
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);
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);
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);
467 ////////////////////////////////////////////////////////
468 void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
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;
482 PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
484 // a. Set to "TX calibration mode"
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);
497 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
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);
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);
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);
512 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
513 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
515 // mode=2, tone=0
516 //reg_mode_ctrl |= (MASK_CALIB_START|2);
518 // mode=2, tone=1
519 //reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2));
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 pa_stall_execution(US);
527 hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
528 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
530 for (loop = 0; loop < LOOP_TIMES; loop++)
532 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
534 // c.
535 // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
536 reg_dc_cancel &= ~(0x03FF);
537 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
538 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
539 pa_stall_execution(US);
541 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
542 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
544 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
545 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
546 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
547 mag_0 = (s32) _sqrt(sqsum);
548 PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
549 mag_0, iqcal_image_i, iqcal_image_q));
551 // d.
552 reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
553 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
554 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
555 pa_stall_execution(US);
557 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
558 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
560 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
561 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
562 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
563 mag_1 = (s32) _sqrt(sqsum);
564 PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
565 mag_1, iqcal_image_i, iqcal_image_q));
567 // e. Calculate the correct DC offset cancellation value for I
568 if (mag_0 != mag_1)
570 fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
572 else
574 if (mag_0 == mag_1)
576 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
579 fix_cancel_dc_i = 0;
582 PHY_DEBUG(("[CAL] ** fix_cancel_dc_i = %d (0x%04X)\n",
583 fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
585 if ((abs(mag_1-mag_0)*6) > mag_0)
587 break;
591 if ( loop >= 19 )
592 fix_cancel_dc_i = 0;
594 reg_dc_cancel &= ~(0x03FF);
595 reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT);
596 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
597 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
599 // g.
600 reg_mode_ctrl &= ~MASK_CALIB_START;
601 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
602 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
603 pa_stall_execution(US);
606 ///////////////////////////////////////////////////////
607 void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
609 u32 reg_agc_ctrl3;
610 u32 reg_mode_ctrl;
611 u32 reg_dc_cancel;
612 s32 iqcal_image_i;
613 s32 iqcal_image_q;
614 u32 sqsum;
615 s32 mag_0;
616 s32 mag_1;
617 s32 fix_cancel_dc_q = 0;
618 u32 val;
619 int loop;
621 PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
622 //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
623 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
624 //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
625 phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
626 //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
627 phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
628 //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
629 phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
630 //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
631 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
633 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
635 // a. Disable AGC
636 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
637 reg_agc_ctrl3 &= ~BIT(2);
638 reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
639 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
641 hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
642 val |= MASK_AGC_FIX_GAIN;
643 hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
645 // a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0
646 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
647 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
649 //reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
650 reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
651 reg_mode_ctrl |= (MASK_CALIB_START|3);
652 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
653 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
654 pa_stall_execution(US);
656 hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
657 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
659 for (loop = 0; loop < LOOP_TIMES; loop++)
661 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
663 // b.
664 // reset cancel_dc_q[4:0] in register DC_Cancel
665 reg_dc_cancel &= ~(0x001F);
666 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
667 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
668 pa_stall_execution(US);
670 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
671 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
672 pa_stall_execution(US);
674 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
675 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
676 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
677 mag_0 = _sqrt(sqsum);
678 PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
679 mag_0, iqcal_image_i, iqcal_image_q));
681 // c.
682 reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
683 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
684 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
685 pa_stall_execution(US);
687 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
688 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
689 pa_stall_execution(US);
691 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
692 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
693 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
694 mag_1 = _sqrt(sqsum);
695 PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
696 mag_1, iqcal_image_i, iqcal_image_q));
698 // d. Calculate the correct DC offset cancellation value for I
699 if (mag_0 != mag_1)
701 fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
703 else
705 if (mag_0 == mag_1)
707 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
710 fix_cancel_dc_q = 0;
713 PHY_DEBUG(("[CAL] ** fix_cancel_dc_q = %d (0x%04X)\n",
714 fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
716 if ((abs(mag_1-mag_0)*6) > mag_0)
718 break;
722 if ( loop >= 19 )
723 fix_cancel_dc_q = 0;
725 reg_dc_cancel &= ~(0x001F);
726 reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT);
727 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
728 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
731 // f.
732 reg_mode_ctrl &= ~MASK_CALIB_START;
733 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
734 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
735 pa_stall_execution(US);
738 //20060612.1.a 20060718.1 Modify
739 u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
740 s32 a_2_threshold,
741 s32 b_2_threshold)
743 u32 reg_mode_ctrl;
744 s32 iq_mag_0_tx;
745 s32 iqcal_tone_i0;
746 s32 iqcal_tone_q0;
747 s32 iqcal_tone_i;
748 s32 iqcal_tone_q;
749 u32 sqsum;
750 s32 rot_i_b;
751 s32 rot_q_b;
752 s32 tx_cal_flt_b[4];
753 s32 tx_cal[4];
754 s32 tx_cal_reg[4];
755 s32 a_2, b_2;
756 s32 sin_b, sin_2b;
757 s32 cos_b, cos_2b;
758 s32 divisor;
759 s32 temp1, temp2;
760 u32 val;
761 u16 loop;
762 s32 iqcal_tone_i_avg,iqcal_tone_q_avg;
763 u8 verify_count;
764 int capture_time;
766 PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
767 PHY_DEBUG(("[CAL] ** a_2_threshold = %d\n", a_2_threshold));
768 PHY_DEBUG(("[CAL] ** b_2_threshold = %d\n", b_2_threshold));
770 verify_count = 0;
772 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
773 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
775 loop = LOOP_TIMES;
777 while (loop > 0)
779 PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
781 iqcal_tone_i_avg=0;
782 iqcal_tone_q_avg=0;
783 if( !hw_set_dxx_reg(phw_data, 0x3C, 0x00) ) // 20060718.1 modify
784 return 0;
785 for(capture_time=0;capture_time<10;capture_time++)
787 // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
788 // enable "IQ alibration Mode II"
789 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
790 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
791 reg_mode_ctrl |= (MASK_CALIB_START|0x02);
792 reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
793 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
794 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
795 pa_stall_execution(US);
797 // b.
798 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
799 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
800 pa_stall_execution(US);
802 iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
803 iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
804 PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
805 iqcal_tone_i0, iqcal_tone_q0));
807 sqsum = iqcal_tone_i0*iqcal_tone_i0 +
808 iqcal_tone_q0*iqcal_tone_q0;
809 iq_mag_0_tx = (s32) _sqrt(sqsum);
810 PHY_DEBUG(("[CAL] ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
812 // c. Set "calib_start" to 0x0
813 reg_mode_ctrl &= ~MASK_CALIB_START;
814 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
815 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
816 pa_stall_execution(US);
818 // d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
819 // enable "IQ alibration Mode II"
820 //hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
821 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
822 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
823 reg_mode_ctrl |= (MASK_CALIB_START|0x03);
824 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
825 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
826 pa_stall_execution(US);
828 // e.
829 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
830 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
831 pa_stall_execution(US);
833 iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
834 iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
835 PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
836 iqcal_tone_i, iqcal_tone_q));
837 if( capture_time == 0)
839 continue;
841 else
843 iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
844 iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
848 iqcal_tone_i = iqcal_tone_i_avg;
849 iqcal_tone_q = iqcal_tone_q_avg;
852 rot_i_b = (iqcal_tone_i * iqcal_tone_i0 +
853 iqcal_tone_q * iqcal_tone_q0) / 1024;
854 rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) +
855 iqcal_tone_q * iqcal_tone_i0) / 1024;
856 PHY_DEBUG(("[CAL] ** rot_i_b = %d, rot_q_b = %d\n",
857 rot_i_b, rot_q_b));
859 // f.
860 divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
862 if (divisor == 0)
864 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
865 PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
866 PHY_DEBUG(("[CAL] ******************************************\n"));
867 break;
870 a_2 = (rot_i_b * 32768) / divisor;
871 b_2 = (rot_q_b * (-32768)) / divisor;
872 PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
873 PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
875 phw_data->iq_rsdl_gain_tx_d2 = a_2;
876 phw_data->iq_rsdl_phase_tx_d2 = b_2;
878 //if ((abs(a_2) < 150) && (abs(b_2) < 100))
879 //if ((abs(a_2) < 200) && (abs(b_2) < 200))
880 if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold))
882 verify_count++;
884 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
885 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
886 PHY_DEBUG(("[CAL] ******************************************\n"));
888 if (verify_count > 2)
890 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
891 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
892 PHY_DEBUG(("[CAL] **************************************\n"));
893 return 0;
896 continue;
898 else
900 verify_count = 0;
903 _sin_cos(b_2, &sin_b, &cos_b);
904 _sin_cos(b_2*2, &sin_2b, &cos_2b);
905 PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
906 PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
908 if (cos_2b == 0)
910 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
911 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
912 PHY_DEBUG(("[CAL] ******************************************\n"));
913 break;
916 // 1280 * 32768 = 41943040
917 temp1 = (41943040/cos_2b)*cos_b;
919 //temp2 = (41943040/cos_2b)*sin_b*(-1);
920 if (phw_data->revision == 0x2002) // 1st-cut
922 temp2 = (41943040/cos_2b)*sin_b*(-1);
924 else // 2nd-cut
926 temp2 = (41943040*4/cos_2b)*sin_b*(-1);
929 tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
930 tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
931 tx_cal_flt_b[2] = _floor(temp2/(32768-a_2));
932 tx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
933 PHY_DEBUG(("[CAL] ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0]));
934 PHY_DEBUG(("[CAL] tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1]));
935 PHY_DEBUG(("[CAL] tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2]));
936 PHY_DEBUG(("[CAL] tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
938 tx_cal[2] = tx_cal_flt_b[2];
939 tx_cal[2] = tx_cal[2] +3;
940 tx_cal[1] = tx_cal[2];
941 tx_cal[3] = tx_cal_flt_b[3] - 128;
942 tx_cal[0] = -tx_cal[3]+1;
944 PHY_DEBUG(("[CAL] tx_cal[0] = %d\n", tx_cal[0]));
945 PHY_DEBUG(("[CAL] tx_cal[1] = %d\n", tx_cal[1]));
946 PHY_DEBUG(("[CAL] tx_cal[2] = %d\n", tx_cal[2]));
947 PHY_DEBUG(("[CAL] tx_cal[3] = %d\n", tx_cal[3]));
949 //if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
950 // (tx_cal[2] == 0) && (tx_cal[3] == 0))
952 // PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
953 // PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
954 // PHY_DEBUG(("[CAL] ******************************************\n"));
955 // return 0;
958 // g.
959 if (phw_data->revision == 0x2002) // 1st-cut
961 hw_get_dxx_reg(phw_data, 0x54, &val);
962 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
963 tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
964 tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
965 tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
966 tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
968 else // 2nd-cut
970 hw_get_dxx_reg(phw_data, 0x3C, &val);
971 PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
972 tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
973 tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
974 tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
975 tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
979 PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
980 PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
981 PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
982 PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
984 if (phw_data->revision == 0x2002) // 1st-cut
986 if (((tx_cal_reg[0]==7) || (tx_cal_reg[0]==(-8))) &&
987 ((tx_cal_reg[3]==7) || (tx_cal_reg[3]==(-8))))
989 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
990 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
991 PHY_DEBUG(("[CAL] **************************************\n"));
992 break;
995 else // 2nd-cut
997 if (((tx_cal_reg[0]==31) || (tx_cal_reg[0]==(-32))) &&
998 ((tx_cal_reg[3]==31) || (tx_cal_reg[3]==(-32))))
1000 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
1001 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
1002 PHY_DEBUG(("[CAL] **************************************\n"));
1003 break;
1007 tx_cal[0] = tx_cal[0] + tx_cal_reg[0];
1008 tx_cal[1] = tx_cal[1] + tx_cal_reg[1];
1009 tx_cal[2] = tx_cal[2] + tx_cal_reg[2];
1010 tx_cal[3] = tx_cal[3] + tx_cal_reg[3];
1011 PHY_DEBUG(("[CAL] ** apply tx_cal[0] = %d\n", tx_cal[0]));
1012 PHY_DEBUG(("[CAL] apply tx_cal[1] = %d\n", tx_cal[1]));
1013 PHY_DEBUG(("[CAL] apply tx_cal[2] = %d\n", tx_cal[2]));
1014 PHY_DEBUG(("[CAL] apply tx_cal[3] = %d\n", tx_cal[3]));
1016 if (phw_data->revision == 0x2002) // 1st-cut
1018 val &= 0x0000FFFF;
1019 val |= ((_s32_to_s4(tx_cal[0]) << 28)|
1020 (_s32_to_s4(tx_cal[1]) << 24)|
1021 (_s32_to_s4(tx_cal[2]) << 20)|
1022 (_s32_to_s4(tx_cal[3]) << 16));
1023 hw_set_dxx_reg(phw_data, 0x54, val);
1024 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
1025 return 0;
1027 else // 2nd-cut
1029 val &= 0x000003FF;
1030 val |= ((_s32_to_s5(tx_cal[0]) << 27)|
1031 (_s32_to_s6(tx_cal[1]) << 21)|
1032 (_s32_to_s6(tx_cal[2]) << 15)|
1033 (_s32_to_s5(tx_cal[3]) << 10));
1034 hw_set_dxx_reg(phw_data, 0x3C, val);
1035 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION = 0x%08X\n", val));
1036 return 0;
1039 // i. Set "calib_start" to 0x0
1040 reg_mode_ctrl &= ~MASK_CALIB_START;
1041 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1042 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1044 loop--;
1047 return 1;
1050 void _tx_iq_calibration_winbond(hw_data_t *phw_data)
1052 u32 reg_agc_ctrl3;
1053 #ifdef _DEBUG
1054 s32 tx_cal_reg[4];
1056 #endif
1057 u32 reg_mode_ctrl;
1058 u32 val;
1059 u8 result;
1061 PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
1063 //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
1064 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
1065 //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
1066 phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); // 20060612.1.a 0x1905D6);
1067 //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
1068 phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); //0x24C60A (high temperature)
1069 //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
1070 phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); // 20060612.1.a 0x06890C);
1071 //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
1072 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
1073 //; [BB-chip]: Calibration (6f).Send test pattern
1074 //; [BB-chip]: Calibration (6g). Search RXGCL optimal value
1075 //; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table
1076 //phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
1078 OS_SLEEP(30000); // 20060612.1.a 30ms delay. Add the follow 2 lines
1079 //To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750
1080 adjust_TXVGA_for_iq_mag( phw_data );
1082 // a. Disable AGC
1083 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
1084 reg_agc_ctrl3 &= ~BIT(2);
1085 reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
1086 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
1088 hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
1089 val |= MASK_AGC_FIX_GAIN;
1090 hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
1092 result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
1094 if (result > 0)
1096 if (phw_data->revision == 0x2002) // 1st-cut
1098 hw_get_dxx_reg(phw_data, 0x54, &val);
1099 val &= 0x0000FFFF;
1100 hw_set_dxx_reg(phw_data, 0x54, val);
1102 else // 2nd-cut
1104 hw_get_dxx_reg(phw_data, 0x3C, &val);
1105 val &= 0x000003FF;
1106 hw_set_dxx_reg(phw_data, 0x3C, val);
1109 result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
1111 if (result > 0)
1113 if (phw_data->revision == 0x2002) // 1st-cut
1115 hw_get_dxx_reg(phw_data, 0x54, &val);
1116 val &= 0x0000FFFF;
1117 hw_set_dxx_reg(phw_data, 0x54, val);
1119 else // 2nd-cut
1121 hw_get_dxx_reg(phw_data, 0x3C, &val);
1122 val &= 0x000003FF;
1123 hw_set_dxx_reg(phw_data, 0x3C, val);
1126 result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
1127 if (result > 0)
1129 if (phw_data->revision == 0x2002) // 1st-cut
1131 hw_get_dxx_reg(phw_data, 0x54, &val);
1132 val &= 0x0000FFFF;
1133 hw_set_dxx_reg(phw_data, 0x54, val);
1135 else // 2nd-cut
1137 hw_get_dxx_reg(phw_data, 0x3C, &val);
1138 val &= 0x000003FF;
1139 hw_set_dxx_reg(phw_data, 0x3C, val);
1143 result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
1145 if (result > 0)
1147 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
1148 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
1149 PHY_DEBUG(("[CAL] **************************************\n"));
1151 if (phw_data->revision == 0x2002) // 1st-cut
1153 hw_get_dxx_reg(phw_data, 0x54, &val);
1154 val &= 0x0000FFFF;
1155 hw_set_dxx_reg(phw_data, 0x54, val);
1157 else // 2nd-cut
1159 hw_get_dxx_reg(phw_data, 0x3C, &val);
1160 val &= 0x000003FF;
1161 hw_set_dxx_reg(phw_data, 0x3C, val);
1168 // i. Set "calib_start" to 0x0
1169 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1170 reg_mode_ctrl &= ~MASK_CALIB_START;
1171 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1172 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1174 // g. Enable AGC
1175 //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
1176 reg_agc_ctrl3 |= BIT(2);
1177 reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
1178 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
1180 #ifdef _DEBUG
1181 if (phw_data->revision == 0x2002) // 1st-cut
1183 hw_get_dxx_reg(phw_data, 0x54, &val);
1184 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1185 tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
1186 tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
1187 tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
1188 tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
1190 else // 2nd-cut
1192 hw_get_dxx_reg(phw_data, 0x3C, &val);
1193 PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
1194 tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1195 tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1196 tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1197 tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1201 PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
1202 PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
1203 PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
1204 PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
1205 #endif
1208 // for test - BEN
1209 // RF Control Override
1212 /////////////////////////////////////////////////////////////////////////////////////////
1213 u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequency)
1215 u32 reg_mode_ctrl;
1216 s32 iqcal_tone_i;
1217 s32 iqcal_tone_q;
1218 s32 iqcal_image_i;
1219 s32 iqcal_image_q;
1220 s32 rot_tone_i_b;
1221 s32 rot_tone_q_b;
1222 s32 rot_image_i_b;
1223 s32 rot_image_q_b;
1224 s32 rx_cal_flt_b[4];
1225 s32 rx_cal[4];
1226 s32 rx_cal_reg[4];
1227 s32 a_2, b_2;
1228 s32 sin_b, sin_2b;
1229 s32 cos_b, cos_2b;
1230 s32 temp1, temp2;
1231 u32 val;
1232 u16 loop;
1234 u32 pwr_tone;
1235 u32 pwr_image;
1236 u8 verify_count;
1238 s32 iqcal_tone_i_avg,iqcal_tone_q_avg;
1239 s32 iqcal_image_i_avg,iqcal_image_q_avg;
1240 u16 capture_time;
1242 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
1243 PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
1246 // RF Control Override
1247 hw_get_cxx_reg(phw_data, 0x80, &val);
1248 val |= BIT(19);
1249 hw_set_cxx_reg(phw_data, 0x80, val);
1251 // RF_Ctrl
1252 hw_get_cxx_reg(phw_data, 0xE4, &val);
1253 val |= BIT(0);
1254 hw_set_cxx_reg(phw_data, 0xE4, val);
1255 PHY_DEBUG(("[CAL] ** RF_CTRL(0xE4) = 0x%08X", val));
1257 hw_set_dxx_reg(phw_data, 0x58, 0x44444444); // IQ_Alpha
1259 // b.
1261 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1262 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1264 verify_count = 0;
1266 //for (loop = 0; loop < 1; loop++)
1267 //for (loop = 0; loop < LOOP_TIMES; loop++)
1268 loop = LOOP_TIMES;
1269 while (loop > 0)
1271 PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
1272 iqcal_tone_i_avg=0;
1273 iqcal_tone_q_avg=0;
1274 iqcal_image_i_avg=0;
1275 iqcal_image_q_avg=0;
1276 capture_time=0;
1278 for(capture_time=0; capture_time<10; capture_time++)
1280 // i. Set "calib_start" to 0x0
1281 reg_mode_ctrl &= ~MASK_CALIB_START;
1282 if( !hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl) )//20060718.1 modify
1283 return 0;
1284 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1285 pa_stall_execution(US);
1287 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1288 reg_mode_ctrl |= (MASK_CALIB_START|0x1);
1289 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1290 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1291 pa_stall_execution(US); //Should be read out after 450us
1293 // c.
1294 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1295 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1297 iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
1298 iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1299 PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
1300 iqcal_tone_i, iqcal_tone_q));
1302 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
1303 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
1305 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
1306 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1307 PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n",
1308 iqcal_image_i, iqcal_image_q));
1309 if( capture_time == 0)
1311 continue;
1313 else
1315 iqcal_image_i_avg=( iqcal_image_i_avg*(capture_time-1) +iqcal_image_i)/capture_time;
1316 iqcal_image_q_avg=( iqcal_image_q_avg*(capture_time-1) +iqcal_image_q)/capture_time;
1317 iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
1318 iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
1323 iqcal_image_i = iqcal_image_i_avg;
1324 iqcal_image_q = iqcal_image_q_avg;
1325 iqcal_tone_i = iqcal_tone_i_avg;
1326 iqcal_tone_q = iqcal_tone_q_avg;
1328 // d.
1329 rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
1330 iqcal_tone_q * iqcal_tone_q) / 1024;
1331 rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
1332 iqcal_tone_q * iqcal_tone_i) / 1024;
1333 rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
1334 iqcal_image_q * iqcal_tone_q) / 1024;
1335 rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
1336 iqcal_image_q * iqcal_tone_i) / 1024;
1338 PHY_DEBUG(("[CAL] ** rot_tone_i_b = %d\n", rot_tone_i_b));
1339 PHY_DEBUG(("[CAL] ** rot_tone_q_b = %d\n", rot_tone_q_b));
1340 PHY_DEBUG(("[CAL] ** rot_image_i_b = %d\n", rot_image_i_b));
1341 PHY_DEBUG(("[CAL] ** rot_image_q_b = %d\n", rot_image_q_b));
1343 // f.
1344 if (rot_tone_i_b == 0)
1346 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1347 PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
1348 PHY_DEBUG(("[CAL] ******************************************\n"));
1349 break;
1352 a_2 = (rot_image_i_b * 32768) / rot_tone_i_b -
1353 phw_data->iq_rsdl_gain_tx_d2;
1354 b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
1355 phw_data->iq_rsdl_phase_tx_d2;
1357 PHY_DEBUG(("[CAL] ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
1358 PHY_DEBUG(("[CAL] ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
1359 PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
1360 PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
1362 _sin_cos(b_2, &sin_b, &cos_b);
1363 _sin_cos(b_2*2, &sin_2b, &cos_2b);
1364 PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
1365 PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
1367 if (cos_2b == 0)
1369 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1370 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
1371 PHY_DEBUG(("[CAL] ******************************************\n"));
1372 break;
1375 // 1280 * 32768 = 41943040
1376 temp1 = (41943040/cos_2b)*cos_b;
1378 //temp2 = (41943040/cos_2b)*sin_b*(-1);
1379 if (phw_data->revision == 0x2002) // 1st-cut
1381 temp2 = (41943040/cos_2b)*sin_b*(-1);
1383 else // 2nd-cut
1385 temp2 = (41943040*4/cos_2b)*sin_b*(-1);
1388 rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
1389 rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
1390 rx_cal_flt_b[2] = _floor(temp2/(32768+a_2));
1391 rx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
1393 PHY_DEBUG(("[CAL] ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0]));
1394 PHY_DEBUG(("[CAL] rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1]));
1395 PHY_DEBUG(("[CAL] rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2]));
1396 PHY_DEBUG(("[CAL] rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3]));
1398 rx_cal[0] = rx_cal_flt_b[0] - 128;
1399 rx_cal[1] = rx_cal_flt_b[1];
1400 rx_cal[2] = rx_cal_flt_b[2];
1401 rx_cal[3] = rx_cal_flt_b[3] - 128;
1402 PHY_DEBUG(("[CAL] ** rx_cal[0] = %d\n", rx_cal[0]));
1403 PHY_DEBUG(("[CAL] rx_cal[1] = %d\n", rx_cal[1]));
1404 PHY_DEBUG(("[CAL] rx_cal[2] = %d\n", rx_cal[2]));
1405 PHY_DEBUG(("[CAL] rx_cal[3] = %d\n", rx_cal[3]));
1407 // e.
1408 pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
1409 pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
1411 PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone));
1412 PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image));
1414 if (pwr_tone > pwr_image)
1416 verify_count++;
1418 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
1419 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
1420 PHY_DEBUG(("[CAL] ******************************************\n"));
1422 if (verify_count > 2)
1424 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1425 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
1426 PHY_DEBUG(("[CAL] **************************************\n"));
1427 return 0;
1430 continue;
1432 // g.
1433 hw_get_dxx_reg(phw_data, 0x54, &val);
1434 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1436 if (phw_data->revision == 0x2002) // 1st-cut
1438 rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1439 rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
1440 rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
1441 rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1443 else // 2nd-cut
1445 rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1446 rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1447 rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1448 rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1451 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1452 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1453 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1454 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1456 if (phw_data->revision == 0x2002) // 1st-cut
1458 if (((rx_cal_reg[0]==7) || (rx_cal_reg[0]==(-8))) &&
1459 ((rx_cal_reg[3]==7) || (rx_cal_reg[3]==(-8))))
1461 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1462 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1463 PHY_DEBUG(("[CAL] **************************************\n"));
1464 break;
1467 else // 2nd-cut
1469 if (((rx_cal_reg[0]==31) || (rx_cal_reg[0]==(-32))) &&
1470 ((rx_cal_reg[3]==31) || (rx_cal_reg[3]==(-32))))
1472 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1473 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1474 PHY_DEBUG(("[CAL] **************************************\n"));
1475 break;
1479 rx_cal[0] = rx_cal[0] + rx_cal_reg[0];
1480 rx_cal[1] = rx_cal[1] + rx_cal_reg[1];
1481 rx_cal[2] = rx_cal[2] + rx_cal_reg[2];
1482 rx_cal[3] = rx_cal[3] + rx_cal_reg[3];
1483 PHY_DEBUG(("[CAL] ** apply rx_cal[0] = %d\n", rx_cal[0]));
1484 PHY_DEBUG(("[CAL] apply rx_cal[1] = %d\n", rx_cal[1]));
1485 PHY_DEBUG(("[CAL] apply rx_cal[2] = %d\n", rx_cal[2]));
1486 PHY_DEBUG(("[CAL] apply rx_cal[3] = %d\n", rx_cal[3]));
1488 hw_get_dxx_reg(phw_data, 0x54, &val);
1489 if (phw_data->revision == 0x2002) // 1st-cut
1491 val &= 0x0000FFFF;
1492 val |= ((_s32_to_s4(rx_cal[0]) << 12)|
1493 (_s32_to_s4(rx_cal[1]) << 8)|
1494 (_s32_to_s4(rx_cal[2]) << 4)|
1495 (_s32_to_s4(rx_cal[3])));
1496 hw_set_dxx_reg(phw_data, 0x54, val);
1498 else // 2nd-cut
1500 val &= 0x000003FF;
1501 val |= ((_s32_to_s5(rx_cal[0]) << 27)|
1502 (_s32_to_s6(rx_cal[1]) << 21)|
1503 (_s32_to_s6(rx_cal[2]) << 15)|
1504 (_s32_to_s5(rx_cal[3]) << 10));
1505 hw_set_dxx_reg(phw_data, 0x54, val);
1507 if( loop == 3 )
1508 return 0;
1510 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
1512 loop--;
1515 return 1;
1518 //////////////////////////////////////////////////////////
1520 //////////////////////////////////////////////////////////////////////////
1521 void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
1523 // figo 20050523 marked thsi flag for can't compile for relesase
1524 #ifdef _DEBUG
1525 s32 rx_cal_reg[4];
1526 u32 val;
1527 #endif
1529 u8 result;
1531 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
1532 // a. Set RFIC to "RX calibration mode"
1533 //; ----- Calibration (7). RX path IQ imbalance calibration loop
1534 // 0x01 0xFFBFC2 ; 3FEFF ; Calibration (7a). enable RX IQ calibration loop circuits
1535 phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
1536 // 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuit
1537 phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
1538 //0x05 0x24848A ; 09212 ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized
1539 phy_set_rf_data(phw_data, 5, (5<<24)| phw_data->txvga_setting_for_cal);
1540 //0x06 0x06840C ; 01A10 ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized
1541 phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
1542 //0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode
1543 phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
1545 // ; [BB-chip]: Calibration (7f). Send test pattern
1546 // ; [BB-chip]: Calibration (7g). Search RXGCL optimal value
1547 // ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table
1549 result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
1551 if (result > 0)
1553 _reset_rx_cal(phw_data);
1554 result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
1556 if (result > 0)
1558 _reset_rx_cal(phw_data);
1559 result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
1561 if (result > 0)
1563 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
1564 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
1565 PHY_DEBUG(("[CAL] **************************************\n"));
1566 _reset_rx_cal(phw_data);
1571 #ifdef _DEBUG
1572 hw_get_dxx_reg(phw_data, 0x54, &val);
1573 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1575 if (phw_data->revision == 0x2002) // 1st-cut
1577 rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1578 rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
1579 rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
1580 rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1582 else // 2nd-cut
1584 rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1585 rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1586 rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1587 rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1590 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1591 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1592 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1593 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1594 #endif
1598 ////////////////////////////////////////////////////////////////////////
1599 void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
1601 u32 reg_mode_ctrl;
1602 u32 iq_alpha;
1604 PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
1606 // 20040701 1.1.25.1000 kevin
1607 hw_get_cxx_reg(phw_data, 0x80, &mac_ctrl);
1608 hw_get_cxx_reg(phw_data, 0xE4, &rf_ctrl);
1609 hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
1613 _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
1614 //_txidac_dc_offset_cancellation_winbond(phw_data);
1615 //_txqdac_dc_offset_cacellation_winbond(phw_data);
1617 _tx_iq_calibration_winbond(phw_data);
1618 _rx_iq_calibration_winbond(phw_data, frequency);
1620 //------------------------------------------------------------------------
1621 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1622 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); // set when finish
1623 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1624 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1626 // i. Set RFIC to "Normal mode"
1627 hw_set_cxx_reg(phw_data, 0x80, mac_ctrl);
1628 hw_set_cxx_reg(phw_data, 0xE4, rf_ctrl);
1629 hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
1632 //------------------------------------------------------------------------
1633 phy_init_rf(phw_data);
1637 //===========================
1638 void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value )
1640 u32 ltmp=0;
1642 switch( pHwData->phy_type )
1644 case RF_MAXIM_2825:
1645 case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
1646 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
1647 break;
1649 case RF_MAXIM_2827:
1650 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
1651 break;
1653 case RF_MAXIM_2828:
1654 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
1655 break;
1657 case RF_MAXIM_2829:
1658 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
1659 break;
1661 case RF_AIROHA_2230:
1662 case RF_AIROHA_2230S: // 20060420 Add this
1663 ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( value, 20 );
1664 break;
1666 case RF_AIROHA_7230:
1667 ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
1668 break;
1670 case RF_WB_242:
1671 case RF_WB_242_1: // 20060619.5 Add
1672 ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( value, 24 );
1673 break;
1676 Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
1679 // 20060717 modify as Bruce's mail
1680 unsigned char adjust_TXVGA_for_iq_mag(hw_data_t *phw_data)
1682 int init_txvga = 0;
1683 u32 reg_mode_ctrl;
1684 u32 val;
1685 s32 iqcal_tone_i0;
1686 s32 iqcal_tone_q0;
1687 u32 sqsum;
1688 s32 iq_mag_0_tx;
1689 u8 reg_state;
1690 int current_txvga;
1693 reg_state = 0;
1694 for( init_txvga=0; init_txvga<10; init_txvga++)
1696 current_txvga = ( 0x24C40A|(init_txvga<<6) );
1697 phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga) );
1698 phw_data->txvga_setting_for_cal = current_txvga;
1700 //pa_stall_execution(30000);//Sleep(30);
1701 OS_SLEEP(30000); // 20060612.1.a
1703 if( !hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl) ) // 20060718.1 modify
1704 return FALSE;
1706 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1708 // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1709 // enable "IQ alibration Mode II"
1710 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
1711 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1712 reg_mode_ctrl |= (MASK_CALIB_START|0x02);
1713 reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
1714 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1715 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1717 //pa_stall_execution(US);
1718 OS_SLEEP(1); // 20060612.1.a
1720 //pa_stall_execution(300);//Sleep(30);
1721 OS_SLEEP(300); // 20060612.1.a
1723 // b.
1724 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1726 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1727 //pa_stall_execution(US);
1728 //pa_stall_execution(300);//Sleep(30);
1729 OS_SLEEP(300); // 20060612.1.a
1731 iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
1732 iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
1733 PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
1734 iqcal_tone_i0, iqcal_tone_q0));
1736 sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
1737 iq_mag_0_tx = (s32) _sqrt(sqsum);
1738 PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
1740 if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
1741 break;
1742 else if(iq_mag_0_tx > 1750)
1744 init_txvga=-2;
1745 continue;
1747 else
1748 continue;
1752 if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
1753 return TRUE;
1754 else
1755 return FALSE;