Merge commit 'v2.6.36-rc1' into HEAD
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / winbond / phy_calibration.c
CommitLineData
66101de1
PM
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 ***********************************/
7e797abf 13#include "sysdef.h"
66101de1 14#include "phy_calibration.h"
80aba536 15#include "wbhal_f.h"
66101de1
PM
16
17
18/****************** DEBUG CONSTANT AND MACRO SECTION ************************/
19
20/****************** LOCAL CONSTANT AND MACRO SECTION ************************/
21#define LOOP_TIMES 20
3a4d1b90 22#define US 1000/* MICROSECOND*/
66101de1
PM
23
24#define AG_CONST 0.6072529350
25#define FIXED(X) ((s32)((X) * 32768.0))
26#define DEG2RAD(X) 0.017453 * (X)
27
3a4d1b90
TT
28static 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))
66101de1
PM
33};
34
2e04bb7b 35/****************** LOCAL FUNCTION DECLARATION SECTION **********************/
3a4d1b90
TT
36
37/*
38 * void _phy_rf_write_delay(struct hw_data *phw_data);
39 * void phy_init_rf(struct hw_data *phw_data);
40 */
66101de1
PM
41
42/****************** FUNCTION DEFINITION SECTION *****************************/
43
44s32 _s13_to_s32(u32 data)
45{
46 u32 val;
47
48 val = (data & 0x0FFF);
49
50 if ((data & BIT(12)) != 0)
66101de1 51 val |= 0xFFFFF000;
66101de1
PM
52
53 return ((s32) val);
54}
55
56u32 _s32_to_s13(s32 data)
57{
58 u32 val;
59
60 if (data > 4095)
66101de1 61 data = 4095;
66101de1 62 else if (data < -4096)
66101de1 63 data = -4096;
66101de1
PM
64
65 val = data & 0x1FFF;
66
67 return val;
68}
69
70/****************************************************************************/
71s32 _s4_to_s32(u32 data)
72{
73 s32 val;
74
75 val = (data & 0x0007);
76
77 if ((data & BIT(3)) != 0)
66101de1 78 val |= 0xFFFFFFF8;
66101de1
PM
79
80 return val;
81}
82
83u32 _s32_to_s4(s32 data)
84{
85 u32 val;
86
87 if (data > 7)
66101de1 88 data = 7;
66101de1 89 else if (data < -8)
66101de1 90 data = -8;
66101de1
PM
91
92 val = data & 0x000F;
93
94 return val;
95}
96
97/****************************************************************************/
98s32 _s5_to_s32(u32 data)
99{
100 s32 val;
101
102 val = (data & 0x000F);
103
104 if ((data & BIT(4)) != 0)
66101de1 105 val |= 0xFFFFFFF0;
66101de1
PM
106
107 return val;
108}
109
110u32 _s32_to_s5(s32 data)
111{
112 u32 val;
113
114 if (data > 15)
66101de1 115 data = 15;
66101de1 116 else if (data < -16)
66101de1 117 data = -16;
66101de1
PM
118
119 val = data & 0x001F;
120
121 return val;
122}
123
124/****************************************************************************/
125s32 _s6_to_s32(u32 data)
126{
127 s32 val;
128
129 val = (data & 0x001F);
130
131 if ((data & BIT(5)) != 0)
66101de1 132 val |= 0xFFFFFFE0;
66101de1
PM
133
134 return val;
135}
136
137u32 _s32_to_s6(s32 data)
138{
139 u32 val;
140
141 if (data > 31)
66101de1 142 data = 31;
66101de1 143 else if (data < -32)
66101de1 144 data = -32;
66101de1
PM
145
146 val = data & 0x003F;
147
148 return val;
149}
150
151/****************************************************************************/
152s32 _s9_to_s32(u32 data)
153{
154 s32 val;
155
156 val = data & 0x00FF;
157
158 if ((data & BIT(8)) != 0)
66101de1 159 val |= 0xFFFFFF00;
66101de1
PM
160
161 return val;
162}
163
164u32 _s32_to_s9(s32 data)
165{
166 u32 val;
167
168 if (data > 255)
66101de1 169 data = 255;
66101de1 170 else if (data < -256)
66101de1 171 data = -256;
66101de1
PM
172
173 val = data & 0x01FF;
174
175 return val;
176}
177
178/****************************************************************************/
179s32 _floor(s32 n)
180{
181 if (n > 0)
3a4d1b90 182 n += 5;
66101de1 183 else
66101de1 184 n -= 5;
66101de1
PM
185
186 return (n/10);
187}
188
189/****************************************************************************/
3a4d1b90
TT
190/*
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;
194 */
66101de1
PM
195u32 _sqrt(u32 sqsum)
196{
197 u32 sq_rt;
198
199 int g0, g1, g2, g3, g4;
200 int seed;
201 int next;
202 int step;
203
204 g4 = sqsum / 100000000;
3a4d1b90
TT
205 g3 = (sqsum - g4*100000000) / 1000000;
206 g2 = (sqsum - g4*100000000 - g3*1000000) / 10000;
207 g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100;
66101de1
PM
208 g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
209
210 next = g4;
211 step = 0;
212 seed = 0;
3a4d1b90
TT
213 while (((seed+1)*(step+1)) <= next) {
214 step++;
215 seed++;
66101de1
PM
216 }
217
218 sq_rt = seed * 10000;
219 next = (next-(seed*step))*100 + g3;
220
221 step = 0;
222 seed = 2 * seed * 10;
3a4d1b90 223 while (((seed+1)*(step+1)) <= next) {
66101de1 224 step++;
3a4d1b90 225 seed++;
66101de1
PM
226 }
227
228 sq_rt = sq_rt + step * 1000;
229 next = (next - seed * step) * 100 + g2;
230 seed = (seed + step) * 10;
231 step = 0;
3a4d1b90 232 while (((seed+1)*(step+1)) <= next) {
66101de1 233 step++;
3a4d1b90 234 seed++;
66101de1
PM
235 }
236
237 sq_rt = sq_rt + step * 100;
238 next = (next - seed * step) * 100 + g1;
239 seed = (seed + step) * 10;
240 step = 0;
241
3a4d1b90 242 while (((seed+1)*(step+1)) <= next) {
66101de1 243 step++;
3a4d1b90 244 seed++;
66101de1
PM
245 }
246
247 sq_rt = sq_rt + step * 10;
3a4d1b90 248 next = (next - seed * step) * 100 + g0;
66101de1
PM
249 seed = (seed + step) * 10;
250 step = 0;
251
3a4d1b90 252 while (((seed+1)*(step+1)) <= next) {
66101de1 253 step++;
3a4d1b90 254 seed++;
66101de1
PM
255 }
256
257 sq_rt = sq_rt + step;
258
259 return sq_rt;
260}
261
262/****************************************************************************/
263void _sin_cos(s32 angle, s32 *sin, s32 *cos)
264{
20dbe695 265 s32 X, Y, TargetAngle, CurrAngle;
66101de1
PM
266 unsigned Step;
267
3a4d1b90
TT
268 X = FIXED(AG_CONST); /* AG_CONST * cos(0) */
269 Y = 0; /* AG_CONST * sin(0) */
270 TargetAngle = abs(angle);
271 CurrAngle = 0;
66101de1 272
3a4d1b90 273 for (Step = 0; Step < 12; Step++) {
20dbe695 274 s32 NewX;
66101de1 275
3a4d1b90
TT
276 if (TargetAngle > CurrAngle) {
277 NewX = X - (Y >> Step);
278 Y = (X >> Step) + Y;
279 X = NewX;
66101de1 280 CurrAngle += Angles[Step];
3a4d1b90
TT
281 } else {
282 NewX = X + (Y >> Step);
283 Y = -(X >> Step) + Y;
284 X = NewX;
66101de1
PM
285 CurrAngle -= Angles[Step];
286 }
287 }
288
3a4d1b90 289 if (angle > 0) {
66101de1
PM
290 *cos = X;
291 *sin = Y;
3a4d1b90 292 } else {
66101de1
PM
293 *cos = X;
294 *sin = -Y;
295 }
296}
297
dd68e1b4
PE
298static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue)
299{
300 if (number < 0x1000)
301 number += 0x1000;
302 return Wb35Reg_ReadSync(pHwData, number, pValue);
303}
3a4d1b90 304#define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
dd68e1b4
PE
305
306static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
307{
308 unsigned char ret;
309
310 if (number < 0x1000)
311 number += 0x1000;
312 ret = Wb35Reg_WriteSync(pHwData, number, value);
313 return ret;
314}
3a4d1b90 315#define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
dd68e1b4 316
66101de1 317
8e41b4b6 318void _reset_rx_cal(struct hw_data *phw_data)
66101de1
PM
319{
320 u32 val;
321
322 hw_get_dxx_reg(phw_data, 0x54, &val);
323
3a4d1b90 324 if (phw_data->revision == 0x2002) /* 1st-cut */
66101de1 325 val &= 0xFFFF0000;
3a4d1b90 326 else /* 2nd-cut */
66101de1 327 val &= 0x000003FF;
66101de1
PM
328
329 hw_set_dxx_reg(phw_data, 0x54, val);
330}
331
332
3a4d1b90
TT
333/**************for winbond calibration*********/
334
335
66101de1 336
3a4d1b90 337/**********************************************/
8e41b4b6 338void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
66101de1
PM
339{
340 u32 reg_agc_ctrl3;
341 u32 reg_a_acq_ctrl;
342 u32 reg_b_acq_ctrl;
343 u32 val;
344
345 PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
346 phy_init_rf(phw_data);
347
3a4d1b90
TT
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 */
66101de1
PM
353 PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
354 phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
355
356 }
3a4d1b90 357 } else {
66101de1
PM
358
359 }
360
3a4d1b90 361 /* reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
66101de1
PM
362 hw_get_dxx_reg(phw_data, 0x5C, &val);
363 val &= ~(0x03FF);
364 hw_set_dxx_reg(phw_data, 0x5C, val);
365
3a4d1b90 366 /* reset the TX and RX IQ calibration data */
66101de1
PM
367 hw_set_dxx_reg(phw_data, 0x3C, 0);
368 hw_set_dxx_reg(phw_data, 0x54, 0);
369
3a4d1b90 370 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
66101de1 371
3a4d1b90 372 /* a. Disable AGC */
66101de1
PM
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);
377
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);
381
3a4d1b90 382 /* b. Turn off BB RX */
66101de1
PM
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);
386
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);
390
3a4d1b90
TT
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 */
66101de1
PM
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);
397
398 val |= MASK_ADC_DC_CAL_STR;
399 hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
66101de1 400
3a4d1b90 401 /* e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */
66101de1
PM
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));
405
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
411
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);
415
3a4d1b90
TT
416 /* f. Turn on BB RX */
417 /* hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl); */
66101de1
PM
418 reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG;
419 hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
420
3a4d1b90 421 /* hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl); */
66101de1
PM
422 reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG;
423 hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
424
3a4d1b90
TT
425 /* g. Enable AGC */
426 /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
66101de1
PM
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);
430}
431
3a4d1b90 432/****************************************************************/
8e41b4b6 433void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
66101de1
PM
434{
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;
446
447 PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
448
3a4d1b90 449 /* a. Set to "TX calibration mode" */
66101de1 450
3a4d1b90 451 /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
66101de1 452 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
3a4d1b90 453 /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
66101de1 454 phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
3a4d1b90 455 /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
66101de1 456 phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
3a4d1b90 457 /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
66101de1 458 phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
3a4d1b90 459 /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */
66101de1
PM
460 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
461
3a4d1b90 462 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
66101de1 463
3a4d1b90 464 /* a. Disable AGC */
66101de1
PM
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);
469
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);
473
3a4d1b90 474 /* b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 */
66101de1
PM
475 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
476
477 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
478 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
479
3a4d1b90
TT
480 /* mode=2, tone=0 */
481 /* reg_mode_ctrl |= (MASK_CALIB_START|2); */
66101de1 482
3a4d1b90
TT
483 /* mode=2, tone=1 */
484 /* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */
66101de1 485
3a4d1b90 486 /* mode=2, tone=2 */
66101de1
PM
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));
66101de1
PM
490
491 hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
492 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
493
3a4d1b90 494 for (loop = 0; loop < LOOP_TIMES; loop++) {
66101de1
PM
495 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
496
3a4d1b90 497 /* c. reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
66101de1
PM
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);
66101de1
PM
501
502 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
503 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
504
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));
511
3a4d1b90 512 /* d. */
66101de1
PM
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);
66101de1
PM
516
517 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
518 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
519
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));
526
3a4d1b90 527 /* e. Calculate the correct DC offset cancellation value for I */
66101de1 528 if (mag_0 != mag_1)
66101de1 529 fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
3a4d1b90 530 else {
66101de1 531 if (mag_0 == mag_1)
66101de1 532 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
66101de1
PM
533 fix_cancel_dc_i = 0;
534 }
535
536 PHY_DEBUG(("[CAL] ** fix_cancel_dc_i = %d (0x%04X)\n",
537 fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
538
539 if ((abs(mag_1-mag_0)*6) > mag_0)
66101de1 540 break;
66101de1
PM
541 }
542
3a4d1b90 543 if (loop >= 19)
66101de1
PM
544 fix_cancel_dc_i = 0;
545
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));
550
3a4d1b90 551 /* g. */
66101de1
PM
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));
66101de1
PM
555}
556
3a4d1b90 557/*****************************************************/
8e41b4b6 558void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
66101de1
PM
559{
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;
571
572 PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
3a4d1b90 573 /*0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
66101de1 574 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
3a4d1b90 575 /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
66101de1 576 phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
3a4d1b90 577 /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
66101de1 578 phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
3a4d1b90 579 /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
66101de1 580 phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
3a4d1b90 581 /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */
66101de1
PM
582 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
583
3a4d1b90 584 hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
66101de1 585
3a4d1b90 586 /* a. Disable AGC */
66101de1
PM
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);
591
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);
595
3a4d1b90 596 /* a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 */
66101de1
PM
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));
599
3a4d1b90 600 /* reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); */
66101de1
PM
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));
66101de1
PM
605
606 hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
607 PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
608
3a4d1b90 609 for (loop = 0; loop < LOOP_TIMES; loop++) {
66101de1
PM
610 PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
611
3a4d1b90 612 /* b. reset cancel_dc_q[4:0] in register DC_Cancel */
66101de1
PM
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);
66101de1
PM
616
617 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
618 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
66101de1
PM
619
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));
626
3a4d1b90 627 /* c. */
66101de1
PM
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);
66101de1
PM
631
632 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
633 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
66101de1
PM
634
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));
641
3a4d1b90 642 /* d. Calculate the correct DC offset cancellation value for I */
66101de1 643 if (mag_0 != mag_1)
66101de1 644 fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
3a4d1b90 645 else {
66101de1 646 if (mag_0 == mag_1)
66101de1 647 PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
66101de1
PM
648 fix_cancel_dc_q = 0;
649 }
650
651 PHY_DEBUG(("[CAL] ** fix_cancel_dc_q = %d (0x%04X)\n",
652 fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
653
654 if ((abs(mag_1-mag_0)*6) > mag_0)
66101de1 655 break;
66101de1
PM
656 }
657
3a4d1b90 658 if (loop >= 19)
66101de1
PM
659 fix_cancel_dc_q = 0;
660
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));
665
666
3a4d1b90 667 /* f. */
66101de1
PM
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));
66101de1
PM
671}
672
3a4d1b90 673/* 20060612.1.a 20060718.1 Modify */
8e41b4b6 674u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
66101de1
PM
675 s32 a_2_threshold,
676 s32 b_2_threshold)
677{
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;
3a4d1b90 697 s32 iqcal_tone_i_avg, iqcal_tone_q_avg;
66101de1
PM
698 u8 verify_count;
699 int capture_time;
700
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));
704
705 verify_count = 0;
706
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));
709
710 loop = LOOP_TIMES;
711
3a4d1b90 712 while (loop > 0) {
66101de1
PM
713 PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
714
3a4d1b90
TT
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 */
66101de1 718 return 0;
3a4d1b90
TT
719 for (capture_time = 0; capture_time < 10; capture_time++) {
720 /*
721 * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
722 * enable "IQ alibration Mode II"
723 */
66101de1
PM
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));
66101de1 730
3a4d1b90 731 /* b. */
66101de1
PM
732 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
733 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
66101de1
PM
734
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));
739
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));
744
3a4d1b90 745 /* c. Set "calib_start" to 0x0 */
66101de1
PM
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));
66101de1 749
3a4d1b90
TT
750 /*
751 * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
752 * enable "IQ alibration Mode II"
753 */
754 /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
66101de1
PM
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));
66101de1 760
3a4d1b90 761 /* e. */
66101de1
PM
762 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
763 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
66101de1
PM
764
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));
3a4d1b90 769 if (capture_time == 0)
66101de1 770 continue;
3a4d1b90
TT
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;
66101de1
PM
774 }
775 }
776
777 iqcal_tone_i = iqcal_tone_i_avg;
778 iqcal_tone_q = iqcal_tone_q_avg;
779
780
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));
787
3a4d1b90 788 /* f. */
66101de1
PM
789 divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
790
3a4d1b90 791 if (divisor == 0) {
66101de1
PM
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;
796 }
797
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));
802
803 phw_data->iq_rsdl_gain_tx_d2 = a_2;
804 phw_data->iq_rsdl_phase_tx_d2 = b_2;
805
3a4d1b90
TT
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)) {
66101de1
PM
809 verify_count++;
810
811 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
812 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
813 PHY_DEBUG(("[CAL] ******************************************\n"));
814
3a4d1b90 815 if (verify_count > 2) {
66101de1
PM
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;
820 }
821
822 continue;
3a4d1b90 823 } else
66101de1 824 verify_count = 0;
66101de1
PM
825
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));
830
3a4d1b90 831 if (cos_2b == 0) {
66101de1
PM
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;
836 }
837
3a4d1b90 838 /* 1280 * 32768 = 41943040 */
66101de1
PM
839 temp1 = (41943040/cos_2b)*cos_b;
840
3a4d1b90
TT
841 /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
842 if (phw_data->revision == 0x2002) /* 1st-cut */
66101de1 843 temp2 = (41943040/cos_2b)*sin_b*(-1);
3a4d1b90 844 else /* 2nd-cut */
66101de1 845 temp2 = (41943040*4/cos_2b)*sin_b*(-1);
66101de1
PM
846
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]));
855
856 tx_cal[2] = tx_cal_flt_b[2];
3a4d1b90 857 tx_cal[2] = tx_cal[2] + 3;
66101de1
PM
858 tx_cal[1] = tx_cal[2];
859 tx_cal[3] = tx_cal_flt_b[3] - 128;
3a4d1b90 860 tx_cal[0] = -tx_cal[3] + 1;
66101de1
PM
861
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]));
866
3a4d1b90
TT
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 } */
875
876 /* g. */
877 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
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);
3a4d1b90 884 } else /* 2nd-cut */{
66101de1
PM
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);
891
892 }
893
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]));
898
3a4d1b90
TT
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)))) {
66101de1
PM
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;
906 }
3a4d1b90
TT
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)))) {
66101de1
PM
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;
914 }
915 }
916
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]));
925
3a4d1b90 926 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
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;
3a4d1b90 935 } else /* 2nd-cut */{
66101de1
PM
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;
944 }
945
3a4d1b90 946 /* i. Set "calib_start" to 0x0 */
66101de1
PM
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));
950
951 loop--;
952 }
953
954 return 1;
955}
956
8e41b4b6 957void _tx_iq_calibration_winbond(struct hw_data *phw_data)
66101de1
PM
958{
959 u32 reg_agc_ctrl3;
960#ifdef _DEBUG
961 s32 tx_cal_reg[4];
962
963#endif
964 u32 reg_mode_ctrl;
965 u32 val;
966 u8 result;
967
968 PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
969
3a4d1b90 970 /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
66101de1 971 phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
3a4d1b90
TT
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 */
66101de1 979 phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
3a4d1b90
TT
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); */
66101de1 984
3a4d1b90
TT
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);
66101de1 988
3a4d1b90 989 /* a. Disable AGC */
66101de1
PM
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);
994
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);
998
999 result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
1000
3a4d1b90
TT
1001 if (result > 0) {
1002 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
1003 hw_get_dxx_reg(phw_data, 0x54, &val);
1004 val &= 0x0000FFFF;
1005 hw_set_dxx_reg(phw_data, 0x54, val);
3a4d1b90 1006 } else /* 2nd-cut*/{
66101de1
PM
1007 hw_get_dxx_reg(phw_data, 0x3C, &val);
1008 val &= 0x000003FF;
1009 hw_set_dxx_reg(phw_data, 0x3C, val);
1010 }
1011
1012 result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
1013
3a4d1b90
TT
1014 if (result > 0) {
1015 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
1016 hw_get_dxx_reg(phw_data, 0x54, &val);
1017 val &= 0x0000FFFF;
1018 hw_set_dxx_reg(phw_data, 0x54, val);
3a4d1b90 1019 } else /* 2nd-cut*/{
66101de1
PM
1020 hw_get_dxx_reg(phw_data, 0x3C, &val);
1021 val &= 0x000003FF;
1022 hw_set_dxx_reg(phw_data, 0x3C, val);
1023 }
1024
1025 result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
3a4d1b90
TT
1026 if (result > 0) {
1027 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
1028 hw_get_dxx_reg(phw_data, 0x54, &val);
1029 val &= 0x0000FFFF;
1030 hw_set_dxx_reg(phw_data, 0x54, val);
3a4d1b90 1031 } else /* 2nd-cut */{
66101de1
PM
1032 hw_get_dxx_reg(phw_data, 0x3C, &val);
1033 val &= 0x000003FF;
1034 hw_set_dxx_reg(phw_data, 0x3C, val);
1035 }
1036
1037
1038 result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
1039
3a4d1b90 1040 if (result > 0) {
66101de1
PM
1041 PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
1042 PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
1043 PHY_DEBUG(("[CAL] **************************************\n"));
1044
3a4d1b90 1045 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
1046 hw_get_dxx_reg(phw_data, 0x54, &val);
1047 val &= 0x0000FFFF;
1048 hw_set_dxx_reg(phw_data, 0x54, val);
3a4d1b90 1049 } else /* 2nd-cut */{
66101de1
PM
1050 hw_get_dxx_reg(phw_data, 0x3C, &val);
1051 val &= 0x000003FF;
1052 hw_set_dxx_reg(phw_data, 0x3C, val);
1053 }
1054 }
1055 }
1056 }
1057 }
1058
3a4d1b90 1059 /* i. Set "calib_start" to 0x0 */
66101de1
PM
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));
1064
3a4d1b90
TT
1065 /* g. Enable AGC */
1066 /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
66101de1
PM
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);
1070
1071#ifdef _DEBUG
3a4d1b90 1072 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
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);
3a4d1b90 1079 } else /* 2nd-cut */ {
66101de1
PM
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);
1086
1087 }
1088
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
1094
1095
3a4d1b90
TT
1096 /*
1097 * for test - BEN
1098 * RF Control Override
1099 */
66101de1
PM
1100}
1101
3a4d1b90 1102/*****************************************************/
8e41b4b6 1103u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
66101de1
PM
1104{
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;
1123
1124 u32 pwr_tone;
1125 u32 pwr_image;
1126 u8 verify_count;
1127
3a4d1b90
TT
1128 s32 iqcal_tone_i_avg, iqcal_tone_q_avg;
1129 s32 iqcal_image_i_avg, iqcal_image_q_avg;
1130 u16 capture_time;
66101de1
PM
1131
1132 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
1133 PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
1134
1135
3a4d1b90 1136/* RF Control Override */
66101de1
PM
1137 hw_get_cxx_reg(phw_data, 0x80, &val);
1138 val |= BIT(19);
1139 hw_set_cxx_reg(phw_data, 0x80, val);
1140
3a4d1b90 1141/* RF_Ctrl */
66101de1
PM
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));
1146
3a4d1b90 1147 hw_set_dxx_reg(phw_data, 0x58, 0x44444444); /* IQ_Alpha */
66101de1 1148
3a4d1b90 1149 /* b. */
66101de1
PM
1150
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));
1153
1154 verify_count = 0;
1155
3a4d1b90
TT
1156 /* for (loop = 0; loop < 1; loop++) */
1157 /* for (loop = 0; loop < LOOP_TIMES; loop++) */
66101de1 1158 loop = LOOP_TIMES;
3a4d1b90 1159 while (loop > 0) {
66101de1 1160 PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
3a4d1b90
TT
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;
1166
1167 for (capture_time = 0; capture_time < 10; capture_time++) {
1168 /* i. Set "calib_start" to 0x0 */
66101de1 1169 reg_mode_ctrl &= ~MASK_CALIB_START;
3a4d1b90 1170 if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */
66101de1
PM
1171 return 0;
1172 PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
66101de1
PM
1173
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));
66101de1 1178
3a4d1b90 1179 /* c. */
66101de1
PM
1180 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1181 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1182
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));
1187
1188 hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
1189 PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
1190
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));
3a4d1b90 1195 if (capture_time == 0)
66101de1 1196 continue;
3a4d1b90
TT
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;
66101de1
PM
1202 }
1203 }
1204
1205
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;
1210
3a4d1b90 1211 /* d. */
66101de1
PM
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;
1220
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));
1225
3a4d1b90
TT
1226 /* f. */
1227 if (rot_tone_i_b == 0) {
66101de1
PM
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;
1232 }
1233
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;
1238
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));
1243
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));
1248
3a4d1b90 1249 if (cos_2b == 0) {
66101de1
PM
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;
1254 }
1255
3a4d1b90 1256 /* 1280 * 32768 = 41943040 */
66101de1
PM
1257 temp1 = (41943040/cos_2b)*cos_b;
1258
3a4d1b90
TT
1259 /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
1260 if (phw_data->revision == 0x2002)/* 1st-cut */
66101de1 1261 temp2 = (41943040/cos_2b)*sin_b*(-1);
3a4d1b90 1262 else/* 2nd-cut */
66101de1 1263 temp2 = (41943040*4/cos_2b)*sin_b*(-1);
66101de1
PM
1264
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));
1269
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]));
1274
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]));
1283
3a4d1b90 1284 /* e. */
66101de1
PM
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;
1287
1288 PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone));
1289 PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image));
1290
3a4d1b90 1291 if (pwr_tone > pwr_image) {
66101de1
PM
1292 verify_count++;
1293
1294 PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
1295 PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
1296 PHY_DEBUG(("[CAL] ******************************************\n"));
1297
3a4d1b90 1298 if (verify_count > 2) {
66101de1
PM
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;
1303 }
1304
1305 continue;
1306 }
3a4d1b90 1307 /* g. */
66101de1
PM
1308 hw_get_dxx_reg(phw_data, 0x54, &val);
1309 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1310
3a4d1b90 1311 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
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));
3a4d1b90 1316 } else /* 2nd-cut */{
66101de1
PM
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);
1321 }
1322
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]));
1327
3a4d1b90
TT
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)))) {
66101de1
PM
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;
1335 }
3a4d1b90
TT
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)))) {
66101de1
PM
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;
1343 }
1344 }
1345
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]));
1354
1355 hw_get_dxx_reg(phw_data, 0x54, &val);
3a4d1b90 1356 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
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);
3a4d1b90 1363 } else /* 2nd-cut */{
66101de1
PM
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);
1370
3a4d1b90 1371 if (loop == 3)
66101de1
PM
1372 return 0;
1373 }
1374 PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
1375
1376 loop--;
1377 }
1378
1379 return 1;
1380}
1381
3a4d1b90 1382/*************************************************/
66101de1 1383
3a4d1b90 1384/***************************************************************/
8e41b4b6 1385void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
66101de1 1386{
3a4d1b90 1387/* figo 20050523 marked this flag for can't compile for relesase */
66101de1
PM
1388#ifdef _DEBUG
1389 s32 rx_cal_reg[4];
1390 u32 val;
1391#endif
1392
1393 u8 result;
1394
1395 PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
3a4d1b90
TT
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 */
66101de1 1399 phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
3a4d1b90 1400 /* 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuits */
66101de1 1401 phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
3a4d1b90
TT
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 */
66101de1 1405 phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
3a4d1b90 1406 /* 0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode */
66101de1
PM
1407 phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
1408
3a4d1b90
TT
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 */
66101de1
PM
1412
1413 result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
1414
3a4d1b90 1415 if (result > 0) {
66101de1
PM
1416 _reset_rx_cal(phw_data);
1417 result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
1418
3a4d1b90 1419 if (result > 0) {
66101de1
PM
1420 _reset_rx_cal(phw_data);
1421 result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
1422
3a4d1b90 1423 if (result > 0) {
66101de1
PM
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);
1428 }
1429 }
1430 }
1431
1432#ifdef _DEBUG
1433 hw_get_dxx_reg(phw_data, 0x54, &val);
1434 PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
1435
3a4d1b90 1436 if (phw_data->revision == 0x2002) /* 1st-cut */{
66101de1
PM
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));
3a4d1b90 1441 } else /* 2nd-cut */{
66101de1
PM
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);
1446 }
1447
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
1453
1454}
1455
3a4d1b90 1456/*******************************************************/
8e41b4b6 1457void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
66101de1
PM
1458{
1459 u32 reg_mode_ctrl;
1460 u32 iq_alpha;
1461
1462 PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
1463
3a4d1b90 1464 /* 20040701 1.1.25.1000 kevin */
66101de1
PM
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);
1468
1469
1470
1471 _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
3a4d1b90
TT
1472 /* _txidac_dc_offset_cancellation_winbond(phw_data); */
1473 /* _txqdac_dc_offset_cacellation_winbond(phw_data); */
66101de1
PM
1474
1475 _tx_iq_calibration_winbond(phw_data);
1476 _rx_iq_calibration_winbond(phw_data, frequency);
1477
3a4d1b90 1478 /*********************************************************************/
66101de1 1479 hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
3a4d1b90 1480 reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); /* set when finish */
66101de1
PM
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));
1483
3a4d1b90 1484 /* i. Set RFIC to "Normal mode" */
66101de1
PM
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);
1488
1489
3a4d1b90 1490 /*********************************************************************/
66101de1
PM
1491 phy_init_rf(phw_data);
1492
1493}
1494
3a4d1b90
TT
1495/******************/
1496void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value)
66101de1 1497{
2e04bb7b 1498 u32 ltmp = 0;
3a4d1b90
TT
1499
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;
1505
1506 case RF_MAXIM_2827:
1507 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1508 break;
1509
1510 case RF_MAXIM_2828:
1511 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1512 break;
1513
1514 case RF_MAXIM_2829:
1515 ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1516 break;
1517
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;
1522
1523 case RF_AIROHA_7230:
1524 ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
1525 break;
1526
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;
1531 }
66101de1 1532
3a4d1b90 1533 Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
66101de1
PM
1534}
1535
3a4d1b90 1536/* 20060717 modify as Bruce's mail */
8e41b4b6 1537unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
66101de1
PM
1538{
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;
3a4d1b90
TT
1546 u8 reg_state;
1547 int current_txvga;
66101de1
PM
1548
1549
1550 reg_state = 0;
3a4d1b90
TT
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));
66101de1
PM
1554 phw_data->txvga_setting_for_cal = current_txvga;
1555
3a4d1b90 1556 msleep(30);/* 20060612.1.a */
66101de1 1557
3a4d1b90 1558 if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl))/* 20060718.1 modify */
279b6ccc 1559 return false;
66101de1
PM
1560
1561 PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1562
3a4d1b90
TT
1563 /*
1564 * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1565 * enable "IQ alibration Mode II"
1566 */
66101de1
PM
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));
1573
3a4d1b90 1574 udelay(1);/* 20060612.1.a */
66101de1 1575
3a4d1b90 1576 udelay(300);/* 20060612.1.a */
66101de1 1577
3a4d1b90 1578 /* b. */
66101de1
PM
1579 hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1580
1581 PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
3a4d1b90 1582 udelay(300);/* 20060612.1.a */
66101de1
PM
1583
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));
1588
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));
1592
3a4d1b90 1593 if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
66101de1 1594 break;
3a4d1b90
TT
1595 else if (iq_mag_0_tx > 1750) {
1596 init_txvga = -2;
66101de1 1597 continue;
3a4d1b90 1598 } else
66101de1
PM
1599 continue;
1600
1601 }
1602
3a4d1b90 1603 if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
279b6ccc 1604 return true;
66101de1 1605 else
279b6ccc 1606 return false;
66101de1 1607}