1 /*
2  * phy_302_calibration.c
3  *
4  * Copyright (C) 2002, 2005  Winbond Electronics Corp.
5  *
6  * modification history
7  * ---------------------------------------------------------------------------
8  * 0.01.001, 2003-04-16, Kevin      created
9  *
10  */
11 
12 /****************** INCLUDE FILES SECTION ***********************************/
13 #include "phy_calibration.h"
14 #include "wbhal.h"
15 #include "wb35reg_f.h"
16 #include "core.h"
17 
18 
19 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
20 
21 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
22 #define LOOP_TIMES      20
23 #define US              1000/* MICROSECOND*/
24 
25 #define AG_CONST        0.6072529350
26 #define FIXED(X)        ((s32)((X) * 32768.0))
27 #define DEG2RAD(X)      0.017453 * (X)
28 
29 static const s32 Angles[] = {
30     FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),   FIXED(DEG2RAD(14.0362)),
31     FIXED(DEG2RAD(7.12502)),  FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
32     FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
33     FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
34 };
35 
36 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
37 
38 /*
39  * void    _phy_rf_write_delay(struct hw_data *phw_data);
40  * void    phy_init_rf(struct hw_data *phw_data);
41  */
42 
43 /****************** FUNCTION DEFINITION SECTION *****************************/
44 
_s13_to_s32(u32 data)45 s32 _s13_to_s32(u32 data)
46 {
47     u32     val;
48 
49     val = (data & 0x0FFF);
50 
51     if ((data & BIT(12)) != 0)
52         val |= 0xFFFFF000;
53 
54     return ((s32) val);
55 }
56 
_s32_to_s13(s32 data)57 u32 _s32_to_s13(s32 data)
58 {
59     u32     val;
60 
61     if (data > 4095)
62         data = 4095;
63     else if (data < -4096)
64         data = -4096;
65 
66     val = data & 0x1FFF;
67 
68     return val;
69 }
70 
71 /****************************************************************************/
_s4_to_s32(u32 data)72 s32 _s4_to_s32(u32 data)
73 {
74     s32     val;
75 
76     val = (data & 0x0007);
77 
78     if ((data & BIT(3)) != 0)
79         val |= 0xFFFFFFF8;
80 
81     return val;
82 }
83 
_s32_to_s4(s32 data)84 u32 _s32_to_s4(s32 data)
85 {
86     u32     val;
87 
88     if (data > 7)
89         data = 7;
90     else if (data < -8)
91         data = -8;
92 
93     val = data & 0x000F;
94 
95     return val;
96 }
97 
98 /****************************************************************************/
_s5_to_s32(u32 data)99 s32 _s5_to_s32(u32 data)
100 {
101     s32     val;
102 
103     val = (data & 0x000F);
104 
105     if ((data & BIT(4)) != 0)
106         val |= 0xFFFFFFF0;
107 
108     return val;
109 }
110 
_s32_to_s5(s32 data)111 u32 _s32_to_s5(s32 data)
112 {
113     u32     val;
114 
115     if (data > 15)
116         data = 15;
117     else if (data < -16)
118         data = -16;
119 
120     val = data & 0x001F;
121 
122     return val;
123 }
124 
125 /****************************************************************************/
_s6_to_s32(u32 data)126 s32 _s6_to_s32(u32 data)
127 {
128     s32     val;
129 
130     val = (data & 0x001F);
131 
132     if ((data & BIT(5)) != 0)
133         val |= 0xFFFFFFE0;
134 
135     return val;
136 }
137 
_s32_to_s6(s32 data)138 u32 _s32_to_s6(s32 data)
139 {
140     u32     val;
141 
142     if (data > 31)
143         data = 31;
144     else if (data < -32)
145         data = -32;
146 
147     val = data & 0x003F;
148 
149     return val;
150 }
151 
152 /****************************************************************************/
_s9_to_s32(u32 data)153 s32 _s9_to_s32(u32 data)
154 {
155     s32     val;
156 
157     val = data & 0x00FF;
158 
159     if ((data & BIT(8)) != 0)
160         val |= 0xFFFFFF00;
161 
162     return val;
163 }
164 
_s32_to_s9(s32 data)165 u32 _s32_to_s9(s32 data)
166 {
167     u32     val;
168 
169     if (data > 255)
170         data = 255;
171     else if (data < -256)
172         data = -256;
173 
174     val = data & 0x01FF;
175 
176     return val;
177 }
178 
179 /****************************************************************************/
_floor(s32 n)180 s32 _floor(s32 n)
181 {
182     if (n > 0)
183 	n += 5;
184     else
185         n -= 5;
186 
187     return (n/10);
188 }
189 
190 /****************************************************************************/
191 /*
192  * The following code is sqare-root function.
193  * sqsum is the input and the output is sq_rt;
194  * The maximum of sqsum = 2^27 -1;
195  */
_sqrt(u32 sqsum)196 u32 _sqrt(u32 sqsum)
197 {
198     u32     sq_rt;
199 
200     int     g0, g1, g2, g3, g4;
201     int     seed;
202     int     next;
203     int     step;
204 
205     g4 =  sqsum / 100000000;
206     g3 = (sqsum - g4*100000000) / 1000000;
207     g2 = (sqsum - g4*100000000 - g3*1000000) / 10000;
208     g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100;
209     g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
210 
211     next = g4;
212     step = 0;
213     seed = 0;
214     while (((seed+1)*(step+1)) <= next) {
215         step++;
216         seed++;
217     }
218 
219     sq_rt = seed * 10000;
220     next = (next-(seed*step))*100 + g3;
221 
222     step = 0;
223     seed = 2 * seed * 10;
224     while (((seed+1)*(step+1)) <= next) {
225         step++;
226         seed++;
227     }
228 
229     sq_rt = sq_rt + step * 1000;
230     next = (next - seed * step) * 100 + g2;
231     seed = (seed + step) * 10;
232     step = 0;
233     while (((seed+1)*(step+1)) <= next) {
234         step++;
235         seed++;
236     }
237 
238     sq_rt = sq_rt + step * 100;
239     next = (next - seed * step) * 100 + g1;
240     seed = (seed + step) * 10;
241     step = 0;
242 
243     while (((seed+1)*(step+1)) <= next) {
244         step++;
245         seed++;
246     }
247 
248     sq_rt = sq_rt + step * 10;
249     next = (next - seed * step) * 100 + g0;
250     seed = (seed + step) * 10;
251     step = 0;
252 
253     while (((seed+1)*(step+1)) <= next) {
254         step++;
255         seed++;
256     }
257 
258     sq_rt = sq_rt + step;
259 
260     return sq_rt;
261 }
262 
263 /****************************************************************************/
_sin_cos(s32 angle,s32 * sin,s32 * cos)264 void _sin_cos(s32 angle, s32 *sin, s32 *cos)
265 {
266     s32 X, Y, TargetAngle, CurrAngle;
267     unsigned    Step;
268 
269     X = FIXED(AG_CONST);      /* AG_CONST * cos(0) */
270     Y = 0;                    /* AG_CONST * sin(0) */
271     TargetAngle = abs(angle);
272     CurrAngle = 0;
273 
274     for (Step = 0; Step < 12; Step++) {
275 	s32 NewX;
276 
277         if (TargetAngle > CurrAngle) {
278             NewX = X - (Y >> Step);
279             Y = (X >> Step) + Y;
280             X = NewX;
281             CurrAngle += Angles[Step];
282         } else {
283             NewX = X + (Y >> Step);
284             Y = -(X >> Step) + Y;
285             X = NewX;
286             CurrAngle -= Angles[Step];
287         }
288     }
289 
290     if (angle > 0) {
291         *cos = X;
292         *sin = Y;
293     } else {
294         *cos = X;
295         *sin = -Y;
296     }
297 }
298 
hal_get_dxx_reg(struct hw_data * pHwData,u16 number,u32 * pValue)299 static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue)
300 {
301 	if (number < 0x1000)
302 		number += 0x1000;
303 	return Wb35Reg_ReadSync(pHwData, number, pValue);
304 }
305 #define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
306 
hal_set_dxx_reg(struct hw_data * pHwData,u16 number,u32 value)307 static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
308 {
309 	unsigned char ret;
310 
311 	if (number < 0x1000)
312 		number += 0x1000;
313 	ret = Wb35Reg_WriteSync(pHwData, number, value);
314 	return ret;
315 }
316 #define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
317 
318 
_reset_rx_cal(struct hw_data * phw_data)319 void _reset_rx_cal(struct hw_data *phw_data)
320 {
321 	u32     val;
322 
323 	hw_get_dxx_reg(phw_data, 0x54, &val);
324 
325 	if (phw_data->revision == 0x2002) /* 1st-cut */
326 		val &= 0xFFFF0000;
327 	else /* 2nd-cut */
328 		val &= 0x000003FF;
329 
330 	hw_set_dxx_reg(phw_data, 0x54, val);
331 }
332 
333 
334 /**************for winbond calibration*********/
335 
336 
337 
338 /**********************************************/
_rxadc_dc_offset_cancellation_winbond(struct hw_data * phw_data,u32 frequency)339 void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
340 {
341     u32     reg_agc_ctrl3;
342     u32     reg_a_acq_ctrl;
343     u32     reg_b_acq_ctrl;
344     u32     val;
345 
346     PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
347     phy_init_rf(phw_data);
348 
349     /* set calibration channel */
350     if ((RF_WB_242 == phw_data->phy_type) ||
351 		(RF_WB_242_1 == phw_data->phy_type)) /* 20060619.5 Add */{
352         if ((frequency >= 2412) && (frequency <= 2484)) {
353             /* w89rf242 change frequency to 2390Mhz */
354             PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
355 			phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
356 
357         }
358     } else {
359 
360 	}
361 
362 	/* reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
363 	hw_get_dxx_reg(phw_data, 0x5C, &val);
364 	val &= ~(0x03FF);
365 	hw_set_dxx_reg(phw_data, 0x5C, val);
366 
367 	/* reset the TX and RX IQ calibration data */
368 	hw_set_dxx_reg(phw_data, 0x3C, 0);
369 	hw_set_dxx_reg(phw_data, 0x54, 0);
370 
371 	hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
372 
373 	/* a. Disable AGC */
374 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
375 	reg_agc_ctrl3 &= ~BIT(2);
376 	reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
377 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
378 
379 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
380 	val |= MASK_AGC_FIX_GAIN;
381 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
382 
383 	/* b. Turn off BB RX */
384 	hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
385 	reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
386 	hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
387 
388 	hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl);
389 	reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
390 	hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
391 
392 	/* c. Make sure MAC is in receiving mode
393 	 * d. Turn ON ADC calibration
394 	 *    - ADC calibrator is triggered by this signal rising from 0 to 1 */
395 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
396 	val &= ~MASK_ADC_DC_CAL_STR;
397 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
398 
399 	val |= MASK_ADC_DC_CAL_STR;
400 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
401 
402 	/* e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */
403 #ifdef _DEBUG
404 	hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val);
405 	PHY_DEBUG(("[CAL]    REG_OFFSET_READ = 0x%08X\n", val));
406 
407 	PHY_DEBUG(("[CAL]    ** adc_dc_cal_i = %d (0x%04X)\n",
408 			   _s9_to_s32(val&0x000001FF), val&0x000001FF));
409 	PHY_DEBUG(("[CAL]    ** adc_dc_cal_q = %d (0x%04X)\n",
410 			   _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9));
411 #endif
412 
413 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
414 	val &= ~MASK_ADC_DC_CAL_STR;
415 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
416 
417 	/* f. Turn on BB RX */
418 	/* hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl); */
419 	reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG;
420 	hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
421 
422 	/* hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl); */
423 	reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG;
424 	hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
425 
426 	/* g. Enable AGC */
427 	/* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
428 	reg_agc_ctrl3 |= BIT(2);
429 	reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
430 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
431 }
432 
433 /****************************************************************/
_txidac_dc_offset_cancellation_winbond(struct hw_data * phw_data)434 void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
435 {
436 	u32     reg_agc_ctrl3;
437 	u32     reg_mode_ctrl;
438 	u32     reg_dc_cancel;
439 	s32     iqcal_image_i;
440 	s32     iqcal_image_q;
441 	u32     sqsum;
442 	s32     mag_0;
443 	s32     mag_1;
444 	s32     fix_cancel_dc_i = 0;
445 	u32     val;
446 	int     loop;
447 
448 	PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
449 
450 	/* a. Set to "TX calibration mode" */
451 
452 	/* 0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
453 	phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
454 	/* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
455 	phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
456 	/* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
457 	phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
458         /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
459 	phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
460 	/* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
461 	phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
462 
463 	hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
464 
465 	/* a. Disable AGC */
466 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
467 	reg_agc_ctrl3 &= ~BIT(2);
468 	reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
469 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
470 
471 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
472 	val |= MASK_AGC_FIX_GAIN;
473 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
474 
475 	/* b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 */
476 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
477 
478 	PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
479 	reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
480 
481 	/* mode=2, tone=0 */
482 	/* reg_mode_ctrl |= (MASK_CALIB_START|2); */
483 
484 	/* mode=2, tone=1 */
485 	/* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */
486 
487 	/* mode=2, tone=2 */
488 	reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2));
489 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
490 	PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
491 
492 	hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
493 	PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
494 
495 	for (loop = 0; loop < LOOP_TIMES; loop++) {
496 		PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
497 
498 		/* c. reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
499 		reg_dc_cancel &= ~(0x03FF);
500 		PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
501 		hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
502 
503 		hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
504 		PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
505 
506 		iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
507 		iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
508 		sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
509 		mag_0 = (s32) _sqrt(sqsum);
510 		PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
511 				   mag_0, iqcal_image_i, iqcal_image_q));
512 
513 		/* d. */
514 		reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
515 		PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
516 		hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
517 
518 		hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
519 		PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
520 
521 		iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
522 		iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
523 		sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
524 		mag_1 = (s32) _sqrt(sqsum);
525 		PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
526 				   mag_1, iqcal_image_i, iqcal_image_q));
527 
528 		/* e. Calculate the correct DC offset cancellation value for I */
529 		if (mag_0 != mag_1)
530 			fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
531 		else {
532 			if (mag_0 == mag_1)
533 				PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
534 			fix_cancel_dc_i = 0;
535 		}
536 
537 		PHY_DEBUG(("[CAL]    ** fix_cancel_dc_i = %d (0x%04X)\n",
538 				   fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
539 
540 		if ((abs(mag_1-mag_0)*6) > mag_0)
541 			break;
542 	}
543 
544 	if (loop >= 19)
545 	   fix_cancel_dc_i = 0;
546 
547 	reg_dc_cancel &= ~(0x03FF);
548 	reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT);
549 	hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
550 	PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
551 
552 	/* g. */
553 	reg_mode_ctrl &= ~MASK_CALIB_START;
554 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
555 	PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
556 }
557 
558 /*****************************************************/
_txqdac_dc_offset_cacellation_winbond(struct hw_data * phw_data)559 void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
560 {
561 	u32     reg_agc_ctrl3;
562 	u32     reg_mode_ctrl;
563 	u32     reg_dc_cancel;
564 	s32     iqcal_image_i;
565 	s32     iqcal_image_q;
566 	u32     sqsum;
567 	s32     mag_0;
568 	s32     mag_1;
569 	s32     fix_cancel_dc_q = 0;
570 	u32     val;
571 	int     loop;
572 
573 	PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
574 	/*0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
575 	phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
576 	/* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
577 	phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
578 	/* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
579 	phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
580         /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
581 	phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
582 	/* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
583 	phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
584 
585 	hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
586 
587 	/* a. Disable AGC */
588 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
589 	reg_agc_ctrl3 &= ~BIT(2);
590 	reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
591 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
592 
593 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
594 	val |= MASK_AGC_FIX_GAIN;
595 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
596 
597 	/* a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 */
598 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
599 	PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
600 
601 	/* reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); */
602 	reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
603 	reg_mode_ctrl |= (MASK_CALIB_START|3);
604 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
605 	PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
606 
607 	hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
608 	PHY_DEBUG(("[CAL]    DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
609 
610 	for (loop = 0; loop < LOOP_TIMES; loop++) {
611 		PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
612 
613 		/* b. reset cancel_dc_q[4:0] in register DC_Cancel */
614 		reg_dc_cancel &= ~(0x001F);
615 		PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
616 		hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
617 
618 		hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
619 		PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
620 
621 		iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
622 		iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
623 		sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
624 		mag_0 = _sqrt(sqsum);
625 		PHY_DEBUG(("[CAL]    mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
626 				   mag_0, iqcal_image_i, iqcal_image_q));
627 
628 		/* c. */
629 		reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
630 		PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
631 		hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
632 
633 		hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
634 		PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
635 
636 		iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
637 		iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
638 		sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
639 		mag_1 = _sqrt(sqsum);
640 		PHY_DEBUG(("[CAL]    mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
641 				   mag_1, iqcal_image_i, iqcal_image_q));
642 
643 		/* d. Calculate the correct DC offset cancellation value for I */
644 		if (mag_0 != mag_1)
645 			fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
646 		else {
647 			if (mag_0 == mag_1)
648 				PHY_DEBUG(("[CAL]   ***** mag_0 = mag_1 !!\n"));
649 			fix_cancel_dc_q = 0;
650 		}
651 
652 		PHY_DEBUG(("[CAL]    ** fix_cancel_dc_q = %d (0x%04X)\n",
653 				   fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
654 
655 		if ((abs(mag_1-mag_0)*6) > mag_0)
656 			break;
657 	}
658 
659 	if (loop >= 19)
660 	   fix_cancel_dc_q = 0;
661 
662 	reg_dc_cancel &= ~(0x001F);
663 	reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT);
664 	hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
665 	PHY_DEBUG(("[CAL]    DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
666 
667 
668 	/* f. */
669 	reg_mode_ctrl &= ~MASK_CALIB_START;
670 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
671 	PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
672 }
673 
674 /* 20060612.1.a 20060718.1 Modify */
_tx_iq_calibration_loop_winbond(struct hw_data * phw_data,s32 a_2_threshold,s32 b_2_threshold)675 u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
676 						   s32 a_2_threshold,
677 						   s32 b_2_threshold)
678 {
679 	u32     reg_mode_ctrl;
680 	s32     iq_mag_0_tx;
681 	s32     iqcal_tone_i0;
682 	s32     iqcal_tone_q0;
683 	s32     iqcal_tone_i;
684 	s32     iqcal_tone_q;
685 	u32     sqsum;
686 	s32     rot_i_b;
687 	s32     rot_q_b;
688 	s32     tx_cal_flt_b[4];
689 	s32     tx_cal[4];
690 	s32     tx_cal_reg[4];
691 	s32     a_2, b_2;
692 	s32     sin_b, sin_2b;
693 	s32     cos_b, cos_2b;
694 	s32     divisor;
695 	s32     temp1, temp2;
696 	u32     val;
697 	u16     loop;
698 	s32     iqcal_tone_i_avg, iqcal_tone_q_avg;
699 	u8      verify_count;
700 	int capture_time;
701 
702 	PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
703 	PHY_DEBUG(("[CAL]    ** a_2_threshold = %d\n", a_2_threshold));
704 	PHY_DEBUG(("[CAL]    ** b_2_threshold = %d\n", b_2_threshold));
705 
706 	verify_count = 0;
707 
708 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
709 	PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
710 
711 	loop = LOOP_TIMES;
712 
713 	while (loop > 0) {
714 		PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
715 
716 		iqcal_tone_i_avg = 0;
717 		iqcal_tone_q_avg = 0;
718 		if (!hw_set_dxx_reg(phw_data, 0x3C, 0x00)) /* 20060718.1 modify */
719 			return 0;
720 		for (capture_time = 0; capture_time < 10; capture_time++) {
721 			/*
722 			 * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
723 			 *    enable "IQ alibration Mode II"
724 			 */
725 			reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
726 			reg_mode_ctrl &= ~MASK_IQCAL_MODE;
727 			reg_mode_ctrl |= (MASK_CALIB_START|0x02);
728 			reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
729 			hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
730 			PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
731 
732 			/* b. */
733 			hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
734 			PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
735 
736 			iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
737 			iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
738 			PHY_DEBUG(("[CAL]    ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
739 				   iqcal_tone_i0, iqcal_tone_q0));
740 
741 			sqsum = iqcal_tone_i0*iqcal_tone_i0 +
742 			iqcal_tone_q0*iqcal_tone_q0;
743 			iq_mag_0_tx = (s32) _sqrt(sqsum);
744 			PHY_DEBUG(("[CAL]    ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
745 
746 			/* c. Set "calib_start" to 0x0 */
747 			reg_mode_ctrl &= ~MASK_CALIB_START;
748 			hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
749 			PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
750 
751 			/*
752 			 * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
753 			 *    enable "IQ alibration Mode II"
754 			 */
755 			/* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
756 			hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
757 			reg_mode_ctrl &= ~MASK_IQCAL_MODE;
758 			reg_mode_ctrl |= (MASK_CALIB_START|0x03);
759 			hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
760 			PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
761 
762 			/* e. */
763 			hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
764 			PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
765 
766 			iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
767 			iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
768 			PHY_DEBUG(("[CAL]    ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
769 			iqcal_tone_i, iqcal_tone_q));
770 			if (capture_time == 0)
771 				continue;
772 			else {
773 				iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
774 				iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
775 			}
776 		}
777 
778 		iqcal_tone_i = iqcal_tone_i_avg;
779 		iqcal_tone_q = iqcal_tone_q_avg;
780 
781 
782 		rot_i_b = (iqcal_tone_i * iqcal_tone_i0 +
783 				   iqcal_tone_q * iqcal_tone_q0) / 1024;
784 		rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) +
785 				   iqcal_tone_q * iqcal_tone_i0) / 1024;
786 		PHY_DEBUG(("[CAL]    ** rot_i_b = %d, rot_q_b = %d\n",
787 				   rot_i_b, rot_q_b));
788 
789 		/* f. */
790 		divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
791 
792 		if (divisor == 0) {
793 			PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
794 			PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
795 			PHY_DEBUG(("[CAL] ******************************************\n"));
796 			break;
797 		}
798 
799 		a_2 = (rot_i_b * 32768) / divisor;
800 		b_2 = (rot_q_b * (-32768)) / divisor;
801 		PHY_DEBUG(("[CAL]    ***** EPSILON/2 = %d\n", a_2));
802 		PHY_DEBUG(("[CAL]    ***** THETA/2   = %d\n", b_2));
803 
804 		phw_data->iq_rsdl_gain_tx_d2 = a_2;
805 		phw_data->iq_rsdl_phase_tx_d2 = b_2;
806 
807 		/* if ((abs(a_2) < 150) && (abs(b_2) < 100)) */
808 		/* if ((abs(a_2) < 200) && (abs(b_2) < 200)) */
809 		if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold)) {
810 			verify_count++;
811 
812 			PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
813 			PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
814 			PHY_DEBUG(("[CAL] ******************************************\n"));
815 
816 			if (verify_count > 2) {
817 				PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
818 				PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
819 				PHY_DEBUG(("[CAL] **************************************\n"));
820 				return 0;
821 			}
822 
823 			continue;
824 		} else
825 			verify_count = 0;
826 
827 		_sin_cos(b_2, &sin_b, &cos_b);
828 		_sin_cos(b_2*2, &sin_2b, &cos_2b);
829 		PHY_DEBUG(("[CAL]    ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
830 		PHY_DEBUG(("[CAL]    ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
831 
832 		if (cos_2b == 0) {
833 			PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
834 			PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
835 			PHY_DEBUG(("[CAL] ******************************************\n"));
836 			break;
837 		}
838 
839 		/* 1280 * 32768 = 41943040 */
840 		temp1 = (41943040/cos_2b)*cos_b;
841 
842 		/* temp2 = (41943040/cos_2b)*sin_b*(-1); */
843 		if (phw_data->revision == 0x2002) /* 1st-cut */
844 			temp2 = (41943040/cos_2b)*sin_b*(-1);
845 		else /* 2nd-cut */
846 			temp2 = (41943040*4/cos_2b)*sin_b*(-1);
847 
848 		tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
849 		tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
850 		tx_cal_flt_b[2] = _floor(temp2/(32768-a_2));
851 		tx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
852 		PHY_DEBUG(("[CAL]    ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0]));
853 		PHY_DEBUG(("[CAL]       tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1]));
854 		PHY_DEBUG(("[CAL]       tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2]));
855 		PHY_DEBUG(("[CAL]       tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
856 
857 		tx_cal[2] = tx_cal_flt_b[2];
858 		tx_cal[2] = tx_cal[2] + 3;
859 		tx_cal[1] = tx_cal[2];
860 		tx_cal[3] = tx_cal_flt_b[3] - 128;
861 		tx_cal[0] = -tx_cal[3] + 1;
862 
863 		PHY_DEBUG(("[CAL]       tx_cal[0] = %d\n", tx_cal[0]));
864 		PHY_DEBUG(("[CAL]       tx_cal[1] = %d\n", tx_cal[1]));
865 		PHY_DEBUG(("[CAL]       tx_cal[2] = %d\n", tx_cal[2]));
866 		PHY_DEBUG(("[CAL]       tx_cal[3] = %d\n", tx_cal[3]));
867 
868 		/* if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
869 		      (tx_cal[2] == 0) && (tx_cal[3] == 0))
870 		  { */
871 		/*    PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
872 		 *    PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
873 		 *    PHY_DEBUG(("[CAL] ******************************************\n"));
874 		 *    return 0;
875 		  } */
876 
877 		/* g. */
878 		if (phw_data->revision == 0x2002) /* 1st-cut */{
879 			hw_get_dxx_reg(phw_data, 0x54, &val);
880 			PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
881 			tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
882 			tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
883 			tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
884 			tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
885 		} else /* 2nd-cut */{
886 			hw_get_dxx_reg(phw_data, 0x3C, &val);
887 			PHY_DEBUG(("[CAL]    ** 0x3C = 0x%08X\n", val));
888 			tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
889 			tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
890 			tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
891 			tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
892 
893 		}
894 
895 		PHY_DEBUG(("[CAL]    ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
896 		PHY_DEBUG(("[CAL]       tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
897 		PHY_DEBUG(("[CAL]       tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
898 		PHY_DEBUG(("[CAL]       tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
899 
900 		if (phw_data->revision == 0x2002) /* 1st-cut */{
901 			if (((tx_cal_reg[0] == 7) || (tx_cal_reg[0] == (-8))) &&
902 				((tx_cal_reg[3] == 7) || (tx_cal_reg[3] == (-8)))) {
903 				PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
904 				PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
905 				PHY_DEBUG(("[CAL] **************************************\n"));
906 				break;
907 			}
908 		} else /* 2nd-cut */{
909 			if (((tx_cal_reg[0] == 31) || (tx_cal_reg[0] == (-32))) &&
910 				((tx_cal_reg[3] == 31) || (tx_cal_reg[3] == (-32)))) {
911 				PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
912 				PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
913 				PHY_DEBUG(("[CAL] **************************************\n"));
914 				break;
915 			}
916 		}
917 
918 		tx_cal[0] = tx_cal[0] + tx_cal_reg[0];
919 		tx_cal[1] = tx_cal[1] + tx_cal_reg[1];
920 		tx_cal[2] = tx_cal[2] + tx_cal_reg[2];
921 		tx_cal[3] = tx_cal[3] + tx_cal_reg[3];
922 		PHY_DEBUG(("[CAL]    ** apply tx_cal[0] = %d\n", tx_cal[0]));
923 		PHY_DEBUG(("[CAL]       apply tx_cal[1] = %d\n", tx_cal[1]));
924 		PHY_DEBUG(("[CAL]       apply tx_cal[2] = %d\n", tx_cal[2]));
925 		PHY_DEBUG(("[CAL]       apply tx_cal[3] = %d\n", tx_cal[3]));
926 
927 		if (phw_data->revision == 0x2002) /* 1st-cut */{
928 			val &= 0x0000FFFF;
929 			val |= ((_s32_to_s4(tx_cal[0]) << 28)|
930 					(_s32_to_s4(tx_cal[1]) << 24)|
931 					(_s32_to_s4(tx_cal[2]) << 20)|
932 					(_s32_to_s4(tx_cal[3]) << 16));
933 			hw_set_dxx_reg(phw_data, 0x54, val);
934 			PHY_DEBUG(("[CAL]    ** CALIB_DATA = 0x%08X\n", val));
935 			return 0;
936 		} else /* 2nd-cut */{
937 			val &= 0x000003FF;
938 			val |= ((_s32_to_s5(tx_cal[0]) << 27)|
939 					(_s32_to_s6(tx_cal[1]) << 21)|
940 					(_s32_to_s6(tx_cal[2]) << 15)|
941 					(_s32_to_s5(tx_cal[3]) << 10));
942 			hw_set_dxx_reg(phw_data, 0x3C, val);
943 			PHY_DEBUG(("[CAL]    ** TX_IQ_CALIBRATION = 0x%08X\n", val));
944 			return 0;
945 		}
946 
947 		/* i. Set "calib_start" to 0x0 */
948 		reg_mode_ctrl &= ~MASK_CALIB_START;
949 		hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
950 		PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
951 
952 		loop--;
953 	}
954 
955 	return 1;
956 }
957 
_tx_iq_calibration_winbond(struct hw_data * phw_data)958 void _tx_iq_calibration_winbond(struct hw_data *phw_data)
959 {
960 	u32     reg_agc_ctrl3;
961 #ifdef _DEBUG
962 	s32     tx_cal_reg[4];
963 
964 #endif
965 	u32     reg_mode_ctrl;
966 	u32     val;
967 	u8      result;
968 
969 	PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
970 
971 	/* 0x01 0xEE3FC2  ; 3B8FF  ; Calibration (6a). enable TX IQ calibration loop circuits */
972 	phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
973 	/* 0x0B 0x1905D6  ; 06417  ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
974 	phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); /* 20060612.1.a 0x1905D6); */
975 	/* 0x05 0x24C60A  ; 09318  ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
976 	phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); /* 0x24C60A (high temperature) */
977         /* 0x06 0x06880C  ; 01A20  ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
978 	phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); /* 20060612.1.a 0x06890C); */
979 	/* 0x00 0xFDF1C0  ; 3F7C7  ; Calibration (6e). turn on IQ imbalance/Test mode */
980 	phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
981 	/* ; [BB-chip]: Calibration (6f).Send test pattern */
982 	/* ; [BB-chip]: Calibration (6g). Search RXGCL optimal value */
983 	/* ; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table */
984 	/* phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); */
985 
986 	msleep(30); /* 20060612.1.a 30ms delay. Add the follow 2 lines */
987 	/* To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750 */
988 	adjust_TXVGA_for_iq_mag(phw_data);
989 
990 	/* a. Disable AGC */
991 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
992 	reg_agc_ctrl3 &= ~BIT(2);
993 	reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
994 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
995 
996 	hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
997 	val |= MASK_AGC_FIX_GAIN;
998 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
999 
1000 	result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
1001 
1002 	if (result > 0) {
1003 		if (phw_data->revision == 0x2002) /* 1st-cut */{
1004 			hw_get_dxx_reg(phw_data, 0x54, &val);
1005 			val &= 0x0000FFFF;
1006 			hw_set_dxx_reg(phw_data, 0x54, val);
1007 		} else /* 2nd-cut*/{
1008 			hw_get_dxx_reg(phw_data, 0x3C, &val);
1009 			val &= 0x000003FF;
1010 			hw_set_dxx_reg(phw_data, 0x3C, val);
1011 		}
1012 
1013 		result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
1014 
1015 		if (result > 0) {
1016 			if (phw_data->revision == 0x2002) /* 1st-cut */{
1017 				hw_get_dxx_reg(phw_data, 0x54, &val);
1018 				val &= 0x0000FFFF;
1019 				hw_set_dxx_reg(phw_data, 0x54, val);
1020 			} else /* 2nd-cut*/{
1021 				hw_get_dxx_reg(phw_data, 0x3C, &val);
1022 				val &= 0x000003FF;
1023 				hw_set_dxx_reg(phw_data, 0x3C, val);
1024 			}
1025 
1026 			result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
1027 			if (result > 0) {
1028 				if (phw_data->revision == 0x2002) /* 1st-cut */{
1029 					hw_get_dxx_reg(phw_data, 0x54, &val);
1030 					val &= 0x0000FFFF;
1031 					hw_set_dxx_reg(phw_data, 0x54, val);
1032 				} else /* 2nd-cut */{
1033 					hw_get_dxx_reg(phw_data, 0x3C, &val);
1034 					val &= 0x000003FF;
1035 					hw_set_dxx_reg(phw_data, 0x3C, val);
1036 				}
1037 
1038 
1039 				result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
1040 
1041 				if (result > 0) {
1042 					PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
1043 					PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
1044 					PHY_DEBUG(("[CAL] **************************************\n"));
1045 
1046 					if (phw_data->revision == 0x2002) /* 1st-cut */{
1047 						hw_get_dxx_reg(phw_data, 0x54, &val);
1048 						val &= 0x0000FFFF;
1049 						hw_set_dxx_reg(phw_data, 0x54, val);
1050 					} else /* 2nd-cut */{
1051 						hw_get_dxx_reg(phw_data, 0x3C, &val);
1052 						val &= 0x000003FF;
1053 						hw_set_dxx_reg(phw_data, 0x3C, val);
1054 					}
1055 				}
1056 			}
1057 		}
1058 	}
1059 
1060 	/* i. Set "calib_start" to 0x0 */
1061 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1062 	reg_mode_ctrl &= ~MASK_CALIB_START;
1063 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1064 	PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1065 
1066 	/* g. Enable AGC */
1067 	/* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
1068 	reg_agc_ctrl3 |= BIT(2);
1069 	reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
1070 	hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
1071 
1072 #ifdef _DEBUG
1073 	if (phw_data->revision == 0x2002) /* 1st-cut */{
1074 		hw_get_dxx_reg(phw_data, 0x54, &val);
1075 		PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
1076 		tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
1077 		tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
1078 		tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
1079 		tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
1080 	} else /* 2nd-cut */ {
1081 		hw_get_dxx_reg(phw_data, 0x3C, &val);
1082 		PHY_DEBUG(("[CAL]    ** 0x3C = 0x%08X\n", val));
1083 		tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1084 		tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1085 		tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1086 		tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1087 
1088 	}
1089 
1090 	PHY_DEBUG(("[CAL]    ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
1091 	PHY_DEBUG(("[CAL]       tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
1092 	PHY_DEBUG(("[CAL]       tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
1093 	PHY_DEBUG(("[CAL]       tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
1094 #endif
1095 
1096 
1097 	/*
1098 	 * for test - BEN
1099 	 * RF Control Override
1100 	 */
1101 }
1102 
1103 /*****************************************************/
_rx_iq_calibration_loop_winbond(struct hw_data * phw_data,u16 factor,u32 frequency)1104 u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
1105 {
1106 	u32     reg_mode_ctrl;
1107 	s32     iqcal_tone_i;
1108 	s32     iqcal_tone_q;
1109 	s32     iqcal_image_i;
1110 	s32     iqcal_image_q;
1111 	s32     rot_tone_i_b;
1112 	s32     rot_tone_q_b;
1113 	s32     rot_image_i_b;
1114 	s32     rot_image_q_b;
1115 	s32     rx_cal_flt_b[4];
1116 	s32     rx_cal[4];
1117 	s32     rx_cal_reg[4];
1118 	s32     a_2, b_2;
1119 	s32     sin_b, sin_2b;
1120 	s32     cos_b, cos_2b;
1121 	s32     temp1, temp2;
1122 	u32     val;
1123 	u16     loop;
1124 
1125 	u32     pwr_tone;
1126 	u32     pwr_image;
1127 	u8      verify_count;
1128 
1129 	s32     iqcal_tone_i_avg, iqcal_tone_q_avg;
1130 	s32     iqcal_image_i_avg, iqcal_image_q_avg;
1131 	u16	capture_time;
1132 
1133 	PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
1134 	PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
1135 
1136 	hw_set_dxx_reg(phw_data, 0x58, 0x44444444); /* IQ_Alpha */
1137 
1138 	/* b. */
1139 
1140 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1141 	PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1142 
1143 	verify_count = 0;
1144 
1145 	/* for (loop = 0; loop < 1; loop++) */
1146 	/* for (loop = 0; loop < LOOP_TIMES; loop++) */
1147 	loop = LOOP_TIMES;
1148 	while (loop > 0) {
1149 		PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
1150 		iqcal_tone_i_avg = 0;
1151 		iqcal_tone_q_avg = 0;
1152 		iqcal_image_i_avg = 0;
1153 		iqcal_image_q_avg = 0;
1154 		capture_time = 0;
1155 
1156 		for (capture_time = 0; capture_time < 10; capture_time++) {
1157 		/* i. Set "calib_start" to 0x0 */
1158 		reg_mode_ctrl &= ~MASK_CALIB_START;
1159 		if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */
1160 			return 0;
1161 		PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1162 
1163 		reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1164 		reg_mode_ctrl |= (MASK_CALIB_START|0x1);
1165 		hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1166 		PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1167 
1168 		/* c. */
1169 		hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1170 		PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
1171 
1172 		iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
1173 		iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1174 		PHY_DEBUG(("[CAL]    ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
1175 				   iqcal_tone_i, iqcal_tone_q));
1176 
1177 		hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
1178 		PHY_DEBUG(("[CAL]    CALIB_READ2 = 0x%08X\n", val));
1179 
1180 		iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
1181 		iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
1182 		PHY_DEBUG(("[CAL]    ** iqcal_image_i = %d, iqcal_image_q = %d\n",
1183 				   iqcal_image_i, iqcal_image_q));
1184 			if (capture_time == 0)
1185 				continue;
1186 			else {
1187 				iqcal_image_i_avg = (iqcal_image_i_avg*(capture_time-1) + iqcal_image_i)/capture_time;
1188 				iqcal_image_q_avg = (iqcal_image_q_avg*(capture_time-1) + iqcal_image_q)/capture_time;
1189 				iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
1190 				iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
1191 			}
1192 		}
1193 
1194 
1195 		iqcal_image_i = iqcal_image_i_avg;
1196 		iqcal_image_q = iqcal_image_q_avg;
1197 		iqcal_tone_i = iqcal_tone_i_avg;
1198 		iqcal_tone_q = iqcal_tone_q_avg;
1199 
1200 		/* d. */
1201 		rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
1202 						iqcal_tone_q * iqcal_tone_q) / 1024;
1203 		rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
1204 						iqcal_tone_q * iqcal_tone_i) / 1024;
1205 		rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
1206 						 iqcal_image_q * iqcal_tone_q) / 1024;
1207 		rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
1208 						 iqcal_image_q * iqcal_tone_i) / 1024;
1209 
1210 		PHY_DEBUG(("[CAL]    ** rot_tone_i_b  = %d\n", rot_tone_i_b));
1211 		PHY_DEBUG(("[CAL]    ** rot_tone_q_b  = %d\n", rot_tone_q_b));
1212 		PHY_DEBUG(("[CAL]    ** rot_image_i_b = %d\n", rot_image_i_b));
1213 		PHY_DEBUG(("[CAL]    ** rot_image_q_b = %d\n", rot_image_q_b));
1214 
1215 		/* f. */
1216 		if (rot_tone_i_b == 0) {
1217 			PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1218 			PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
1219 			PHY_DEBUG(("[CAL] ******************************************\n"));
1220 			break;
1221 		}
1222 
1223 		a_2 = (rot_image_i_b * 32768) / rot_tone_i_b -
1224 			phw_data->iq_rsdl_gain_tx_d2;
1225 		b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
1226 			phw_data->iq_rsdl_phase_tx_d2;
1227 
1228 		PHY_DEBUG(("[CAL]    ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
1229 		PHY_DEBUG(("[CAL]    ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
1230 		PHY_DEBUG(("[CAL]    ***** EPSILON/2 = %d\n", a_2));
1231 		PHY_DEBUG(("[CAL]    ***** THETA/2   = %d\n", b_2));
1232 
1233 		_sin_cos(b_2, &sin_b, &cos_b);
1234 		_sin_cos(b_2*2, &sin_2b, &cos_2b);
1235 		PHY_DEBUG(("[CAL]    ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
1236 		PHY_DEBUG(("[CAL]    ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
1237 
1238 		if (cos_2b == 0) {
1239 			PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
1240 			PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
1241 			PHY_DEBUG(("[CAL] ******************************************\n"));
1242 			break;
1243 		}
1244 
1245 		/* 1280 * 32768 = 41943040 */
1246 		temp1 = (41943040/cos_2b)*cos_b;
1247 
1248 		/* temp2 = (41943040/cos_2b)*sin_b*(-1); */
1249 		if (phw_data->revision == 0x2002)/* 1st-cut */
1250 			temp2 = (41943040/cos_2b)*sin_b*(-1);
1251 		else/* 2nd-cut */
1252 			temp2 = (41943040*4/cos_2b)*sin_b*(-1);
1253 
1254 		rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
1255 		rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
1256 		rx_cal_flt_b[2] = _floor(temp2/(32768+a_2));
1257 		rx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
1258 
1259 		PHY_DEBUG(("[CAL]    ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0]));
1260 		PHY_DEBUG(("[CAL]       rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1]));
1261 		PHY_DEBUG(("[CAL]       rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2]));
1262 		PHY_DEBUG(("[CAL]       rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3]));
1263 
1264 		rx_cal[0] = rx_cal_flt_b[0] - 128;
1265 		rx_cal[1] = rx_cal_flt_b[1];
1266 		rx_cal[2] = rx_cal_flt_b[2];
1267 		rx_cal[3] = rx_cal_flt_b[3] - 128;
1268 		PHY_DEBUG(("[CAL]    ** rx_cal[0] = %d\n", rx_cal[0]));
1269 		PHY_DEBUG(("[CAL]       rx_cal[1] = %d\n", rx_cal[1]));
1270 		PHY_DEBUG(("[CAL]       rx_cal[2] = %d\n", rx_cal[2]));
1271 		PHY_DEBUG(("[CAL]       rx_cal[3] = %d\n", rx_cal[3]));
1272 
1273 		/* e. */
1274 		pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
1275 		pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
1276 
1277 		PHY_DEBUG(("[CAL]    ** pwr_tone  = %d\n", pwr_tone));
1278 		PHY_DEBUG(("[CAL]    ** pwr_image  = %d\n", pwr_image));
1279 
1280 		if (pwr_tone > pwr_image) {
1281 			verify_count++;
1282 
1283 			PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
1284 			PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
1285 			PHY_DEBUG(("[CAL] ******************************************\n"));
1286 
1287 			if (verify_count > 2) {
1288 				PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1289 				PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
1290 				PHY_DEBUG(("[CAL] **************************************\n"));
1291 				return 0;
1292 			}
1293 
1294 			continue;
1295 		}
1296 		/* g. */
1297 		hw_get_dxx_reg(phw_data, 0x54, &val);
1298 		PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
1299 
1300 		if (phw_data->revision == 0x2002) /* 1st-cut */{
1301 			rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1302 			rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >>  8);
1303 			rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >>  4);
1304 			rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1305 		} else /* 2nd-cut */{
1306 			rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1307 			rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1308 			rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1309 			rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1310 		}
1311 
1312 		PHY_DEBUG(("[CAL]    ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1313 		PHY_DEBUG(("[CAL]       rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1314 		PHY_DEBUG(("[CAL]       rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1315 		PHY_DEBUG(("[CAL]       rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1316 
1317 		if (phw_data->revision == 0x2002) /* 1st-cut */{
1318 			if (((rx_cal_reg[0] == 7) || (rx_cal_reg[0] == (-8))) &&
1319 				((rx_cal_reg[3] == 7) || (rx_cal_reg[3] == (-8)))) {
1320 				PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1321 				PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1322 				PHY_DEBUG(("[CAL] **************************************\n"));
1323 				break;
1324 			}
1325 		} else /* 2nd-cut */{
1326 			if (((rx_cal_reg[0] == 31) || (rx_cal_reg[0] == (-32))) &&
1327 				((rx_cal_reg[3] == 31) || (rx_cal_reg[3] == (-32)))) {
1328 				PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
1329 				PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
1330 				PHY_DEBUG(("[CAL] **************************************\n"));
1331 				break;
1332 			}
1333 		}
1334 
1335 		rx_cal[0] = rx_cal[0] + rx_cal_reg[0];
1336 		rx_cal[1] = rx_cal[1] + rx_cal_reg[1];
1337 		rx_cal[2] = rx_cal[2] + rx_cal_reg[2];
1338 		rx_cal[3] = rx_cal[3] + rx_cal_reg[3];
1339 		PHY_DEBUG(("[CAL]    ** apply rx_cal[0] = %d\n", rx_cal[0]));
1340 		PHY_DEBUG(("[CAL]       apply rx_cal[1] = %d\n", rx_cal[1]));
1341 		PHY_DEBUG(("[CAL]       apply rx_cal[2] = %d\n", rx_cal[2]));
1342 		PHY_DEBUG(("[CAL]       apply rx_cal[3] = %d\n", rx_cal[3]));
1343 
1344 		hw_get_dxx_reg(phw_data, 0x54, &val);
1345 		if (phw_data->revision == 0x2002) /* 1st-cut */{
1346 			val &= 0x0000FFFF;
1347 			val |= ((_s32_to_s4(rx_cal[0]) << 12)|
1348 					(_s32_to_s4(rx_cal[1]) <<  8)|
1349 					(_s32_to_s4(rx_cal[2]) <<  4)|
1350 					(_s32_to_s4(rx_cal[3])));
1351 			hw_set_dxx_reg(phw_data, 0x54, val);
1352 		} else /* 2nd-cut */{
1353 			val &= 0x000003FF;
1354 			val |= ((_s32_to_s5(rx_cal[0]) << 27)|
1355 					(_s32_to_s6(rx_cal[1]) << 21)|
1356 					(_s32_to_s6(rx_cal[2]) << 15)|
1357 					(_s32_to_s5(rx_cal[3]) << 10));
1358 			hw_set_dxx_reg(phw_data, 0x54, val);
1359 
1360 			if (loop == 3)
1361 			return 0;
1362 		}
1363 		PHY_DEBUG(("[CAL]    ** CALIB_DATA = 0x%08X\n", val));
1364 
1365 		loop--;
1366 	}
1367 
1368 	return 1;
1369 }
1370 
1371 /*************************************************/
1372 
1373 /***************************************************************/
_rx_iq_calibration_winbond(struct hw_data * phw_data,u32 frequency)1374 void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1375 {
1376 /* figo 20050523 marked this flag for can't compile for relesase */
1377 #ifdef _DEBUG
1378 	s32     rx_cal_reg[4];
1379 	u32     val;
1380 #endif
1381 
1382 	u8      result;
1383 
1384 	PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
1385 /* a. Set RFIC to "RX calibration mode" */
1386 	/* ; ----- Calibration (7). RX path IQ imbalance calibration loop */
1387 	/*	0x01 0xFFBFC2  ; 3FEFF  ; Calibration (7a). enable RX IQ calibration loop circuits */
1388 	phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
1389 	/*	0x0B 0x1A01D6  ; 06817  ; Calibration (7b). enable RX I/Q cal loop SW1 circuits */
1390 	phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
1391 	/* 0x05 0x24848A  ; 09212  ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized */
1392 	phy_set_rf_data(phw_data, 5, (5<<24) | phw_data->txvga_setting_for_cal);
1393 	/* 0x06 0x06840C  ; 01A10  ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized */
1394 	phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
1395 	/* 0x00 0xFFF1C0  ; 3F7C7  ; Calibration (7e). turn on IQ imbalance/Test mode */
1396 	phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
1397 
1398 	/*  ; [BB-chip]: Calibration (7f). Send test pattern */
1399 	/*	; [BB-chip]: Calibration (7g). Search RXGCL optimal value */
1400 	/*	; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table */
1401 
1402 	result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
1403 
1404 	if (result > 0) {
1405 		_reset_rx_cal(phw_data);
1406 		result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
1407 
1408 		if (result > 0) {
1409 			_reset_rx_cal(phw_data);
1410 			result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
1411 
1412 			if (result > 0) {
1413 				PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
1414 				PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
1415 				PHY_DEBUG(("[CAL] **************************************\n"));
1416 				_reset_rx_cal(phw_data);
1417 			}
1418 		}
1419 	}
1420 
1421 #ifdef _DEBUG
1422 	hw_get_dxx_reg(phw_data, 0x54, &val);
1423 	PHY_DEBUG(("[CAL]    ** 0x54 = 0x%08X\n", val));
1424 
1425 	if (phw_data->revision == 0x2002) /* 1st-cut */{
1426 		rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
1427 		rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >>  8);
1428 		rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >>  4);
1429 		rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
1430 	} else /* 2nd-cut */{
1431 		rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
1432 		rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
1433 		rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
1434 		rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
1435 	}
1436 
1437 	PHY_DEBUG(("[CAL]    ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
1438 	PHY_DEBUG(("[CAL]       rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
1439 	PHY_DEBUG(("[CAL]       rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
1440 	PHY_DEBUG(("[CAL]       rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
1441 #endif
1442 
1443 }
1444 
1445 /*******************************************************/
phy_calibration_winbond(struct hw_data * phw_data,u32 frequency)1446 void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
1447 {
1448 	u32     reg_mode_ctrl;
1449 	u32     iq_alpha;
1450 
1451 	PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
1452 
1453 	hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
1454 
1455 	_rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
1456 	/* _txidac_dc_offset_cancellation_winbond(phw_data); */
1457 	/* _txqdac_dc_offset_cacellation_winbond(phw_data); */
1458 
1459 	_tx_iq_calibration_winbond(phw_data);
1460 	_rx_iq_calibration_winbond(phw_data, frequency);
1461 
1462 	/*********************************************************************/
1463 	hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
1464 	reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); /* set when finish */
1465 	hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1466 	PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1467 
1468 	/* i. Set RFIC to "Normal mode" */
1469 	hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
1470 
1471 	/*********************************************************************/
1472 	phy_init_rf(phw_data);
1473 
1474 }
1475 
1476 /******************/
phy_set_rf_data(struct hw_data * pHwData,u32 index,u32 value)1477 void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value)
1478 {
1479    u32 ltmp = 0;
1480 
1481     switch (pHwData->phy_type) {
1482     case RF_MAXIM_2825:
1483     case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */
1484             ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1485             break;
1486 
1487     case RF_MAXIM_2827:
1488             ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1489 	    break;
1490 
1491     case RF_MAXIM_2828:
1492 	    ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1493 	    break;
1494 
1495     case RF_MAXIM_2829:
1496 	    ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1497 	    break;
1498 
1499     case RF_AIROHA_2230:
1500     case RF_AIROHA_2230S: /* 20060420 Add this */
1501 	    ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20);
1502 	    break;
1503 
1504     case RF_AIROHA_7230:
1505 	    ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
1506 	    break;
1507 
1508     case RF_WB_242:
1509     case RF_WB_242_1:/* 20060619.5 Add */
1510 	    ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24);
1511 	    break;
1512     }
1513 
1514 	Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
1515 }
1516 
1517 /* 20060717 modify as Bruce's mail */
adjust_TXVGA_for_iq_mag(struct hw_data * phw_data)1518 unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
1519 {
1520 	int init_txvga = 0;
1521 	u32     reg_mode_ctrl;
1522 	u32     val;
1523 	s32     iqcal_tone_i0;
1524 	s32     iqcal_tone_q0;
1525 	u32     sqsum;
1526 	s32     iq_mag_0_tx;
1527 	u8	reg_state;
1528 	int	current_txvga;
1529 
1530 
1531 	reg_state = 0;
1532 	for (init_txvga = 0; init_txvga < 10; init_txvga++) {
1533 		current_txvga = (0x24C40A|(init_txvga<<6));
1534 		phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga));
1535 		phw_data->txvga_setting_for_cal = current_txvga;
1536 
1537 		msleep(30);/* 20060612.1.a */
1538 
1539 		if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl))/* 20060718.1 modify */
1540 			return false;
1541 
1542 		PHY_DEBUG(("[CAL]    MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1543 
1544 		/*
1545 		 * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1546 		 *    enable "IQ alibration Mode II"
1547 		 */
1548 		reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
1549 		reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1550 		reg_mode_ctrl |= (MASK_CALIB_START|0x02);
1551 		reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
1552 		hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1553 		PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1554 
1555 		udelay(1);/* 20060612.1.a */
1556 
1557 		udelay(300);/* 20060612.1.a */
1558 
1559 		/* b. */
1560 		hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1561 
1562 		PHY_DEBUG(("[CAL]    CALIB_READ1 = 0x%08X\n", val));
1563 		udelay(300);/* 20060612.1.a */
1564 
1565 		iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
1566 		iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
1567 		PHY_DEBUG(("[CAL]    ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
1568 				   iqcal_tone_i0, iqcal_tone_q0));
1569 
1570 		sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
1571 		iq_mag_0_tx = (s32) _sqrt(sqsum);
1572 		PHY_DEBUG(("[CAL]    ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
1573 
1574 		if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1575 			break;
1576 		else if (iq_mag_0_tx > 1750) {
1577 			init_txvga = -2;
1578 			continue;
1579 		} else
1580 			continue;
1581 
1582 	}
1583 
1584 	if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1585 		return true;
1586 	else
1587 		return false;
1588 }
1589