Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
phy_calibration.c
Go to the documentation of this file.
1 /*
2  * phy_302_calibration.c
3  *
4  * Copyright (C) 2002, 2005 Winbond Electronics Corp.
5  *
6  * modification history
7  * ---------------------------------------------------------------------------
8  * 0.01.001, 2003-04-16, Kevin created
9  *
10  */
11 
12 /****************** INCLUDE FILES SECTION ***********************************/
13 #include "phy_calibration.h"
14 #include "wbhal.h"
15 #include "wb35reg_f.h"
16 #include "core.h"
17 
18 
19 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
20 
21 /****************** LOCAL CONSTANT AND MACRO SECTION ************************/
22 #define LOOP_TIMES 20
23 #define US 1000/* MICROSECOND*/
24 
25 #define AG_CONST 0.6072529350
26 #define FIXED(X) ((s32)((X) * 32768.0))
27 #define DEG2RAD(X) (0.017453 * (X))
28 
29 static const s32 Angles[] = {
30  FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)),
31  FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
32  FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
33  FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
34 };
35 
36 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
37 
38 /*
39  * void _phy_rf_write_delay(struct hw_data *phw_data);
40  * void phy_init_rf(struct hw_data *phw_data);
41  */
42 
43 /****************** FUNCTION DEFINITION SECTION *****************************/
44 
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 
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 /****************************************************************************/
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 
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 /****************************************************************************/
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 
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 /****************************************************************************/
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 
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 /****************************************************************************/
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 
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 /****************************************************************************/
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  */
196 u32 _sqrt(u32 sqsum)
197 {
198  u32 sq_rt;
199 
200  int g0, g1, g2, g3, g4;
201  int seed;
202  int next;
203  int step;
204 
205  g4 = sqsum / 100000000;
206  g3 = (sqsum - g4*100000000) / 1000000;
207  g2 = (sqsum - g4*100000000 - g3*1000000) / 10000;
208  g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100;
209  g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
210 
211  next = g4;
212  step = 0;
213  seed = 0;
214  while (((seed+1)*(step+1)) <= next) {
215  step++;
216  seed++;
217  }
218 
219  sq_rt = seed * 10000;
220  next = (next-(seed*step))*100 + g3;
221 
222  step = 0;
223  seed = 2 * seed * 10;
224  while (((seed+1)*(step+1)) <= next) {
225  step++;
226  seed++;
227  }
228 
229  sq_rt = sq_rt + step * 1000;
230  next = (next - seed * step) * 100 + g2;
231  seed = (seed + step) * 10;
232  step = 0;
233  while (((seed+1)*(step+1)) <= next) {
234  step++;
235  seed++;
236  }
237 
238  sq_rt = sq_rt + step * 100;
239  next = (next - seed * step) * 100 + g1;
240  seed = (seed + step) * 10;
241  step = 0;
242 
243  while (((seed+1)*(step+1)) <= next) {
244  step++;
245  seed++;
246  }
247 
248  sq_rt = sq_rt + step * 10;
249  next = (next - seed * step) * 100 + g0;
250  seed = (seed + step) * 10;
251  step = 0;
252 
253  while (((seed+1)*(step+1)) <= next) {
254  step++;
255  seed++;
256  }
257 
258  sq_rt = sq_rt + step;
259 
260  return sq_rt;
261 }
262 
263 /****************************************************************************/
264 void _sin_cos(s32 angle, s32 *sin, s32 *cos)
265 {
266  s32 X, Y, TargetAngle, CurrAngle;
267  unsigned Step;
268 
269  X = FIXED(AG_CONST); /* AG_CONST * cos(0) */
270  Y = 0; /* AG_CONST * sin(0) */
271  TargetAngle = abs(angle);
272  CurrAngle = 0;
273 
274  for (Step = 0; Step < 12; Step++) {
275  s32 NewX;
276 
277  if (TargetAngle > CurrAngle) {
278  NewX = X - (Y >> Step);
279  Y = (X >> Step) + Y;
280  X = NewX;
281  CurrAngle += Angles[Step];
282  } else {
283  NewX = X + (Y >> Step);
284  Y = -(X >> Step) + Y;
285  X = NewX;
286  CurrAngle -= Angles[Step];
287  }
288  }
289 
290  if (angle > 0) {
291  *cos = X;
292  *sin = Y;
293  } else {
294  *cos = X;
295  *sin = -Y;
296  }
297 }
298 
299 static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue)
300 {
301  if (number < 0x1000)
302  number += 0x1000;
303  return Wb35Reg_ReadSync(pHwData, number, pValue);
304 }
305 #define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
306 
307 static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
308 {
309  unsigned char ret;
310 
311  if (number < 0x1000)
312  number += 0x1000;
313  ret = Wb35Reg_WriteSync(pHwData, number, value);
314  return ret;
315 }
316 #define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
317 
318 
319 void _reset_rx_cal(struct hw_data *phw_data)
320 {
321  u32 val;
322 
323  hw_get_dxx_reg(phw_data, 0x54, &val);
324 
325  if (phw_data->revision == 0x2002) /* 1st-cut */
326  val &= 0xFFFF0000;
327  else /* 2nd-cut */
328  val &= 0x000003FF;
329 
330  hw_set_dxx_reg(phw_data, 0x54, val);
331 }
332 
333 
334 /**************for winbond calibration*********/
335 
336 
337 
338 /**********************************************/
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 results 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 /****************************************************************/
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 /*****************************************************/
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 */
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 calibration 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 calibration 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 
958 void _tx_iq_calibration_winbond(struct hw_data *phw_data)
959 {
960  u32 reg_agc_ctrl3;
961 #ifdef _DEBUG
962  s32 tx_cal_reg[4];
963 
964 #endif
965  u32 reg_mode_ctrl;
966  u32 val;
967  u8 result;
968 
969  PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
970 
971  /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
972  phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
973  /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
974  phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); /* 20060612.1.a 0x1905D6); */
975  /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
976  phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); /* 0x24C60A (high temperature) */
977  /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
978  phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); /* 20060612.1.a 0x06890C); */
979  /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */
980  phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
981  /* ; [BB-chip]: Calibration (6f).Send test pattern */
982  /* ; [BB-chip]: Calibration (6g). Search RXGCL optimal value */
983  /* ; [BB-chip]: Calibration (6h). Calculate 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 /*****************************************************/
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 /***************************************************************/
1375 {
1376 /* figo 20050523 marked this flag for can't compile for release */
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). Calculate 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 /*******************************************************/
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_cancellation_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 /******************/
1477 void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value)
1478 {
1479  u32 ltmp = 0;
1480 
1481  switch (pHwData->phy_type) {
1482  case RF_MAXIM_2825:
1483  case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */
1484  ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1485  break;
1486 
1487  case RF_MAXIM_2827:
1488  ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1489  break;
1490 
1491  case RF_MAXIM_2828:
1492  ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1493  break;
1494 
1495  case RF_MAXIM_2829:
1496  ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18);
1497  break;
1498 
1499  case RF_AIROHA_2230:
1500  case RF_AIROHA_2230S: /* 20060420 Add this */
1501  ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20);
1502  break;
1503 
1504  case RF_AIROHA_7230:
1505  ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
1506  break;
1507 
1508  case RF_WB_242:
1509  case RF_WB_242_1:/* 20060619.5 Add */
1510  ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24);
1511  break;
1512  }
1513 
1514  Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
1515 }
1516 
1517 /* 20060717 modify as Bruce's mail */
1518 unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
1519 {
1520  int init_txvga = 0;
1521  u32 reg_mode_ctrl;
1522  u32 val;
1523  s32 iqcal_tone_i0;
1524  s32 iqcal_tone_q0;
1525  u32 sqsum;
1526  s32 iq_mag_0_tx;
1527  u8 reg_state;
1528  int current_txvga;
1529 
1530 
1531  reg_state = 0;
1532  for (init_txvga = 0; init_txvga < 10; init_txvga++) {
1533  current_txvga = (0x24C40A|(init_txvga<<6));
1534  phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga));
1535  phw_data->txvga_setting_for_cal = current_txvga;
1536 
1537  msleep(30);/* 20060612.1.a */
1538 
1539  if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl))/* 20060718.1 modify */
1540  return false;
1541 
1542  PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
1543 
1544  /*
1545  * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
1546  * enable "IQ alibration Mode II"
1547  */
1548  reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
1549  reg_mode_ctrl &= ~MASK_IQCAL_MODE;
1550  reg_mode_ctrl |= (MASK_CALIB_START|0x02);
1551  reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
1552  hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
1553  PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
1554 
1555  udelay(1);/* 20060612.1.a */
1556 
1557  udelay(300);/* 20060612.1.a */
1558 
1559  /* b. */
1560  hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
1561 
1562  PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
1563  udelay(300);/* 20060612.1.a */
1564 
1565  iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
1566  iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
1567  PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
1568  iqcal_tone_i0, iqcal_tone_q0));
1569 
1570  sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
1571  iq_mag_0_tx = (s32) _sqrt(sqsum);
1572  PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
1573 
1574  if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1575  break;
1576  else if (iq_mag_0_tx > 1750) {
1577  init_txvga = -2;
1578  continue;
1579  } else
1580  continue;
1581 
1582  }
1583 
1584  if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
1585  return true;
1586  else
1587  return false;
1588 }