GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / winbond / phy_calibration.c
blob5c1f05392db98aab24174c25ee60f0f0dfd86d6a
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 "sysdef.h"
14 #include "phy_calibration.h"
15 #include "wbhal_f.h"
18 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
20 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
21 #define LOOP_TIMES 20
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)
46 u32 val;
48 val = (data & 0x0FFF);
50 if ((data & BIT(12)) != 0)
51 val |= 0xFFFFF000;
53 return ((s32) val);
56 u32 _s32_to_s13(s32 data)
58 u32 val;
60 if (data > 4095)
61 data = 4095;
62 else if (data < -4096)
63 data = -4096;
65 val = data & 0x1FFF;
67 return val;
70 /****************************************************************************/
71 s32 _s4_to_s32(u32 data)
73 s32 val;
75 val = (data & 0x0007);
77 if ((data & BIT(3)) != 0)
78 val |= 0xFFFFFFF8;
80 return val;
83 u32 _s32_to_s4(s32 data)
85 u32 val;
87 if (data > 7)
88 data = 7;
89 else if (data < -8)
90 data = -8;
92 val = data & 0x000F;
94 return val;
97 /****************************************************************************/
98 s32 _s5_to_s32(u32 data)
100 s32 val;
102 val = (data & 0x000F);
104 if ((data & BIT(4)) != 0)
105 val |= 0xFFFFFFF0;
107 return val;
110 u32 _s32_to_s5(s32 data)
112 u32 val;
114 if (data > 15)
115 data = 15;
116 else if (data < -16)
117 data = -16;
119 val = data & 0x001F;
121 return val;
124 /****************************************************************************/
125 s32 _s6_to_s32(u32 data)
127 s32 val;
129 val = (data & 0x001F);
131 if ((data & BIT(5)) != 0)
132 val |= 0xFFFFFFE0;
134 return val;
137 u32 _s32_to_s6(s32 data)
139 u32 val;
141 if (data > 31)
142 data = 31;
143 else if (data < -32)
144 data = -32;
146 val = data & 0x003F;
148 return val;
151 /****************************************************************************/
152 s32 _s9_to_s32(u32 data)
154 s32 val;
156 val = data & 0x00FF;
158 if ((data & BIT(8)) != 0)
159 val |= 0xFFFFFF00;
161 return val;
164 u32 _s32_to_s9(s32 data)
166 u32 val;
168 if (data > 255)
169 data = 255;
170 else if (data < -256)
171 data = -256;
173 val = data & 0x01FF;
175 return val;
178 /****************************************************************************/
179 s32 _floor(s32 n)
181 if (n > 0)
182 n += 5;
183 else
184 n -= 5;
186 return (n/10);
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;
195 u32 _sqrt(u32 sqsum)
197 u32 sq_rt;
199 int g0, g1, g2, g3, g4;
200 int seed;
201 int next;
202 int step;
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);
210 next = g4;
211 step = 0;
212 seed = 0;
213 while (((seed+1)*(step+1)) <= next) {
214 step++;
215 seed++;
218 sq_rt = seed * 10000;
219 next = (next-(seed*step))*100 + g3;
221 step = 0;
222 seed = 2 * seed * 10;
223 while (((seed+1)*(step+1)) <= next) {
224 step++;
225 seed++;
228 sq_rt = sq_rt + step * 1000;
229 next = (next - seed * step) * 100 + g2;
230 seed = (seed + step) * 10;
231 step = 0;
232 while (((seed+1)*(step+1)) <= next) {
233 step++;
234 seed++;
237 sq_rt = sq_rt + step * 100;
238 next = (next - seed * step) * 100 + g1;
239 seed = (seed + step) * 10;
240 step = 0;
242 while (((seed+1)*(step+1)) <= next) {
243 step++;
244 seed++;
247 sq_rt = sq_rt + step * 10;
248 next = (next - seed * step) * 100 + g0;
249 seed = (seed + step) * 10;
250 step = 0;
252 while (((seed+1)*(step+1)) <= next) {
253 step++;
254 seed++;
257 sq_rt = sq_rt + step;
259 return sq_rt;
262 /****************************************************************************/
263 void _sin_cos(s32 angle, s32 *sin, s32 *cos)
265 s32 X, Y, TargetAngle, CurrAngle;
266 unsigned Step;
268 X = FIXED(AG_CONST); /* AG_CONST * cos(0) */
269 Y = 0; /* AG_CONST * sin(0) */
270 TargetAngle = abs(angle);
271 CurrAngle = 0;
273 for (Step = 0; Step < 12; Step++) {
274 s32 NewX;
276 if (TargetAngle > CurrAngle) {
277 NewX = X - (Y >> Step);
278 Y = (X >> Step) + Y;
279 X = NewX;
280 CurrAngle += Angles[Step];
281 } else {
282 NewX = X + (Y >> Step);
283 Y = -(X >> Step) + Y;
284 X = NewX;
285 CurrAngle -= Angles[Step];
289 if (angle > 0) {
290 *cos = X;
291 *sin = Y;
292 } else {
293 *cos = X;
294 *sin = -Y;
298 static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue)
300 if (number < 0x1000)
301 number += 0x1000;
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)
308 unsigned char ret;
310 if (number < 0x1000)
311 number += 0x1000;
312 ret = Wb35Reg_WriteSync(pHwData, number, value);
313 return ret;
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)
320 u32 val;
322 hw_get_dxx_reg(phw_data, 0x54, &val);
324 if (phw_data->revision == 0x2002) /* 1st-cut */
325 val &= 0xFFFF0000;
326 else /* 2nd-cut */
327 val &= 0x000003FF;
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)
340 u32 reg_agc_ctrl3;
341 u32 reg_a_acq_ctrl;
342 u32 reg_b_acq_ctrl;
343 u32 val;
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);
357 } else {
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);
363 val &= ~(0x03FF);
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 */
372 /* a. Disable AGC */
373 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_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, &reg_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, &reg_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]" */
402 #ifdef _DEBUG
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));
410 #endif
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, &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 /* g. Enable AGC */
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)
435 u32 reg_agc_ctrl3;
436 u32 reg_mode_ctrl;
437 u32 reg_dc_cancel;
438 s32 iqcal_image_i;
439 s32 iqcal_image_q;
440 u32 sqsum;
441 s32 mag_0;
442 s32 mag_1;
443 s32 fix_cancel_dc_i = 0;
444 u32 val;
445 int loop;
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 */
464 /* a. Disable AGC */
465 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_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, &reg_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);
480 /* mode=2, tone=0 */
481 /* reg_mode_ctrl |= (MASK_CALIB_START|2); */
483 /* mode=2, tone=1 */
484 /* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */
486 /* mode=2, tone=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, &reg_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));
512 /* d. */
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 */
528 if (mag_0 != mag_1)
529 fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
530 else {
531 if (mag_0 == mag_1)
532 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
533 fix_cancel_dc_i = 0;
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)
540 break;
543 if (loop >= 19)
544 fix_cancel_dc_i = 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));
551 /* g. */
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)
560 u32 reg_agc_ctrl3;
561 u32 reg_mode_ctrl;
562 u32 reg_dc_cancel;
563 s32 iqcal_image_i;
564 s32 iqcal_image_q;
565 u32 sqsum;
566 s32 mag_0;
567 s32 mag_1;
568 s32 fix_cancel_dc_q = 0;
569 u32 val;
570 int loop;
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 */
586 /* a. Disable AGC */
587 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_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, &reg_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, &reg_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));
627 /* c. */
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 */
643 if (mag_0 != mag_1)
644 fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
645 else {
646 if (mag_0 == mag_1)
647 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
648 fix_cancel_dc_q = 0;
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)
655 break;
658 if (loop >= 19)
659 fix_cancel_dc_q = 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));
667 /* f. */
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,
675 s32 a_2_threshold,
676 s32 b_2_threshold)
678 u32 reg_mode_ctrl;
679 s32 iq_mag_0_tx;
680 s32 iqcal_tone_i0;
681 s32 iqcal_tone_q0;
682 s32 iqcal_tone_i;
683 s32 iqcal_tone_q;
684 u32 sqsum;
685 s32 rot_i_b;
686 s32 rot_q_b;
687 s32 tx_cal_flt_b[4];
688 s32 tx_cal[4];
689 s32 tx_cal_reg[4];
690 s32 a_2, b_2;
691 s32 sin_b, sin_2b;
692 s32 cos_b, cos_2b;
693 s32 divisor;
694 s32 temp1, temp2;
695 u32 val;
696 u16 loop;
697 s32 iqcal_tone_i_avg, iqcal_tone_q_avg;
698 u8 verify_count;
699 int capture_time;
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));
705 verify_count = 0;
707 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
708 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
710 loop = LOOP_TIMES;
712 while (loop > 0) {
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 */
718 return 0;
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));
731 /* b. */
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, &reg_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));
761 /* e. */
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)
770 continue;
771 else {
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",
786 rot_i_b, rot_q_b));
788 /* f. */
789 divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
791 if (divisor == 0) {
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"));
795 break;
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)) {
809 verify_count++;
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"));
819 return 0;
822 continue;
823 } else
824 verify_count = 0;
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));
831 if (cos_2b == 0) {
832 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
833 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
834 PHY_DEBUG(("[CAL] ******************************************\n"));
835 break;
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);
844 else /* 2nd-cut */
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))
869 { */
870 /* PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
871 * PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
872 * PHY_DEBUG(("[CAL] ******************************************\n"));
873 * return 0;
874 } */
876 /* g. */
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"));
905 break;
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"));
913 break;
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 */{
927 val &= 0x0000FFFF;
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));
934 return 0;
935 } else /* 2nd-cut */{
936 val &= 0x000003FF;
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));
943 return 0;
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));
951 loop--;
954 return 1;
957 void _tx_iq_calibration_winbond(struct hw_data *phw_data)
959 u32 reg_agc_ctrl3;
960 #ifdef _DEBUG
961 s32 tx_cal_reg[4];
963 #endif
964 u32 reg_mode_ctrl;
965 u32 val;
966 u8 result;
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);
989 /* a. Disable AGC */
990 hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_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);
1001 if (result > 0) {
1002 if (phw_data->revision == 0x2002) /* 1st-cut */{
1003 hw_get_dxx_reg(phw_data, 0x54, &val);
1004 val &= 0x0000FFFF;
1005 hw_set_dxx_reg(phw_data, 0x54, val);
1006 } else /* 2nd-cut*/{
1007 hw_get_dxx_reg(phw_data, 0x3C, &val);
1008 val &= 0x000003FF;
1009 hw_set_dxx_reg(phw_data, 0x3C, val);
1012 result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
1014 if (result > 0) {
1015 if (phw_data->revision == 0x2002) /* 1st-cut */{
1016 hw_get_dxx_reg(phw_data, 0x54, &val);
1017 val &= 0x0000FFFF;
1018 hw_set_dxx_reg(phw_data, 0x54, val);
1019 } else /* 2nd-cut*/{
1020 hw_get_dxx_reg(phw_data, 0x3C, &val);
1021 val &= 0x000003FF;
1022 hw_set_dxx_reg(phw_data, 0x3C, val);
1025 result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
1026 if (result > 0) {
1027 if (phw_data->revision == 0x2002) /* 1st-cut */{
1028 hw_get_dxx_reg(phw_data, 0x54, &val);
1029 val &= 0x0000FFFF;
1030 hw_set_dxx_reg(phw_data, 0x54, val);
1031 } else /* 2nd-cut */{
1032 hw_get_dxx_reg(phw_data, 0x3C, &val);
1033 val &= 0x000003FF;
1034 hw_set_dxx_reg(phw_data, 0x3C, val);
1038 result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
1040 if (result > 0) {
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);
1047 val &= 0x0000FFFF;
1048 hw_set_dxx_reg(phw_data, 0x54, val);
1049 } else /* 2nd-cut */{
1050 hw_get_dxx_reg(phw_data, 0x3C, &val);
1051 val &= 0x000003FF;
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, &reg_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));
1065 /* g. Enable AGC */
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);
1071 #ifdef _DEBUG
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]));
1093 #endif
1097 * for test - BEN
1098 * RF Control Override
1102 /*****************************************************/
1103 u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
1105 u32 reg_mode_ctrl;
1106 s32 iqcal_tone_i;
1107 s32 iqcal_tone_q;
1108 s32 iqcal_image_i;
1109 s32 iqcal_image_q;
1110 s32 rot_tone_i_b;
1111 s32 rot_tone_q_b;
1112 s32 rot_image_i_b;
1113 s32 rot_image_q_b;
1114 s32 rx_cal_flt_b[4];
1115 s32 rx_cal[4];
1116 s32 rx_cal_reg[4];
1117 s32 a_2, b_2;
1118 s32 sin_b, sin_2b;
1119 s32 cos_b, cos_2b;
1120 s32 temp1, temp2;
1121 u32 val;
1122 u16 loop;
1124 u32 pwr_tone;
1125 u32 pwr_image;
1126 u8 verify_count;
1128 s32 iqcal_tone_i_avg, iqcal_tone_q_avg;
1129 s32 iqcal_image_i_avg, iqcal_image_q_avg;
1130 u16 capture_time;
1132 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
1133 PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
1136 /* RF Control Override */
1137 hw_get_cxx_reg(phw_data, 0x80, &val);
1138 val |= BIT(19);
1139 hw_set_cxx_reg(phw_data, 0x80, val);
1141 /* RF_Ctrl */
1142 hw_get_cxx_reg(phw_data, 0xE4, &val);
1143 val |= BIT(0);
1144 hw_set_cxx_reg(phw_data, 0xE4, val);
1145 PHY_DEBUG(("[CAL] ** RF_CTRL(0xE4) = 0x%08X", val));
1147 hw_set_dxx_reg(phw_data, 0x58, 0x44444444); /* IQ_Alpha */
1149 /* b. */
1151 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1152 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1154 verify_count = 0;
1156 /* for (loop = 0; loop < 1; loop++) */
1157 /* for (loop = 0; loop < LOOP_TIMES; loop++) */
1158 loop = LOOP_TIMES;
1159 while (loop > 0) {
1160 PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
1161 iqcal_tone_i_avg = 0;
1162 iqcal_tone_q_avg = 0;
1163 iqcal_image_i_avg = 0;
1164 iqcal_image_q_avg = 0;
1165 capture_time = 0;
1167 for (capture_time = 0; capture_time < 10; capture_time++) {
1168 /* i. Set "calib_start" to 0x0 */
1169 reg_mode_ctrl &= ~MASK_CALIB_START;
1170 if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */
1171 return 0;
1172 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1174 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1175 reg_mode_ctrl |= (MASK_CALIB_START|0x1);
1176 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1177 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1179 /* c. */
1180 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1181 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1183 iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
1184 iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1185 PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
1186 iqcal_tone_i, iqcal_tone_q));
1188 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
1189 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
1191 iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
1192 iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1193 PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n",
1194 iqcal_image_i, iqcal_image_q));
1195 if (capture_time == 0)
1196 continue;
1197 else {
1198 iqcal_image_i_avg = (iqcal_image_i_avg*(capture_time-1) + iqcal_image_i)/capture_time;
1199 iqcal_image_q_avg = (iqcal_image_q_avg*(capture_time-1) + iqcal_image_q)/capture_time;
1200 iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
1201 iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
1206 iqcal_image_i = iqcal_image_i_avg;
1207 iqcal_image_q = iqcal_image_q_avg;
1208 iqcal_tone_i = iqcal_tone_i_avg;
1209 iqcal_tone_q = iqcal_tone_q_avg;
1211 /* d. */
1212 rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
1213 iqcal_tone_q * iqcal_tone_q) / 1024;
1214 rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
1215 iqcal_tone_q * iqcal_tone_i) / 1024;
1216 rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
1217 iqcal_image_q * iqcal_tone_q) / 1024;
1218 rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
1219 iqcal_image_q * iqcal_tone_i) / 1024;
1221 PHY_DEBUG(("[CAL] ** rot_tone_i_b = %d\n", rot_tone_i_b));
1222 PHY_DEBUG(("[CAL] ** rot_tone_q_b = %d\n", rot_tone_q_b));
1223 PHY_DEBUG(("[CAL] ** rot_image_i_b = %d\n", rot_image_i_b));
1224 PHY_DEBUG(("[CAL] ** rot_image_q_b = %d\n", rot_image_q_b));
1226 /* f. */
1227 if (rot_tone_i_b == 0) {
1228 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1229 PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
1230 PHY_DEBUG(("[CAL] ******************************************\n"));
1231 break;
1234 a_2 = (rot_image_i_b * 32768) / rot_tone_i_b -
1235 phw_data->iq_rsdl_gain_tx_d2;
1236 b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
1237 phw_data->iq_rsdl_phase_tx_d2;
1239 PHY_DEBUG(("[CAL] ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
1240 PHY_DEBUG(("[CAL] ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
1241 PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
1242 PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
1244 _sin_cos(b_2, &sin_b, &cos_b);
1245 _sin_cos(b_2*2, &sin_2b, &cos_2b);
1246 PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
1247 PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
1249 if (cos_2b == 0) {
1250 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1251 PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
1252 PHY_DEBUG(("[CAL] ******************************************\n"));
1253 break;
1256 /* 1280 * 32768 = 41943040 */
1257 temp1 = (41943040/cos_2b)*cos_b;
1259 /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
1260 if (phw_data->revision == 0x2002)/* 1st-cut */
1261 temp2 = (41943040/cos_2b)*sin_b*(-1);
1262 else/* 2nd-cut */
1263 temp2 = (41943040*4/cos_2b)*sin_b*(-1);
1265 rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
1266 rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
1267 rx_cal_flt_b[2] = _floor(temp2/(32768+a_2));
1268 rx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
1270 PHY_DEBUG(("[CAL] ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0]));
1271 PHY_DEBUG(("[CAL] rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1]));
1272 PHY_DEBUG(("[CAL] rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2]));
1273 PHY_DEBUG(("[CAL] rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3]));
1275 rx_cal[0] = rx_cal_flt_b[0] - 128;
1276 rx_cal[1] = rx_cal_flt_b[1];
1277 rx_cal[2] = rx_cal_flt_b[2];
1278 rx_cal[3] = rx_cal_flt_b[3] - 128;
1279 PHY_DEBUG(("[CAL] ** rx_cal[0] = %d\n", rx_cal[0]));
1280 PHY_DEBUG(("[CAL] rx_cal[1] = %d\n", rx_cal[1]));
1281 PHY_DEBUG(("[CAL] rx_cal[2] = %d\n", rx_cal[2]));
1282 PHY_DEBUG(("[CAL] rx_cal[3] = %d\n", rx_cal[3]));
1284 /* e. */
1285 pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
1286 pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
1288 PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone));
1289 PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image));
1291 if (pwr_tone > pwr_image) {
1292 verify_count++;
1294 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
1295 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
1296 PHY_DEBUG(("[CAL] ******************************************\n"));
1298 if (verify_count > 2) {
1299 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1300 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
1301 PHY_DEBUG(("[CAL] **************************************\n"));
1302 return 0;
1305 continue;
1307 /* g. */
1308 hw_get_dxx_reg(phw_data, 0x54, &val);
1309 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1311 if (phw_data->revision == 0x2002) /* 1st-cut */{
1312 rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1313 rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
1314 rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
1315 rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1316 } else /* 2nd-cut */{
1317 rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1318 rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1319 rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1320 rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1323 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1324 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1325 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1326 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1328 if (phw_data->revision == 0x2002) /* 1st-cut */{
1329 if (((rx_cal_reg[0] == 7) || (rx_cal_reg[0] == (-8))) &&
1330 ((rx_cal_reg[3] == 7) || (rx_cal_reg[3] == (-8)))) {
1331 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1332 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1333 PHY_DEBUG(("[CAL] **************************************\n"));
1334 break;
1336 } else /* 2nd-cut */{
1337 if (((rx_cal_reg[0] == 31) || (rx_cal_reg[0] == (-32))) &&
1338 ((rx_cal_reg[3] == 31) || (rx_cal_reg[3] == (-32)))) {
1339 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1340 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1341 PHY_DEBUG(("[CAL] **************************************\n"));
1342 break;
1346 rx_cal[0] = rx_cal[0] + rx_cal_reg[0];
1347 rx_cal[1] = rx_cal[1] + rx_cal_reg[1];
1348 rx_cal[2] = rx_cal[2] + rx_cal_reg[2];
1349 rx_cal[3] = rx_cal[3] + rx_cal_reg[3];
1350 PHY_DEBUG(("[CAL] ** apply rx_cal[0] = %d\n", rx_cal[0]));
1351 PHY_DEBUG(("[CAL] apply rx_cal[1] = %d\n", rx_cal[1]));
1352 PHY_DEBUG(("[CAL] apply rx_cal[2] = %d\n", rx_cal[2]));
1353 PHY_DEBUG(("[CAL] apply rx_cal[3] = %d\n", rx_cal[3]));
1355 hw_get_dxx_reg(phw_data, 0x54, &val);
1356 if (phw_data->revision == 0x2002) /* 1st-cut */{
1357 val &= 0x0000FFFF;
1358 val |= ((_s32_to_s4(rx_cal[0]) << 12)|
1359 (_s32_to_s4(rx_cal[1]) << 8)|
1360 (_s32_to_s4(rx_cal[2]) << 4)|
1361 (_s32_to_s4(rx_cal[3])));
1362 hw_set_dxx_reg(phw_data, 0x54, val);
1363 } else /* 2nd-cut */{
1364 val &= 0x000003FF;
1365 val |= ((_s32_to_s5(rx_cal[0]) << 27)|
1366 (_s32_to_s6(rx_cal[1]) << 21)|
1367 (_s32_to_s6(rx_cal[2]) << 15)|
1368 (_s32_to_s5(rx_cal[3]) << 10));
1369 hw_set_dxx_reg(phw_data, 0x54, val);
1371 if (loop == 3)
1372 return 0;
1374 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
1376 loop--;
1379 return 1;
1382 /*************************************************/
1384 /***************************************************************/
1385 void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1387 /* figo 20050523 marked this flag for can't compile for relesase */
1388 #ifdef _DEBUG
1389 s32 rx_cal_reg[4];
1390 u32 val;
1391 #endif
1393 u8 result;
1395 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
1396 /* a. Set RFIC to "RX calibration mode" */
1397 /* ; ----- Calibration (7). RX path IQ imbalance calibration loop */
1398 /* 0x01 0xFFBFC2 ; 3FEFF ; Calibration (7a). enable RX IQ calibration loop circuits */
1399 phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
1400 /* 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuits */
1401 phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
1402 /* 0x05 0x24848A ; 09212 ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized */
1403 phy_set_rf_data(phw_data, 5, (5<<24) | phw_data->txvga_setting_for_cal);
1404 /* 0x06 0x06840C ; 01A10 ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized */
1405 phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
1406 /* 0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode */
1407 phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
1409 /* ; [BB-chip]: Calibration (7f). Send test pattern */
1410 /* ; [BB-chip]: Calibration (7g). Search RXGCL optimal value */
1411 /* ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table */
1413 result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
1415 if (result > 0) {
1416 _reset_rx_cal(phw_data);
1417 result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
1419 if (result > 0) {
1420 _reset_rx_cal(phw_data);
1421 result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
1423 if (result > 0) {
1424 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
1425 PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
1426 PHY_DEBUG(("[CAL] **************************************\n"));
1427 _reset_rx_cal(phw_data);
1432 #ifdef _DEBUG
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 */{
1437 rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1438 rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
1439 rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
1440 rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1441 } else /* 2nd-cut */{
1442 rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1443 rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1444 rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1445 rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1448 PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1449 PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1450 PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1451 PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1452 #endif
1456 /*******************************************************/
1457 void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1459 u32 reg_mode_ctrl;
1460 u32 iq_alpha;
1462 PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
1464 /* 20040701 1.1.25.1000 kevin */
1465 hw_get_cxx_reg(phw_data, 0x80, &mac_ctrl);
1466 hw_get_cxx_reg(phw_data, 0xE4, &rf_ctrl);
1467 hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
1471 _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
1472 /* _txidac_dc_offset_cancellation_winbond(phw_data); */
1473 /* _txqdac_dc_offset_cacellation_winbond(phw_data); */
1475 _tx_iq_calibration_winbond(phw_data);
1476 _rx_iq_calibration_winbond(phw_data, frequency);
1478 /*********************************************************************/
1479 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1480 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); /* set when finish */
1481 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1482 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1484 /* i. Set RFIC to "Normal mode" */
1485 hw_set_cxx_reg(phw_data, 0x80, mac_ctrl);
1486 hw_set_cxx_reg(phw_data, 0xE4, rf_ctrl);
1487 hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
1490 /*********************************************************************/
1491 phy_init_rf(phw_data);
1495 /******************/
1496 void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value)
1498 u32 ltmp = 0;
1500 switch (pHwData->phy_type) {
1501 case RF_MAXIM_2825:
1502 case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */
1503 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1504 break;
1506 case RF_MAXIM_2827:
1507 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1508 break;
1510 case RF_MAXIM_2828:
1511 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1512 break;
1514 case RF_MAXIM_2829:
1515 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1516 break;
1518 case RF_AIROHA_2230:
1519 case RF_AIROHA_2230S: /* 20060420 Add this */
1520 ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20);
1521 break;
1523 case RF_AIROHA_7230:
1524 ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
1525 break;
1527 case RF_WB_242:
1528 case RF_WB_242_1:/* 20060619.5 Add */
1529 ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24);
1530 break;
1533 Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
1536 /* 20060717 modify as Bruce's mail */
1537 unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
1539 int init_txvga = 0;
1540 u32 reg_mode_ctrl;
1541 u32 val;
1542 s32 iqcal_tone_i0;
1543 s32 iqcal_tone_q0;
1544 u32 sqsum;
1545 s32 iq_mag_0_tx;
1546 u8 reg_state;
1547 int current_txvga;
1550 reg_state = 0;
1551 for (init_txvga = 0; init_txvga < 10; init_txvga++) {
1552 current_txvga = (0x24C40A|(init_txvga<<6));
1553 phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga));
1554 phw_data->txvga_setting_for_cal = current_txvga;
1556 msleep(30);/* 20060612.1.a */
1558 if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl))/* 20060718.1 modify */
1559 return false;
1561 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1564 * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1565 * enable "IQ alibration Mode II"
1567 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
1568 reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1569 reg_mode_ctrl |= (MASK_CALIB_START|0x02);
1570 reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
1571 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1572 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1574 udelay(1);/* 20060612.1.a */
1576 udelay(300);/* 20060612.1.a */
1578 /* b. */
1579 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1581 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1582 udelay(300);/* 20060612.1.a */
1584 iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
1585 iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
1586 PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
1587 iqcal_tone_i0, iqcal_tone_q0));
1589 sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
1590 iq_mag_0_tx = (s32) _sqrt(sqsum);
1591 PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
1593 if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1594 break;
1595 else if (iq_mag_0_tx > 1750) {
1596 init_txvga = -2;
1597 continue;
1598 } else
1599 continue;
1603 if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1604 return true;
1605 else
1606 return false;