2 * phy_302_calibration.c
4 * Copyright (C) 2002, 2005 Winbond Electronics Corp.
7 * ---------------------------------------------------------------------------
8 * 0.01.001, 2003-04-16, Kevin created
12 /****************** INCLUDE FILES SECTION ***********************************/
14 #include "phy_calibration.h"
18 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
20 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
22 #define US 1000/* MICROSECOND*/
24 #define AG_CONST 0.6072529350
25 #define FIXED(X) ((s32)((X) * 32768.0))
26 #define DEG2RAD(X) 0.017453 * (X)
28 static const s32 Angles[] = {
29 FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)),
30 FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
31 FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
32 FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
35 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
38 * void _phy_rf_write_delay(struct hw_data *phw_data);
39 * void phy_init_rf(struct hw_data *phw_data);
42 /****************** FUNCTION DEFINITION SECTION *****************************/
44 s32 _s13_to_s32(u32 data)
48 val = (data & 0x0FFF);
50 if ((data & BIT(12)) != 0)
56 u32 _s32_to_s13(s32 data)
62 else if (data < -4096)
70 /****************************************************************************/
71 s32 _s4_to_s32(u32 data)
75 val = (data & 0x0007);
77 if ((data & BIT(3)) != 0)
83 u32 _s32_to_s4(s32 data)
97 /****************************************************************************/
98 s32 _s5_to_s32(u32 data)
102 val = (data & 0x000F);
104 if ((data & BIT(4)) != 0)
110 u32 _s32_to_s5(s32 data)
124 /****************************************************************************/
125 s32 _s6_to_s32(u32 data)
129 val = (data & 0x001F);
131 if ((data & BIT(5)) != 0)
137 u32 _s32_to_s6(s32 data)
151 /****************************************************************************/
152 s32 _s9_to_s32(u32 data)
158 if ((data & BIT(8)) != 0)
164 u32 _s32_to_s9(s32 data)
170 else if (data < -256)
178 /****************************************************************************/
189 /****************************************************************************/
191 * The following code is sqare-root function.
192 * sqsum is the input and the output is sq_rt;
193 * The maximum of sqsum = 2^27 -1;
199 int g0, g1, g2, g3, g4;
204 g4 = sqsum / 100000000;
205 g3 = (sqsum - g4*100000000) / 1000000;
206 g2 = (sqsum - g4*100000000 - g3*1000000) / 10000;
207 g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100;
208 g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
213 while (((seed+1)*(step+1)) <= next) {
218 sq_rt = seed * 10000;
219 next = (next-(seed*step))*100 + g3;
222 seed = 2 * seed * 10;
223 while (((seed+1)*(step+1)) <= next) {
228 sq_rt = sq_rt + step * 1000;
229 next = (next - seed * step) * 100 + g2;
230 seed = (seed + step) * 10;
232 while (((seed+1)*(step+1)) <= next) {
237 sq_rt = sq_rt + step * 100;
238 next = (next - seed * step) * 100 + g1;
239 seed = (seed + step) * 10;
242 while (((seed+1)*(step+1)) <= next) {
247 sq_rt = sq_rt + step * 10;
248 next = (next - seed * step) * 100 + g0;
249 seed = (seed + step) * 10;
252 while (((seed+1)*(step+1)) <= next) {
257 sq_rt = sq_rt + step;
262 /****************************************************************************/
263 void _sin_cos(s32 angle, s32 *sin, s32 *cos)
265 s32 X, Y, TargetAngle, CurrAngle;
268 X = FIXED(AG_CONST); /* AG_CONST * cos(0) */
269 Y = 0; /* AG_CONST * sin(0) */
270 TargetAngle = abs(angle);
273 for (Step = 0; Step < 12; Step++) {
276 if (TargetAngle > CurrAngle) {
277 NewX = X - (Y >> Step);
280 CurrAngle += Angles[Step];
282 NewX = X + (Y >> Step);
283 Y = -(X >> Step) + Y;
285 CurrAngle -= Angles[Step];
298 static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue)
302 return Wb35Reg_ReadSync(pHwData, number, pValue);
304 #define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
306 static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
312 ret = Wb35Reg_WriteSync(pHwData, number, value);
315 #define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
318 void _reset_rx_cal(struct hw_data *phw_data)
322 hw_get_dxx_reg(phw_data, 0x54, &val);
324 if (phw_data->revision == 0x2002) /* 1st-cut */
329 hw_set_dxx_reg(phw_data, 0x54, val);
333 /**************for winbond calibration*********/
337 /**********************************************/
338 void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
345 PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
346 phy_init_rf(phw_data);
348 /* set calibration channel */
349 if ((RF_WB_242 == phw_data->phy_type) ||
350 (RF_WB_242_1 == phw_data->phy_type)) /* 20060619.5 Add */{
351 if ((frequency >= 2412) && (frequency <= 2484)) {
352 /* w89rf242 change frequency to 2390Mhz */
353 PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
354 phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
361 /* reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
362 hw_get_dxx_reg(phw_data, 0x5C, &val);
364 hw_set_dxx_reg(phw_data, 0x5C, val);
366 /* reset the TX and RX IQ calibration data */
367 hw_set_dxx_reg(phw_data, 0x3C, 0);
368 hw_set_dxx_reg(phw_data, 0x54, 0);
370 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
373 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
374 reg_agc_ctrl3 &= ~BIT(2);
375 reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
376 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
378 hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
379 val |= MASK_AGC_FIX_GAIN;
380 hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
382 /* b. Turn off BB RX */
383 hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_a_acq_ctrl);
384 reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
385 hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
387 hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, ®_b_acq_ctrl);
388 reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
389 hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
391 /* c. Make sure MAC is in receiving mode
392 * d. Turn ON ADC calibration
393 * - ADC calibrator is triggered by this signal rising from 0 to 1 */
394 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
395 val &= ~MASK_ADC_DC_CAL_STR;
396 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
398 val |= MASK_ADC_DC_CAL_STR;
399 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
401 /* e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */
403 hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val);
404 PHY_DEBUG(("[CAL] REG_OFFSET_READ = 0x%08X\n", val));
406 PHY_DEBUG(("[CAL] ** adc_dc_cal_i = %d (0x%04X)\n",
407 _s9_to_s32(val&0x000001FF), val&0x000001FF));
408 PHY_DEBUG(("[CAL] ** adc_dc_cal_q = %d (0x%04X)\n",
409 _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9));
412 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
413 val &= ~MASK_ADC_DC_CAL_STR;
414 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
416 /* f. Turn on BB RX */
417 /* hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_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, ®_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);
426 /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
427 reg_agc_ctrl3 |= BIT(2);
428 reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
429 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
432 /****************************************************************/
433 void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
443 s32 fix_cancel_dc_i = 0;
447 PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
449 /* a. Set to "TX calibration mode" */
451 /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
452 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
453 /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
454 phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
455 /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
456 phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
457 /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
458 phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
459 /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */
460 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
462 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
465 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
466 reg_agc_ctrl3 &= ~BIT(2);
467 reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
468 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
470 hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
471 val |= MASK_AGC_FIX_GAIN;
472 hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
474 /* b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 */
475 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
477 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
478 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
481 /* reg_mode_ctrl |= (MASK_CALIB_START|2); */
484 /* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */
487 reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2));
488 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
489 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
491 hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel);
492 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
494 for (loop = 0; loop < LOOP_TIMES; loop++) {
495 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
497 /* c. reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
498 reg_dc_cancel &= ~(0x03FF);
499 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
500 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
502 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
503 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
505 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
506 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
507 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
508 mag_0 = (s32) _sqrt(sqsum);
509 PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
510 mag_0, iqcal_image_i, iqcal_image_q));
513 reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
514 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
515 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
517 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
518 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
520 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
521 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
522 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
523 mag_1 = (s32) _sqrt(sqsum);
524 PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
525 mag_1, iqcal_image_i, iqcal_image_q));
527 /* e. Calculate the correct DC offset cancellation value for I */
529 fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
532 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
536 PHY_DEBUG(("[CAL] ** fix_cancel_dc_i = %d (0x%04X)\n",
537 fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
539 if ((abs(mag_1-mag_0)*6) > mag_0)
546 reg_dc_cancel &= ~(0x03FF);
547 reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT);
548 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
549 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
552 reg_mode_ctrl &= ~MASK_CALIB_START;
553 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
554 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
557 /*****************************************************/
558 void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
568 s32 fix_cancel_dc_q = 0;
572 PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
573 /*0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
574 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
575 /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
576 phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
577 /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
578 phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
579 /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
580 phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
581 /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */
582 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
584 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
587 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
588 reg_agc_ctrl3 &= ~BIT(2);
589 reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
590 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
592 hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
593 val |= MASK_AGC_FIX_GAIN;
594 hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
596 /* a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 */
597 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
598 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
600 /* reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); */
601 reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
602 reg_mode_ctrl |= (MASK_CALIB_START|3);
603 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
604 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
606 hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel);
607 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
609 for (loop = 0; loop < LOOP_TIMES; loop++) {
610 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
612 /* b. reset cancel_dc_q[4:0] in register DC_Cancel */
613 reg_dc_cancel &= ~(0x001F);
614 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
615 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
617 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
618 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
620 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
621 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
622 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
623 mag_0 = _sqrt(sqsum);
624 PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
625 mag_0, iqcal_image_i, iqcal_image_q));
628 reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
629 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
630 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
632 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
633 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
635 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
636 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
637 sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
638 mag_1 = _sqrt(sqsum);
639 PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
640 mag_1, iqcal_image_i, iqcal_image_q));
642 /* d. Calculate the correct DC offset cancellation value for I */
644 fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
647 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
651 PHY_DEBUG(("[CAL] ** fix_cancel_dc_q = %d (0x%04X)\n",
652 fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
654 if ((abs(mag_1-mag_0)*6) > mag_0)
661 reg_dc_cancel &= ~(0x001F);
662 reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT);
663 hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
664 PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
668 reg_mode_ctrl &= ~MASK_CALIB_START;
669 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
670 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
673 /* 20060612.1.a 20060718.1 Modify */
674 u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
697 s32 iqcal_tone_i_avg, iqcal_tone_q_avg;
701 PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
702 PHY_DEBUG(("[CAL] ** a_2_threshold = %d\n", a_2_threshold));
703 PHY_DEBUG(("[CAL] ** b_2_threshold = %d\n", b_2_threshold));
707 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
708 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
713 PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
715 iqcal_tone_i_avg = 0;
716 iqcal_tone_q_avg = 0;
717 if (!hw_set_dxx_reg(phw_data, 0x3C, 0x00)) /* 20060718.1 modify */
719 for (capture_time = 0; capture_time < 10; capture_time++) {
721 * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
722 * enable "IQ alibration Mode II"
724 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
725 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
726 reg_mode_ctrl |= (MASK_CALIB_START|0x02);
727 reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
728 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
729 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
732 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
733 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
735 iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
736 iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
737 PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
738 iqcal_tone_i0, iqcal_tone_q0));
740 sqsum = iqcal_tone_i0*iqcal_tone_i0 +
741 iqcal_tone_q0*iqcal_tone_q0;
742 iq_mag_0_tx = (s32) _sqrt(sqsum);
743 PHY_DEBUG(("[CAL] ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
745 /* c. Set "calib_start" to 0x0 */
746 reg_mode_ctrl &= ~MASK_CALIB_START;
747 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
748 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
751 * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
752 * enable "IQ alibration Mode II"
754 /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
755 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
756 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
757 reg_mode_ctrl |= (MASK_CALIB_START|0x03);
758 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
759 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
762 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
763 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
765 iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
766 iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
767 PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
768 iqcal_tone_i, iqcal_tone_q));
769 if (capture_time == 0)
772 iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
773 iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
777 iqcal_tone_i = iqcal_tone_i_avg;
778 iqcal_tone_q = iqcal_tone_q_avg;
781 rot_i_b = (iqcal_tone_i * iqcal_tone_i0 +
782 iqcal_tone_q * iqcal_tone_q0) / 1024;
783 rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) +
784 iqcal_tone_q * iqcal_tone_i0) / 1024;
785 PHY_DEBUG(("[CAL] ** rot_i_b = %d, rot_q_b = %d\n",
789 divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
792 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
793 PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
794 PHY_DEBUG(("[CAL] ******************************************\n"));
798 a_2 = (rot_i_b * 32768) / divisor;
799 b_2 = (rot_q_b * (-32768)) / divisor;
800 PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
801 PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
803 phw_data->iq_rsdl_gain_tx_d2 = a_2;
804 phw_data->iq_rsdl_phase_tx_d2 = b_2;
806 /* if ((abs(a_2) < 150) && (abs(b_2) < 100)) */
807 /* if ((abs(a_2) < 200) && (abs(b_2) < 200)) */
808 if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold)) {
811 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
812 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
813 PHY_DEBUG(("[CAL] ******************************************\n"));
815 if (verify_count > 2) {
816 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
817 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
818 PHY_DEBUG(("[CAL] **************************************\n"));
826 _sin_cos(b_2, &sin_b, &cos_b);
827 _sin_cos(b_2*2, &sin_2b, &cos_2b);
828 PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
829 PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
832 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
833 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
834 PHY_DEBUG(("[CAL] ******************************************\n"));
838 /* 1280 * 32768 = 41943040 */
839 temp1 = (41943040/cos_2b)*cos_b;
841 /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
842 if (phw_data->revision == 0x2002) /* 1st-cut */
843 temp2 = (41943040/cos_2b)*sin_b*(-1);
845 temp2 = (41943040*4/cos_2b)*sin_b*(-1);
847 tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
848 tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
849 tx_cal_flt_b[2] = _floor(temp2/(32768-a_2));
850 tx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
851 PHY_DEBUG(("[CAL] ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0]));
852 PHY_DEBUG(("[CAL] tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1]));
853 PHY_DEBUG(("[CAL] tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2]));
854 PHY_DEBUG(("[CAL] tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
856 tx_cal[2] = tx_cal_flt_b[2];
857 tx_cal[2] = tx_cal[2] + 3;
858 tx_cal[1] = tx_cal[2];
859 tx_cal[3] = tx_cal_flt_b[3] - 128;
860 tx_cal[0] = -tx_cal[3] + 1;
862 PHY_DEBUG(("[CAL] tx_cal[0] = %d\n", tx_cal[0]));
863 PHY_DEBUG(("[CAL] tx_cal[1] = %d\n", tx_cal[1]));
864 PHY_DEBUG(("[CAL] tx_cal[2] = %d\n", tx_cal[2]));
865 PHY_DEBUG(("[CAL] tx_cal[3] = %d\n", tx_cal[3]));
867 /* if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
868 (tx_cal[2] == 0) && (tx_cal[3] == 0))
870 /* PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
871 * PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
872 * PHY_DEBUG(("[CAL] ******************************************\n"));
877 if (phw_data->revision == 0x2002) /* 1st-cut */{
878 hw_get_dxx_reg(phw_data, 0x54, &val);
879 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
880 tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
881 tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
882 tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
883 tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
884 } else /* 2nd-cut */{
885 hw_get_dxx_reg(phw_data, 0x3C, &val);
886 PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
887 tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
888 tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
889 tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
890 tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
894 PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
895 PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
896 PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
897 PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
899 if (phw_data->revision == 0x2002) /* 1st-cut */{
900 if (((tx_cal_reg[0] == 7) || (tx_cal_reg[0] == (-8))) &&
901 ((tx_cal_reg[3] == 7) || (tx_cal_reg[3] == (-8)))) {
902 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
903 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
904 PHY_DEBUG(("[CAL] **************************************\n"));
907 } else /* 2nd-cut */{
908 if (((tx_cal_reg[0] == 31) || (tx_cal_reg[0] == (-32))) &&
909 ((tx_cal_reg[3] == 31) || (tx_cal_reg[3] == (-32)))) {
910 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
911 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
912 PHY_DEBUG(("[CAL] **************************************\n"));
917 tx_cal[0] = tx_cal[0] + tx_cal_reg[0];
918 tx_cal[1] = tx_cal[1] + tx_cal_reg[1];
919 tx_cal[2] = tx_cal[2] + tx_cal_reg[2];
920 tx_cal[3] = tx_cal[3] + tx_cal_reg[3];
921 PHY_DEBUG(("[CAL] ** apply tx_cal[0] = %d\n", tx_cal[0]));
922 PHY_DEBUG(("[CAL] apply tx_cal[1] = %d\n", tx_cal[1]));
923 PHY_DEBUG(("[CAL] apply tx_cal[2] = %d\n", tx_cal[2]));
924 PHY_DEBUG(("[CAL] apply tx_cal[3] = %d\n", tx_cal[3]));
926 if (phw_data->revision == 0x2002) /* 1st-cut */{
928 val |= ((_s32_to_s4(tx_cal[0]) << 28)|
929 (_s32_to_s4(tx_cal[1]) << 24)|
930 (_s32_to_s4(tx_cal[2]) << 20)|
931 (_s32_to_s4(tx_cal[3]) << 16));
932 hw_set_dxx_reg(phw_data, 0x54, val);
933 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
935 } else /* 2nd-cut */{
937 val |= ((_s32_to_s5(tx_cal[0]) << 27)|
938 (_s32_to_s6(tx_cal[1]) << 21)|
939 (_s32_to_s6(tx_cal[2]) << 15)|
940 (_s32_to_s5(tx_cal[3]) << 10));
941 hw_set_dxx_reg(phw_data, 0x3C, val);
942 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION = 0x%08X\n", val));
946 /* i. Set "calib_start" to 0x0 */
947 reg_mode_ctrl &= ~MASK_CALIB_START;
948 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
949 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
957 void _tx_iq_calibration_winbond(struct hw_data *phw_data)
968 PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
970 /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
971 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
972 /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
973 phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); /* 20060612.1.a 0x1905D6); */
974 /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
975 phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); /* 0x24C60A (high temperature) */
976 /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
977 phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); /* 20060612.1.a 0x06890C); */
978 /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */
979 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
980 /* ; [BB-chip]: Calibration (6f).Send test pattern */
981 /* ; [BB-chip]: Calibration (6g). Search RXGCL optimal value */
982 /* ; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table */
983 /* phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); */
985 msleep(30); /* 20060612.1.a 30ms delay. Add the follow 2 lines */
986 /* To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750 */
987 adjust_TXVGA_for_iq_mag(phw_data);
990 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
991 reg_agc_ctrl3 &= ~BIT(2);
992 reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
993 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
995 hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
996 val |= MASK_AGC_FIX_GAIN;
997 hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
999 result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
1002 if (phw_data->revision == 0x2002) /* 1st-cut */{
1003 hw_get_dxx_reg(phw_data, 0x54, &val);
1005 hw_set_dxx_reg(phw_data, 0x54, val);
1006 } else /* 2nd-cut*/{
1007 hw_get_dxx_reg(phw_data, 0x3C, &val);
1009 hw_set_dxx_reg(phw_data, 0x3C, val);
1012 result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
1015 if (phw_data->revision == 0x2002) /* 1st-cut */{
1016 hw_get_dxx_reg(phw_data, 0x54, &val);
1018 hw_set_dxx_reg(phw_data, 0x54, val);
1019 } else /* 2nd-cut*/{
1020 hw_get_dxx_reg(phw_data, 0x3C, &val);
1022 hw_set_dxx_reg(phw_data, 0x3C, val);
1025 result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
1027 if (phw_data->revision == 0x2002) /* 1st-cut */{
1028 hw_get_dxx_reg(phw_data, 0x54, &val);
1030 hw_set_dxx_reg(phw_data, 0x54, val);
1031 } else /* 2nd-cut */{
1032 hw_get_dxx_reg(phw_data, 0x3C, &val);
1034 hw_set_dxx_reg(phw_data, 0x3C, val);
1038 result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
1041 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
1042 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
1043 PHY_DEBUG(("[CAL] **************************************\n"));
1045 if (phw_data->revision == 0x2002) /* 1st-cut */{
1046 hw_get_dxx_reg(phw_data, 0x54, &val);
1048 hw_set_dxx_reg(phw_data, 0x54, val);
1049 } else /* 2nd-cut */{
1050 hw_get_dxx_reg(phw_data, 0x3C, &val);
1052 hw_set_dxx_reg(phw_data, 0x3C, val);
1059 /* i. Set "calib_start" to 0x0 */
1060 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
1061 reg_mode_ctrl &= ~MASK_CALIB_START;
1062 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1063 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1066 /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
1067 reg_agc_ctrl3 |= BIT(2);
1068 reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
1069 hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
1072 if (phw_data->revision == 0x2002) /* 1st-cut */{
1073 hw_get_dxx_reg(phw_data, 0x54, &val);
1074 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1075 tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
1076 tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
1077 tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
1078 tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
1079 } else /* 2nd-cut */ {
1080 hw_get_dxx_reg(phw_data, 0x3C, &val);
1081 PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
1082 tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1083 tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1084 tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1085 tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1089 PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
1090 PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
1091 PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
1092 PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
1098 * RF Control Override
1102 /*****************************************************/
1103 u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
1114 s32 rx_cal_flt_b[4];
1128 s32 iqcal_tone_i_avg, iqcal_tone_q_avg;
1129 s32 iqcal_image_i_avg, iqcal_image_q_avg;
1132 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
1133 PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
1135 hw_set_dxx_reg(phw_data, 0x58, 0x44444444); /* IQ_Alpha */
1139 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
1140 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1144 /* for (loop = 0; loop < 1; loop++) */
1145 /* for (loop = 0; loop < LOOP_TIMES; loop++) */
1148 PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
1149 iqcal_tone_i_avg = 0;
1150 iqcal_tone_q_avg = 0;
1151 iqcal_image_i_avg = 0;
1152 iqcal_image_q_avg = 0;
1155 for (capture_time = 0; capture_time < 10; capture_time++) {
1156 /* i. Set "calib_start" to 0x0 */
1157 reg_mode_ctrl &= ~MASK_CALIB_START;
1158 if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */
1160 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1162 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1163 reg_mode_ctrl |= (MASK_CALIB_START|0x1);
1164 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1165 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1168 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1169 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1171 iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
1172 iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1173 PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
1174 iqcal_tone_i, iqcal_tone_q));
1176 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
1177 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
1179 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
1180 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1181 PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n",
1182 iqcal_image_i, iqcal_image_q));
1183 if (capture_time == 0)
1186 iqcal_image_i_avg = (iqcal_image_i_avg*(capture_time-1) + iqcal_image_i)/capture_time;
1187 iqcal_image_q_avg = (iqcal_image_q_avg*(capture_time-1) + iqcal_image_q)/capture_time;
1188 iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
1189 iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
1194 iqcal_image_i = iqcal_image_i_avg;
1195 iqcal_image_q = iqcal_image_q_avg;
1196 iqcal_tone_i = iqcal_tone_i_avg;
1197 iqcal_tone_q = iqcal_tone_q_avg;
1200 rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
1201 iqcal_tone_q * iqcal_tone_q) / 1024;
1202 rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
1203 iqcal_tone_q * iqcal_tone_i) / 1024;
1204 rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
1205 iqcal_image_q * iqcal_tone_q) / 1024;
1206 rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
1207 iqcal_image_q * iqcal_tone_i) / 1024;
1209 PHY_DEBUG(("[CAL] ** rot_tone_i_b = %d\n", rot_tone_i_b));
1210 PHY_DEBUG(("[CAL] ** rot_tone_q_b = %d\n", rot_tone_q_b));
1211 PHY_DEBUG(("[CAL] ** rot_image_i_b = %d\n", rot_image_i_b));
1212 PHY_DEBUG(("[CAL] ** rot_image_q_b = %d\n", rot_image_q_b));
1215 if (rot_tone_i_b == 0) {
1216 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1217 PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
1218 PHY_DEBUG(("[CAL] ******************************************\n"));
1222 a_2 = (rot_image_i_b * 32768) / rot_tone_i_b -
1223 phw_data->iq_rsdl_gain_tx_d2;
1224 b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
1225 phw_data->iq_rsdl_phase_tx_d2;
1227 PHY_DEBUG(("[CAL] ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
1228 PHY_DEBUG(("[CAL] ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
1229 PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
1230 PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
1232 _sin_cos(b_2, &sin_b, &cos_b);
1233 _sin_cos(b_2*2, &sin_2b, &cos_2b);
1234 PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
1235 PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
1238 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1239 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
1240 PHY_DEBUG(("[CAL] ******************************************\n"));
1244 /* 1280 * 32768 = 41943040 */
1245 temp1 = (41943040/cos_2b)*cos_b;
1247 /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
1248 if (phw_data->revision == 0x2002)/* 1st-cut */
1249 temp2 = (41943040/cos_2b)*sin_b*(-1);
1251 temp2 = (41943040*4/cos_2b)*sin_b*(-1);
1253 rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
1254 rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
1255 rx_cal_flt_b[2] = _floor(temp2/(32768+a_2));
1256 rx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
1258 PHY_DEBUG(("[CAL] ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0]));
1259 PHY_DEBUG(("[CAL] rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1]));
1260 PHY_DEBUG(("[CAL] rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2]));
1261 PHY_DEBUG(("[CAL] rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3]));
1263 rx_cal[0] = rx_cal_flt_b[0] - 128;
1264 rx_cal[1] = rx_cal_flt_b[1];
1265 rx_cal[2] = rx_cal_flt_b[2];
1266 rx_cal[3] = rx_cal_flt_b[3] - 128;
1267 PHY_DEBUG(("[CAL] ** rx_cal[0] = %d\n", rx_cal[0]));
1268 PHY_DEBUG(("[CAL] rx_cal[1] = %d\n", rx_cal[1]));
1269 PHY_DEBUG(("[CAL] rx_cal[2] = %d\n", rx_cal[2]));
1270 PHY_DEBUG(("[CAL] rx_cal[3] = %d\n", rx_cal[3]));
1273 pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
1274 pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
1276 PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone));
1277 PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image));
1279 if (pwr_tone > pwr_image) {
1282 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
1283 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
1284 PHY_DEBUG(("[CAL] ******************************************\n"));
1286 if (verify_count > 2) {
1287 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1288 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
1289 PHY_DEBUG(("[CAL] **************************************\n"));
1296 hw_get_dxx_reg(phw_data, 0x54, &val);
1297 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1299 if (phw_data->revision == 0x2002) /* 1st-cut */{
1300 rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1301 rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
1302 rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
1303 rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1304 } else /* 2nd-cut */{
1305 rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1306 rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1307 rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1308 rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1311 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1312 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1313 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1314 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1316 if (phw_data->revision == 0x2002) /* 1st-cut */{
1317 if (((rx_cal_reg[0] == 7) || (rx_cal_reg[0] == (-8))) &&
1318 ((rx_cal_reg[3] == 7) || (rx_cal_reg[3] == (-8)))) {
1319 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1320 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1321 PHY_DEBUG(("[CAL] **************************************\n"));
1324 } else /* 2nd-cut */{
1325 if (((rx_cal_reg[0] == 31) || (rx_cal_reg[0] == (-32))) &&
1326 ((rx_cal_reg[3] == 31) || (rx_cal_reg[3] == (-32)))) {
1327 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1328 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1329 PHY_DEBUG(("[CAL] **************************************\n"));
1334 rx_cal[0] = rx_cal[0] + rx_cal_reg[0];
1335 rx_cal[1] = rx_cal[1] + rx_cal_reg[1];
1336 rx_cal[2] = rx_cal[2] + rx_cal_reg[2];
1337 rx_cal[3] = rx_cal[3] + rx_cal_reg[3];
1338 PHY_DEBUG(("[CAL] ** apply rx_cal[0] = %d\n", rx_cal[0]));
1339 PHY_DEBUG(("[CAL] apply rx_cal[1] = %d\n", rx_cal[1]));
1340 PHY_DEBUG(("[CAL] apply rx_cal[2] = %d\n", rx_cal[2]));
1341 PHY_DEBUG(("[CAL] apply rx_cal[3] = %d\n", rx_cal[3]));
1343 hw_get_dxx_reg(phw_data, 0x54, &val);
1344 if (phw_data->revision == 0x2002) /* 1st-cut */{
1346 val |= ((_s32_to_s4(rx_cal[0]) << 12)|
1347 (_s32_to_s4(rx_cal[1]) << 8)|
1348 (_s32_to_s4(rx_cal[2]) << 4)|
1349 (_s32_to_s4(rx_cal[3])));
1350 hw_set_dxx_reg(phw_data, 0x54, val);
1351 } else /* 2nd-cut */{
1353 val |= ((_s32_to_s5(rx_cal[0]) << 27)|
1354 (_s32_to_s6(rx_cal[1]) << 21)|
1355 (_s32_to_s6(rx_cal[2]) << 15)|
1356 (_s32_to_s5(rx_cal[3]) << 10));
1357 hw_set_dxx_reg(phw_data, 0x54, val);
1362 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
1370 /*************************************************/
1372 /***************************************************************/
1373 void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1375 /* figo 20050523 marked this flag for can't compile for relesase */
1383 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
1384 /* a. Set RFIC to "RX calibration mode" */
1385 /* ; ----- Calibration (7). RX path IQ imbalance calibration loop */
1386 /* 0x01 0xFFBFC2 ; 3FEFF ; Calibration (7a). enable RX IQ calibration loop circuits */
1387 phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
1388 /* 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuits */
1389 phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
1390 /* 0x05 0x24848A ; 09212 ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized */
1391 phy_set_rf_data(phw_data, 5, (5<<24) | phw_data->txvga_setting_for_cal);
1392 /* 0x06 0x06840C ; 01A10 ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized */
1393 phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
1394 /* 0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode */
1395 phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
1397 /* ; [BB-chip]: Calibration (7f). Send test pattern */
1398 /* ; [BB-chip]: Calibration (7g). Search RXGCL optimal value */
1399 /* ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table */
1401 result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
1404 _reset_rx_cal(phw_data);
1405 result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
1408 _reset_rx_cal(phw_data);
1409 result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
1412 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
1413 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
1414 PHY_DEBUG(("[CAL] **************************************\n"));
1415 _reset_rx_cal(phw_data);
1421 hw_get_dxx_reg(phw_data, 0x54, &val);
1422 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1424 if (phw_data->revision == 0x2002) /* 1st-cut */{
1425 rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1426 rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
1427 rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
1428 rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1429 } else /* 2nd-cut */{
1430 rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1431 rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1432 rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1433 rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1436 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1437 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1438 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1439 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1444 /*******************************************************/
1445 void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1450 PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
1452 hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
1454 _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
1455 /* _txidac_dc_offset_cancellation_winbond(phw_data); */
1456 /* _txqdac_dc_offset_cacellation_winbond(phw_data); */
1458 _tx_iq_calibration_winbond(phw_data);
1459 _rx_iq_calibration_winbond(phw_data, frequency);
1461 /*********************************************************************/
1462 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
1463 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); /* set when finish */
1464 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1465 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1467 /* i. Set RFIC to "Normal mode" */
1468 hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
1470 /*********************************************************************/
1471 phy_init_rf(phw_data);
1475 /******************/
1476 void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value)
1480 switch (pHwData->phy_type) {
1482 case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */
1483 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1487 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1491 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1495 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1498 case RF_AIROHA_2230:
1499 case RF_AIROHA_2230S: /* 20060420 Add this */
1500 ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20);
1503 case RF_AIROHA_7230:
1504 ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
1508 case RF_WB_242_1:/* 20060619.5 Add */
1509 ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24);
1513 Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
1516 /* 20060717 modify as Bruce's mail */
1517 unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
1531 for (init_txvga = 0; init_txvga < 10; init_txvga++) {
1532 current_txvga = (0x24C40A|(init_txvga<<6));
1533 phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga));
1534 phw_data->txvga_setting_for_cal = current_txvga;
1536 msleep(30);/* 20060612.1.a */
1538 if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl))/* 20060718.1 modify */
1541 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1544 * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1545 * enable "IQ alibration Mode II"
1547 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
1548 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1549 reg_mode_ctrl |= (MASK_CALIB_START|0x02);
1550 reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
1551 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1552 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1554 udelay(1);/* 20060612.1.a */
1556 udelay(300);/* 20060612.1.a */
1559 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1561 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1562 udelay(300);/* 20060612.1.a */
1564 iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
1565 iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
1566 PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
1567 iqcal_tone_i0, iqcal_tone_q0));
1569 sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
1570 iq_mag_0_tx = (s32) _sqrt(sqsum);
1571 PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
1573 if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1575 else if (iq_mag_0_tx > 1750) {
1583 if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)