Commit | Line | Data |
---|---|---|
66101de1 PM |
1 | /* |
2 | * phy_302_calibration.c | |
3 | * | |
4 | * Copyright (C) 2002, 2005 Winbond Electronics Corp. | |
5 | * | |
6 | * modification history | |
7 | * --------------------------------------------------------------------------- | |
8 | * 0.01.001, 2003-04-16, Kevin created | |
9 | * | |
10 | */ | |
11 | ||
12 | /****************** INCLUDE FILES SECTION ***********************************/ | |
66101de1 | 13 | #include "phy_calibration.h" |
b5ef0761 | 14 | #include "wbhal.h" |
72ca8819 PE |
15 | #include "wb35reg_f.h" |
16 | #include "core.h" | |
66101de1 PM |
17 | |
18 | ||
19 | /****************** DEBUG CONSTANT AND MACRO SECTION ************************/ | |
20 | ||
21 | /****************** LOCAL CONSTANT AND MACRO SECTION ************************/ | |
22 | #define LOOP_TIMES 20 | |
3a4d1b90 | 23 | #define US 1000/* MICROSECOND*/ |
66101de1 PM |
24 | |
25 | #define AG_CONST 0.6072529350 | |
26 | #define FIXED(X) ((s32)((X) * 32768.0)) | |
af69c294 | 27 | #define DEG2RAD(X) (0.017453 * (X)) |
66101de1 | 28 | |
3a4d1b90 | 29 | static const s32 Angles[] = { |
74417297 CC |
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)) | |
66101de1 PM |
34 | }; |
35 | ||
2e04bb7b | 36 | /****************** LOCAL FUNCTION DECLARATION SECTION **********************/ |
3a4d1b90 TT |
37 | |
38 | /* | |
39 | * void _phy_rf_write_delay(struct hw_data *phw_data); | |
40 | * void phy_init_rf(struct hw_data *phw_data); | |
41 | */ | |
66101de1 PM |
42 | |
43 | /****************** FUNCTION DEFINITION SECTION *****************************/ | |
44 | ||
45 | s32 _s13_to_s32(u32 data) | |
46 | { | |
919ed52f | 47 | u32 val; |
66101de1 | 48 | |
919ed52f | 49 | val = (data & 0x0FFF); |
66101de1 | 50 | |
919ed52f AJ |
51 | if ((data & BIT(12)) != 0) |
52 | val |= 0xFFFFF000; | |
66101de1 | 53 | |
af69c294 | 54 | return (s32) val; |
66101de1 PM |
55 | } |
56 | ||
57 | u32 _s32_to_s13(s32 data) | |
58 | { | |
919ed52f | 59 | u32 val; |
66101de1 | 60 | |
919ed52f AJ |
61 | if (data > 4095) |
62 | data = 4095; | |
63 | else if (data < -4096) | |
64 | data = -4096; | |
66101de1 | 65 | |
919ed52f | 66 | val = data & 0x1FFF; |
66101de1 | 67 | |
919ed52f | 68 | return val; |
66101de1 PM |
69 | } |
70 | ||
71 | /****************************************************************************/ | |
72 | s32 _s4_to_s32(u32 data) | |
73 | { | |
919ed52f | 74 | s32 val; |
66101de1 | 75 | |
919ed52f | 76 | val = (data & 0x0007); |
66101de1 | 77 | |
919ed52f AJ |
78 | if ((data & BIT(3)) != 0) |
79 | val |= 0xFFFFFFF8; | |
66101de1 | 80 | |
919ed52f | 81 | return val; |
66101de1 PM |
82 | } |
83 | ||
84 | u32 _s32_to_s4(s32 data) | |
85 | { | |
919ed52f | 86 | u32 val; |
66101de1 | 87 | |
919ed52f AJ |
88 | if (data > 7) |
89 | data = 7; | |
90 | else if (data < -8) | |
91 | data = -8; | |
66101de1 | 92 | |
919ed52f | 93 | val = data & 0x000F; |
66101de1 | 94 | |
919ed52f | 95 | return val; |
66101de1 PM |
96 | } |
97 | ||
98 | /****************************************************************************/ | |
99 | s32 _s5_to_s32(u32 data) | |
100 | { | |
919ed52f | 101 | s32 val; |
66101de1 | 102 | |
919ed52f | 103 | val = (data & 0x000F); |
66101de1 | 104 | |
919ed52f AJ |
105 | if ((data & BIT(4)) != 0) |
106 | val |= 0xFFFFFFF0; | |
66101de1 | 107 | |
919ed52f | 108 | return val; |
66101de1 PM |
109 | } |
110 | ||
111 | u32 _s32_to_s5(s32 data) | |
112 | { | |
919ed52f | 113 | u32 val; |
66101de1 | 114 | |
919ed52f AJ |
115 | if (data > 15) |
116 | data = 15; | |
117 | else if (data < -16) | |
118 | data = -16; | |
66101de1 | 119 | |
919ed52f | 120 | val = data & 0x001F; |
66101de1 | 121 | |
919ed52f | 122 | return val; |
66101de1 PM |
123 | } |
124 | ||
125 | /****************************************************************************/ | |
126 | s32 _s6_to_s32(u32 data) | |
127 | { | |
919ed52f | 128 | s32 val; |
66101de1 | 129 | |
919ed52f | 130 | val = (data & 0x001F); |
66101de1 | 131 | |
919ed52f AJ |
132 | if ((data & BIT(5)) != 0) |
133 | val |= 0xFFFFFFE0; | |
66101de1 | 134 | |
919ed52f | 135 | return val; |
66101de1 PM |
136 | } |
137 | ||
138 | u32 _s32_to_s6(s32 data) | |
139 | { | |
919ed52f | 140 | u32 val; |
66101de1 | 141 | |
919ed52f AJ |
142 | if (data > 31) |
143 | data = 31; | |
144 | else if (data < -32) | |
145 | data = -32; | |
66101de1 | 146 | |
919ed52f | 147 | val = data & 0x003F; |
66101de1 | 148 | |
919ed52f | 149 | return val; |
66101de1 PM |
150 | } |
151 | ||
152 | /****************************************************************************/ | |
153 | s32 _s9_to_s32(u32 data) | |
154 | { | |
919ed52f | 155 | s32 val; |
66101de1 | 156 | |
919ed52f | 157 | val = data & 0x00FF; |
66101de1 | 158 | |
919ed52f AJ |
159 | if ((data & BIT(8)) != 0) |
160 | val |= 0xFFFFFF00; | |
66101de1 | 161 | |
919ed52f | 162 | return val; |
66101de1 PM |
163 | } |
164 | ||
165 | u32 _s32_to_s9(s32 data) | |
166 | { | |
919ed52f | 167 | u32 val; |
66101de1 | 168 | |
919ed52f AJ |
169 | if (data > 255) |
170 | data = 255; | |
171 | else if (data < -256) | |
172 | data = -256; | |
66101de1 | 173 | |
919ed52f | 174 | val = data & 0x01FF; |
66101de1 | 175 | |
919ed52f | 176 | return val; |
66101de1 PM |
177 | } |
178 | ||
179 | /****************************************************************************/ | |
180 | s32 _floor(s32 n) | |
181 | { | |
919ed52f AJ |
182 | if (n > 0) |
183 | n += 5; | |
184 | else | |
185 | n -= 5; | |
66101de1 | 186 | |
af69c294 | 187 | return n/10; |
66101de1 PM |
188 | } |
189 | ||
190 | /****************************************************************************/ | |
3a4d1b90 TT |
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 | */ | |
66101de1 PM |
196 | u32 _sqrt(u32 sqsum) |
197 | { | |
919ed52f AJ |
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; | |
66101de1 PM |
261 | } |
262 | ||
263 | /****************************************************************************/ | |
264 | void _sin_cos(s32 angle, s32 *sin, s32 *cos) | |
265 | { | |
919ed52f AJ |
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 | } | |
66101de1 PM |
297 | } |
298 | ||
dd68e1b4 PE |
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 | } | |
3a4d1b90 | 305 | #define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C) |
dd68e1b4 PE |
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 | } | |
3a4d1b90 | 316 | #define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C) |
dd68e1b4 | 317 | |
66101de1 | 318 | |
8e41b4b6 | 319 | void _reset_rx_cal(struct hw_data *phw_data) |
66101de1 PM |
320 | { |
321 | u32 val; | |
322 | ||
323 | hw_get_dxx_reg(phw_data, 0x54, &val); | |
324 | ||
3a4d1b90 | 325 | if (phw_data->revision == 0x2002) /* 1st-cut */ |
66101de1 | 326 | val &= 0xFFFF0000; |
3a4d1b90 | 327 | else /* 2nd-cut */ |
66101de1 | 328 | val &= 0x000003FF; |
66101de1 PM |
329 | |
330 | hw_set_dxx_reg(phw_data, 0x54, val); | |
331 | } | |
332 | ||
333 | ||
3a4d1b90 TT |
334 | /**************for winbond calibration*********/ |
335 | ||
336 | ||
66101de1 | 337 | |
3a4d1b90 | 338 | /**********************************************/ |
8e41b4b6 | 339 | void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency) |
66101de1 | 340 | { |
919ed52f AJ |
341 | u32 reg_agc_ctrl3; |
342 | u32 reg_a_acq_ctrl; | |
343 | u32 reg_b_acq_ctrl; | |
344 | u32 val; | |
66101de1 | 345 | |
919ed52f AJ |
346 | PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n")); |
347 | phy_init_rf(phw_data); | |
66101de1 | 348 | |
919ed52f AJ |
349 | /* set calibration channel */ |
350 | if ((RF_WB_242 == phw_data->phy_type) || | |
3a4d1b90 | 351 | (RF_WB_242_1 == phw_data->phy_type)) /* 20060619.5 Add */{ |
919ed52f AJ |
352 | if ((frequency >= 2412) && (frequency <= 2484)) { |
353 | /* w89rf242 change frequency to 2390Mhz */ | |
354 | PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n")); | |
66101de1 PM |
355 | phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); |
356 | ||
919ed52f AJ |
357 | } |
358 | } else { | |
66101de1 PM |
359 | |
360 | } | |
361 | ||
3a4d1b90 | 362 | /* reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */ |
66101de1 PM |
363 | hw_get_dxx_reg(phw_data, 0x5C, &val); |
364 | val &= ~(0x03FF); | |
365 | hw_set_dxx_reg(phw_data, 0x5C, val); | |
366 | ||
3a4d1b90 | 367 | /* reset the TX and RX IQ calibration data */ |
66101de1 PM |
368 | hw_set_dxx_reg(phw_data, 0x3C, 0); |
369 | hw_set_dxx_reg(phw_data, 0x54, 0); | |
370 | ||
3a4d1b90 | 371 | hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */ |
66101de1 | 372 | |
3a4d1b90 | 373 | /* a. Disable AGC */ |
66101de1 PM |
374 | hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_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 | ||
3a4d1b90 | 383 | /* b. Turn off BB RX */ |
66101de1 PM |
384 | hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_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, ®_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 | ||
3a4d1b90 TT |
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 */ | |
66101de1 PM |
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); | |
66101de1 | 401 | |
3a4d1b90 | 402 | /* e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */ |
66101de1 PM |
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 | ||
3a4d1b90 TT |
417 | /* f. Turn on BB RX */ |
418 | /* hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_a_acq_ctrl); */ | |
66101de1 PM |
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 | ||
3a4d1b90 | 422 | /* hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, ®_b_acq_ctrl); */ |
66101de1 PM |
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 | ||
3a4d1b90 TT |
426 | /* g. Enable AGC */ |
427 | /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */ | |
66101de1 PM |
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 | ||
3a4d1b90 | 433 | /****************************************************************/ |
8e41b4b6 | 434 | void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data) |
66101de1 PM |
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 | ||
3a4d1b90 | 450 | /* a. Set to "TX calibration mode" */ |
66101de1 | 451 | |
3a4d1b90 | 452 | /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */ |
66101de1 | 453 | phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2); |
3a4d1b90 | 454 | /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */ |
66101de1 | 455 | phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6); |
3a4d1b90 | 456 | /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */ |
66101de1 | 457 | phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A); |
af69c294 | 458 | /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ |
66101de1 | 459 | phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C); |
3a4d1b90 | 460 | /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */ |
66101de1 PM |
461 | phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); |
462 | ||
3a4d1b90 | 463 | hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */ |
66101de1 | 464 | |
3a4d1b90 | 465 | /* a. Disable AGC */ |
66101de1 PM |
466 | hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_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 | ||
3a4d1b90 | 475 | /* b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 */ |
66101de1 PM |
476 | hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_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 | ||
3a4d1b90 TT |
481 | /* mode=2, tone=0 */ |
482 | /* reg_mode_ctrl |= (MASK_CALIB_START|2); */ | |
66101de1 | 483 | |
3a4d1b90 TT |
484 | /* mode=2, tone=1 */ |
485 | /* reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); */ | |
66101de1 | 486 | |
3a4d1b90 | 487 | /* mode=2, tone=2 */ |
66101de1 PM |
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)); | |
66101de1 PM |
491 | |
492 | hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel); | |
493 | PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel)); | |
494 | ||
3a4d1b90 | 495 | for (loop = 0; loop < LOOP_TIMES; loop++) { |
66101de1 PM |
496 | PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop)); |
497 | ||
3a4d1b90 | 498 | /* c. reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */ |
66101de1 PM |
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); | |
66101de1 PM |
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 | ||
3a4d1b90 | 513 | /* d. */ |
66101de1 PM |
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); | |
66101de1 PM |
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 | ||
3a4d1b90 | 528 | /* e. Calculate the correct DC offset cancellation value for I */ |
66101de1 | 529 | if (mag_0 != mag_1) |
66101de1 | 530 | fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000); |
3a4d1b90 | 531 | else { |
66101de1 | 532 | if (mag_0 == mag_1) |
66101de1 | 533 | PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n")); |
66101de1 PM |
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) | |
66101de1 | 541 | break; |
66101de1 PM |
542 | } |
543 | ||
3a4d1b90 | 544 | if (loop >= 19) |
919ed52f | 545 | fix_cancel_dc_i = 0; |
66101de1 PM |
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 | ||
3a4d1b90 | 552 | /* g. */ |
66101de1 PM |
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)); | |
66101de1 PM |
556 | } |
557 | ||
3a4d1b90 | 558 | /*****************************************************/ |
8e41b4b6 | 559 | void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data) |
66101de1 PM |
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")); | |
3a4d1b90 | 574 | /*0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */ |
66101de1 | 575 | phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2); |
3a4d1b90 | 576 | /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */ |
66101de1 | 577 | phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6); |
3a4d1b90 | 578 | /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */ |
66101de1 | 579 | phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A); |
af69c294 | 580 | /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ |
66101de1 | 581 | phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C); |
3a4d1b90 | 582 | /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */ |
66101de1 PM |
583 | phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); |
584 | ||
3a4d1b90 | 585 | hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */ |
66101de1 | 586 | |
3a4d1b90 | 587 | /* a. Disable AGC */ |
66101de1 PM |
588 | hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_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 | ||
3a4d1b90 | 597 | /* a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 */ |
66101de1 PM |
598 | hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); |
599 | PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); | |
600 | ||
3a4d1b90 | 601 | /* reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); */ |
66101de1 PM |
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)); | |
66101de1 PM |
606 | |
607 | hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel); | |
608 | PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel)); | |
609 | ||
3a4d1b90 | 610 | for (loop = 0; loop < LOOP_TIMES; loop++) { |
66101de1 PM |
611 | PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop)); |
612 | ||
3a4d1b90 | 613 | /* b. reset cancel_dc_q[4:0] in register DC_Cancel */ |
66101de1 PM |
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); | |
66101de1 PM |
617 | |
618 | hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); | |
619 | PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); | |
66101de1 PM |
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 | ||
3a4d1b90 | 628 | /* c. */ |
66101de1 PM |
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); | |
66101de1 PM |
632 | |
633 | hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); | |
634 | PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); | |
66101de1 PM |
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 | ||
3a4d1b90 | 643 | /* d. Calculate the correct DC offset cancellation value for I */ |
66101de1 | 644 | if (mag_0 != mag_1) |
66101de1 | 645 | fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000); |
3a4d1b90 | 646 | else { |
66101de1 | 647 | if (mag_0 == mag_1) |
66101de1 | 648 | PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n")); |
66101de1 PM |
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) | |
66101de1 | 656 | break; |
66101de1 PM |
657 | } |
658 | ||
3a4d1b90 | 659 | if (loop >= 19) |
919ed52f | 660 | fix_cancel_dc_q = 0; |
66101de1 PM |
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 | ||
3a4d1b90 | 668 | /* f. */ |
66101de1 PM |
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)); | |
66101de1 PM |
672 | } |
673 | ||
3a4d1b90 | 674 | /* 20060612.1.a 20060718.1 Modify */ |
8e41b4b6 | 675 | u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data, |
66101de1 PM |
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; | |
3a4d1b90 | 698 | s32 iqcal_tone_i_avg, iqcal_tone_q_avg; |
66101de1 PM |
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, ®_mode_ctrl); | |
709 | PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); | |
710 | ||
711 | loop = LOOP_TIMES; | |
712 | ||
3a4d1b90 | 713 | while (loop > 0) { |
66101de1 PM |
714 | PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1))); |
715 | ||
3a4d1b90 TT |
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 */ | |
66101de1 | 719 | return 0; |
3a4d1b90 TT |
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 | */ | |
66101de1 PM |
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)); | |
66101de1 | 731 | |
3a4d1b90 | 732 | /* b. */ |
66101de1 PM |
733 | hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); |
734 | PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); | |
66101de1 PM |
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 | ||
3a4d1b90 | 746 | /* c. Set "calib_start" to 0x0 */ |
66101de1 PM |
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)); | |
66101de1 | 750 | |
3a4d1b90 TT |
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); */ | |
66101de1 PM |
756 | hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_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)); | |
66101de1 | 761 | |
3a4d1b90 | 762 | /* e. */ |
66101de1 PM |
763 | hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); |
764 | PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); | |
66101de1 PM |
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)); | |
3a4d1b90 | 770 | if (capture_time == 0) |
66101de1 | 771 | continue; |
3a4d1b90 TT |
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; | |
66101de1 PM |
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 | ||
3a4d1b90 | 789 | /* f. */ |
66101de1 PM |
790 | divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2; |
791 | ||
3a4d1b90 | 792 | if (divisor == 0) { |
66101de1 PM |
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 | ||
3a4d1b90 TT |
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)) { | |
66101de1 PM |
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 | ||
3a4d1b90 | 816 | if (verify_count > 2) { |
66101de1 PM |
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; | |
3a4d1b90 | 824 | } else |
66101de1 | 825 | verify_count = 0; |
66101de1 PM |
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 | ||
3a4d1b90 | 832 | if (cos_2b == 0) { |
66101de1 PM |
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 | ||
3a4d1b90 | 839 | /* 1280 * 32768 = 41943040 */ |
66101de1 PM |
840 | temp1 = (41943040/cos_2b)*cos_b; |
841 | ||
3a4d1b90 TT |
842 | /* temp2 = (41943040/cos_2b)*sin_b*(-1); */ |
843 | if (phw_data->revision == 0x2002) /* 1st-cut */ | |
66101de1 | 844 | temp2 = (41943040/cos_2b)*sin_b*(-1); |
3a4d1b90 | 845 | else /* 2nd-cut */ |
66101de1 | 846 | temp2 = (41943040*4/cos_2b)*sin_b*(-1); |
66101de1 PM |
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]; | |
3a4d1b90 | 858 | tx_cal[2] = tx_cal[2] + 3; |
66101de1 PM |
859 | tx_cal[1] = tx_cal[2]; |
860 | tx_cal[3] = tx_cal_flt_b[3] - 128; | |
3a4d1b90 | 861 | tx_cal[0] = -tx_cal[3] + 1; |
66101de1 PM |
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 | ||
3a4d1b90 TT |
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 */{ | |
66101de1 PM |
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); | |
3a4d1b90 | 885 | } else /* 2nd-cut */{ |
66101de1 PM |
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 | ||
3a4d1b90 TT |
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)))) { | |
66101de1 PM |
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 | } | |
3a4d1b90 TT |
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)))) { | |
66101de1 PM |
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 | ||
3a4d1b90 | 927 | if (phw_data->revision == 0x2002) /* 1st-cut */{ |
66101de1 PM |
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; | |
3a4d1b90 | 936 | } else /* 2nd-cut */{ |
66101de1 PM |
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 | ||
3a4d1b90 | 947 | /* i. Set "calib_start" to 0x0 */ |
66101de1 PM |
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 | ||
8e41b4b6 | 958 | void _tx_iq_calibration_winbond(struct hw_data *phw_data) |
66101de1 PM |
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 | ||
3a4d1b90 | 971 | /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */ |
66101de1 | 972 | phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2); |
3a4d1b90 TT |
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) */ | |
af69c294 | 977 | /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ |
3a4d1b90 TT |
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 */ | |
66101de1 | 980 | phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); |
3a4d1b90 TT |
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); */ | |
66101de1 | 985 | |
3a4d1b90 TT |
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); | |
66101de1 | 989 | |
3a4d1b90 | 990 | /* a. Disable AGC */ |
66101de1 PM |
991 | hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_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 | ||
3a4d1b90 TT |
1002 | if (result > 0) { |
1003 | if (phw_data->revision == 0x2002) /* 1st-cut */{ | |
66101de1 PM |
1004 | hw_get_dxx_reg(phw_data, 0x54, &val); |
1005 | val &= 0x0000FFFF; | |
1006 | hw_set_dxx_reg(phw_data, 0x54, val); | |
3a4d1b90 | 1007 | } else /* 2nd-cut*/{ |
66101de1 PM |
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 | ||
3a4d1b90 TT |
1015 | if (result > 0) { |
1016 | if (phw_data->revision == 0x2002) /* 1st-cut */{ | |
66101de1 PM |
1017 | hw_get_dxx_reg(phw_data, 0x54, &val); |
1018 | val &= 0x0000FFFF; | |
1019 | hw_set_dxx_reg(phw_data, 0x54, val); | |
3a4d1b90 | 1020 | } else /* 2nd-cut*/{ |
66101de1 PM |
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); | |
3a4d1b90 TT |
1027 | if (result > 0) { |
1028 | if (phw_data->revision == 0x2002) /* 1st-cut */{ | |
66101de1 PM |
1029 | hw_get_dxx_reg(phw_data, 0x54, &val); |
1030 | val &= 0x0000FFFF; | |
1031 | hw_set_dxx_reg(phw_data, 0x54, val); | |
3a4d1b90 | 1032 | } else /* 2nd-cut */{ |
66101de1 PM |
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 | ||
3a4d1b90 | 1041 | if (result > 0) { |
66101de1 PM |
1042 | PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n")); |
1043 | PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n")); | |
1044 | PHY_DEBUG(("[CAL] **************************************\n")); | |
1045 | ||
3a4d1b90 | 1046 | if (phw_data->revision == 0x2002) /* 1st-cut */{ |
66101de1 PM |
1047 | hw_get_dxx_reg(phw_data, 0x54, &val); |
1048 | val &= 0x0000FFFF; | |
1049 | hw_set_dxx_reg(phw_data, 0x54, val); | |
3a4d1b90 | 1050 | } else /* 2nd-cut */{ |
66101de1 PM |
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 | ||
3a4d1b90 | 1060 | /* i. Set "calib_start" to 0x0 */ |
66101de1 PM |
1061 | hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_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 | ||
3a4d1b90 TT |
1066 | /* g. Enable AGC */ |
1067 | /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */ | |
66101de1 PM |
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 | |
3a4d1b90 | 1073 | if (phw_data->revision == 0x2002) /* 1st-cut */{ |
66101de1 PM |
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); | |
3a4d1b90 | 1080 | } else /* 2nd-cut */ { |
66101de1 PM |
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 | ||
3a4d1b90 TT |
1097 | /* |
1098 | * for test - BEN | |
1099 | * RF Control Override | |
1100 | */ | |
66101de1 PM |
1101 | } |
1102 | ||
3a4d1b90 | 1103 | /*****************************************************/ |
8e41b4b6 | 1104 | u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency) |
66101de1 PM |
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 | ||
3a4d1b90 TT |
1129 | s32 iqcal_tone_i_avg, iqcal_tone_q_avg; |
1130 | s32 iqcal_image_i_avg, iqcal_image_q_avg; | |
1131 | u16 capture_time; | |
66101de1 PM |
1132 | |
1133 | PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n")); | |
1134 | PHY_DEBUG(("[CAL] ** factor = %d\n", factor)); | |
1135 | ||
3a4d1b90 | 1136 | hw_set_dxx_reg(phw_data, 0x58, 0x44444444); /* IQ_Alpha */ |
66101de1 | 1137 | |
3a4d1b90 | 1138 | /* b. */ |
66101de1 PM |
1139 | |
1140 | hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); | |
1141 | PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); | |
1142 | ||
1143 | verify_count = 0; | |
1144 | ||
3a4d1b90 TT |
1145 | /* for (loop = 0; loop < 1; loop++) */ |
1146 | /* for (loop = 0; loop < LOOP_TIMES; loop++) */ | |
66101de1 | 1147 | loop = LOOP_TIMES; |
3a4d1b90 | 1148 | while (loop > 0) { |
66101de1 | 1149 | PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1))); |
3a4d1b90 TT |
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++) { | |
919ed52f AJ |
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)); | |
66101de1 | 1162 | |
919ed52f AJ |
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)); | |
66101de1 | 1167 | |
919ed52f AJ |
1168 | /* c. */ |
1169 | hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); | |
1170 | PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); | |
66101de1 | 1171 | |
919ed52f AJ |
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)); | |
66101de1 | 1176 | |
919ed52f AJ |
1177 | hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); |
1178 | PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); | |
66101de1 | 1179 | |
919ed52f AJ |
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)); | |
3a4d1b90 | 1184 | if (capture_time == 0) |
66101de1 | 1185 | continue; |
3a4d1b90 TT |
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; | |
66101de1 PM |
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 | ||
3a4d1b90 | 1200 | /* d. */ |
66101de1 PM |
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 | ||
3a4d1b90 TT |
1215 | /* f. */ |
1216 | if (rot_tone_i_b == 0) { | |
66101de1 PM |
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 | ||
3a4d1b90 | 1238 | if (cos_2b == 0) { |
66101de1 PM |
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 | ||
3a4d1b90 | 1245 | /* 1280 * 32768 = 41943040 */ |
66101de1 PM |
1246 | temp1 = (41943040/cos_2b)*cos_b; |
1247 | ||
3a4d1b90 TT |
1248 | /* temp2 = (41943040/cos_2b)*sin_b*(-1); */ |
1249 | if (phw_data->revision == 0x2002)/* 1st-cut */ | |
66101de1 | 1250 | temp2 = (41943040/cos_2b)*sin_b*(-1); |
3a4d1b90 | 1251 | else/* 2nd-cut */ |
66101de1 | 1252 | temp2 = (41943040*4/cos_2b)*sin_b*(-1); |
66101de1 PM |
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 | ||
3a4d1b90 | 1273 | /* e. */ |
66101de1 PM |
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 | ||
3a4d1b90 | 1280 | if (pwr_tone > pwr_image) { |
66101de1 PM |
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 | ||
3a4d1b90 | 1287 | if (verify_count > 2) { |
66101de1 PM |
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 | } | |
3a4d1b90 | 1296 | /* g. */ |
66101de1 PM |
1297 | hw_get_dxx_reg(phw_data, 0x54, &val); |
1298 | PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val)); | |
1299 | ||
3a4d1b90 | 1300 | if (phw_data->revision == 0x2002) /* 1st-cut */{ |
66101de1 PM |
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)); | |
3a4d1b90 | 1305 | } else /* 2nd-cut */{ |
66101de1 PM |
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 | ||
3a4d1b90 TT |
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)))) { | |
66101de1 PM |
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 | } | |
3a4d1b90 TT |
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)))) { | |
66101de1 PM |
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); | |
3a4d1b90 | 1345 | if (phw_data->revision == 0x2002) /* 1st-cut */{ |
66101de1 PM |
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); | |
3a4d1b90 | 1352 | } else /* 2nd-cut */{ |
66101de1 PM |
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 | ||
3a4d1b90 | 1360 | if (loop == 3) |
919ed52f | 1361 | return 0; |
66101de1 PM |
1362 | } |
1363 | PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val)); | |
1364 | ||
1365 | loop--; | |
1366 | } | |
1367 | ||
1368 | return 1; | |
1369 | } | |
1370 | ||
3a4d1b90 | 1371 | /*************************************************/ |
66101de1 | 1372 | |
3a4d1b90 | 1373 | /***************************************************************/ |
8e41b4b6 | 1374 | void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency) |
66101de1 | 1375 | { |
3a4d1b90 | 1376 | /* figo 20050523 marked this flag for can't compile for relesase */ |
66101de1 PM |
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")); | |
3a4d1b90 TT |
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 */ | |
66101de1 | 1388 | phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2); |
3a4d1b90 | 1389 | /* 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuits */ |
66101de1 | 1390 | phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6); |
3a4d1b90 TT |
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 */ | |
66101de1 | 1394 | phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C); |
3a4d1b90 | 1395 | /* 0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode */ |
66101de1 PM |
1396 | phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0); |
1397 | ||
3a4d1b90 TT |
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 */ | |
66101de1 PM |
1401 | |
1402 | result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency); | |
1403 | ||
3a4d1b90 | 1404 | if (result > 0) { |
66101de1 PM |
1405 | _reset_rx_cal(phw_data); |
1406 | result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency); | |
1407 | ||
3a4d1b90 | 1408 | if (result > 0) { |
66101de1 PM |
1409 | _reset_rx_cal(phw_data); |
1410 | result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency); | |
1411 | ||
3a4d1b90 | 1412 | if (result > 0) { |
66101de1 PM |
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 | ||
3a4d1b90 | 1425 | if (phw_data->revision == 0x2002) /* 1st-cut */{ |
66101de1 PM |
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)); | |
3a4d1b90 | 1430 | } else /* 2nd-cut */{ |
66101de1 PM |
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 | ||
3a4d1b90 | 1445 | /*******************************************************/ |
8e41b4b6 | 1446 | void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency) |
66101de1 PM |
1447 | { |
1448 | u32 reg_mode_ctrl; | |
1449 | u32 iq_alpha; | |
1450 | ||
1451 | PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n")); | |
1452 | ||
66101de1 PM |
1453 | hw_get_dxx_reg(phw_data, 0x58, &iq_alpha); |
1454 | ||
66101de1 | 1455 | _rxadc_dc_offset_cancellation_winbond(phw_data, frequency); |
3a4d1b90 TT |
1456 | /* _txidac_dc_offset_cancellation_winbond(phw_data); */ |
1457 | /* _txqdac_dc_offset_cacellation_winbond(phw_data); */ | |
66101de1 PM |
1458 | |
1459 | _tx_iq_calibration_winbond(phw_data); | |
1460 | _rx_iq_calibration_winbond(phw_data, frequency); | |
1461 | ||
3a4d1b90 | 1462 | /*********************************************************************/ |
66101de1 | 1463 | hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); |
3a4d1b90 | 1464 | reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); /* set when finish */ |
66101de1 PM |
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 | ||
3a4d1b90 | 1468 | /* i. Set RFIC to "Normal mode" */ |
66101de1 PM |
1469 | hw_set_dxx_reg(phw_data, 0x58, iq_alpha); |
1470 | ||
3a4d1b90 | 1471 | /*********************************************************************/ |
66101de1 PM |
1472 | phy_init_rf(phw_data); |
1473 | ||
1474 | } | |
1475 | ||
3a4d1b90 TT |
1476 | /******************/ |
1477 | void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value) | |
66101de1 | 1478 | { |
919ed52f AJ |
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 | } | |
66101de1 | 1513 | |
3a4d1b90 | 1514 | Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); |
66101de1 PM |
1515 | } |
1516 | ||
3a4d1b90 | 1517 | /* 20060717 modify as Bruce's mail */ |
8e41b4b6 | 1518 | unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data) |
66101de1 PM |
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; | |
3a4d1b90 TT |
1527 | u8 reg_state; |
1528 | int current_txvga; | |
66101de1 PM |
1529 | |
1530 | ||
1531 | reg_state = 0; | |
3a4d1b90 TT |
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)); | |
66101de1 PM |
1535 | phw_data->txvga_setting_for_cal = current_txvga; |
1536 | ||
3a4d1b90 | 1537 | msleep(30);/* 20060612.1.a */ |
66101de1 | 1538 | |
3a4d1b90 | 1539 | if (!hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl))/* 20060718.1 modify */ |
279b6ccc | 1540 | return false; |
66101de1 PM |
1541 | |
1542 | PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); | |
1543 | ||
3a4d1b90 TT |
1544 | /* |
1545 | * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to | |
1546 | * enable "IQ alibration Mode II" | |
1547 | */ | |
66101de1 PM |
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 | ||
3a4d1b90 | 1555 | udelay(1);/* 20060612.1.a */ |
66101de1 | 1556 | |
3a4d1b90 | 1557 | udelay(300);/* 20060612.1.a */ |
66101de1 | 1558 | |
3a4d1b90 | 1559 | /* b. */ |
66101de1 PM |
1560 | hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); |
1561 | ||
1562 | PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); | |
3a4d1b90 | 1563 | udelay(300);/* 20060612.1.a */ |
66101de1 PM |
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 | ||
3a4d1b90 | 1574 | if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750) |
66101de1 | 1575 | break; |
3a4d1b90 TT |
1576 | else if (iq_mag_0_tx > 1750) { |
1577 | init_txvga = -2; | |
66101de1 | 1578 | continue; |
3a4d1b90 | 1579 | } else |
66101de1 PM |
1580 | continue; |
1581 | ||
1582 | } | |
1583 | ||
3a4d1b90 | 1584 | if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750) |
279b6ccc | 1585 | return true; |
66101de1 | 1586 | else |
279b6ccc | 1587 | return false; |
66101de1 | 1588 | } |