Root/drivers/staging/winbond/phy_calibration.c

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
29static 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
45s32 _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
57u32 _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/****************************************************************************/
72s32 _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
84u32 _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/****************************************************************************/
99s32 _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
111u32 _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/****************************************************************************/
126s32 _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
138u32 _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/****************************************************************************/
153s32 _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
165u32 _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/****************************************************************************/
180s32 _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 */
196u32 _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/****************************************************************************/
264void _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
299static 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
307static 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
319void _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/**********************************************/
339void _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/****************************************************************/
434void _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/*****************************************************/
559void _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 */
675u8 _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
958void _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/*****************************************************/
1104u8 _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/***************************************************************/
1374void _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/*******************************************************/
1446void 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/******************/
1477void 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 */
1518unsigned 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

Archive Download this file



interactive