linux/drivers/staging/winbond/phy_calibration.c
<<
>>
Prefs
   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