1 /* $NetBSD: rtwphy.c,v 1.14 2008/03/03 12:30:57 tsutsui Exp $ */ 2 /*- 3 * Copyright (c) 2004, 2005 David Young. All rights reserved. 4 * 5 * Programmed for NetBSD by David Young. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of David Young may not be used to endorse or promote 16 * products derived from this software without specific prior 17 * written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 23 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 * OF SUCH DAMAGE. 31 */ 32 /* 33 * Control the Philips SA2400 RF front-end and the baseband processor 34 * built into the Realtek RTL8180. 35 */ 36 37 #include <sys/cdefs.h> 38 __KERNEL_RCSID(0, "$NetBSD: rtwphy.c,v 1.14 2008/03/03 12:30:57 tsutsui Exp $"); 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/types.h> 43 #include <sys/device.h> 44 45 #include <sys/bus.h> 46 47 #include <net/if.h> 48 #include <net/if_media.h> 49 #include <net/if_ether.h> 50 51 #include <net80211/ieee80211_netbsd.h> 52 #include <net80211/ieee80211_radiotap.h> 53 #include <net80211/ieee80211_var.h> 54 55 #include <dev/ic/rtwreg.h> 56 #include <dev/ic/max2820reg.h> 57 #include <dev/ic/sa2400reg.h> 58 #include <dev/ic/rtwvar.h> 59 #include <dev/ic/rtwphyio.h> 60 #include <dev/ic/rtwphy.h> 61 62 static int rtw_max2820_pwrstate(struct rtw_rf *, enum rtw_pwrstate); 63 static int rtw_sa2400_pwrstate(struct rtw_rf *, enum rtw_pwrstate); 64 65 #define GCT_WRITE(__gr, __addr, __val, __label) \ 66 do { \ 67 if (rtw_rfbus_write(&(__gr)->gr_bus, RTW_RFCHIPID_GCT, \ 68 (__addr), (__val)) == -1) \ 69 goto __label; \ 70 } while(0) 71 72 static int 73 rtw_bbp_preinit(struct rtw_regs *regs, u_int antatten0, int dflantb, 74 u_int freq) 75 { 76 u_int antatten = antatten0; 77 if (dflantb) 78 antatten |= RTW_BBP_ANTATTEN_DFLANTB; 79 if (freq == 2484) /* channel 14 */ 80 antatten |= RTW_BBP_ANTATTEN_CHAN14; 81 return rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten); 82 } 83 84 static int 85 rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv, 86 int dflantb, uint8_t cs_threshold, u_int freq) 87 { 88 int rc; 89 uint32_t sys2, sys3; 90 91 sys2 = bb->bb_sys2; 92 if (antdiv) 93 sys2 |= RTW_BBP_SYS2_ANTDIV; 94 sys3 = bb->bb_sys3 | 95 __SHIFTIN(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK); 96 97 #define RTW_BBP_WRITE_OR_RETURN(reg, val) \ 98 if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \ 99 return rc; 100 101 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1, bb->bb_sys1); 102 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC, bb->bb_txagc); 103 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET, bb->bb_lnadet); 104 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI, bb->bb_ifagcini); 105 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT, bb->bb_ifagclimit); 106 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET, bb->bb_ifagcdet); 107 108 if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0) 109 return rc; 110 111 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL, bb->bb_trl); 112 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2, sys2); 113 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3, sys3); 114 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM, bb->bb_chestlim); 115 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM, bb->bb_chsqlim); 116 return 0; 117 } 118 119 static int 120 rtw_sa2400_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 121 { 122 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 123 struct rtw_rfbus *bus = &sa->sa_bus; 124 125 return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_TX, 126 opaque_txpower); 127 } 128 129 /* make sure we're using the same settings as the reference driver */ 130 static void 131 verify_syna(u_int freq, uint32_t val) 132 { 133 uint32_t expected_val = ~val; 134 135 switch (freq) { 136 case 2412: 137 expected_val = 0x0000096c; /* ch 1 */ 138 break; 139 case 2417: 140 expected_val = 0x00080970; /* ch 2 */ 141 break; 142 case 2422: 143 expected_val = 0x00100974; /* ch 3 */ 144 break; 145 case 2427: 146 expected_val = 0x00180978; /* ch 4 */ 147 break; 148 case 2432: 149 expected_val = 0x00000980; /* ch 5 */ 150 break; 151 case 2437: 152 expected_val = 0x00080984; /* ch 6 */ 153 break; 154 case 2442: 155 expected_val = 0x00100988; /* ch 7 */ 156 break; 157 case 2447: 158 expected_val = 0x0018098c; /* ch 8 */ 159 break; 160 case 2452: 161 expected_val = 0x00000994; /* ch 9 */ 162 break; 163 case 2457: 164 expected_val = 0x00080998; /* ch 10 */ 165 break; 166 case 2462: 167 expected_val = 0x0010099c; /* ch 11 */ 168 break; 169 case 2467: 170 expected_val = 0x001809a0; /* ch 12 */ 171 break; 172 case 2472: 173 expected_val = 0x000009a8; /* ch 13 */ 174 break; 175 case 2484: 176 expected_val = 0x000009b4; /* ch 14 */ 177 break; 178 } 179 KASSERT(val == expected_val); 180 } 181 182 /* freq is in MHz */ 183 static int 184 rtw_sa2400_tune(struct rtw_rf *rf, u_int freq) 185 { 186 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 187 struct rtw_rfbus *bus = &sa->sa_bus; 188 int rc; 189 uint32_t syna, synb, sync; 190 191 /* XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz. 192 * 193 * The channel spacing (5MHz) is not divisible by 4MHz, so 194 * we set the fractional part of N to compensate. 195 */ 196 int n = freq / 4, nf = (freq % 4) * 2; 197 198 syna = __SHIFTIN(nf, SA2400_SYNA_NF_MASK) | __SHIFTIN(n, SA2400_SYNA_N_MASK); 199 verify_syna(freq, syna); 200 201 /* Divide the 44MHz crystal down to 4MHz. Set the fractional 202 * compensation charge pump value to agree with the fractional 203 * modulus. 204 */ 205 synb = __SHIFTIN(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL | 206 SA2400_SYNB_ON | SA2400_SYNB_ONE | 207 __SHIFTIN(80, SA2400_SYNB_FC_MASK); /* agrees w/ SA2400_SYNA_FM = 0 */ 208 209 sync = SA2400_SYNC_CP_NORMAL; 210 211 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNA, 212 syna)) != 0) 213 return rc; 214 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNB, 215 synb)) != 0) 216 return rc; 217 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNC, 218 sync)) != 0) 219 return rc; 220 return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYND, 0x0); 221 } 222 223 static int 224 rtw_sa2400_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 225 { 226 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 227 struct rtw_rfbus *bus = &sa->sa_bus; 228 uint32_t opmode; 229 opmode = SA2400_OPMODE_DEFAULTS; 230 switch (power) { 231 case RTW_ON: 232 opmode |= SA2400_OPMODE_MODE_TXRX; 233 break; 234 case RTW_SLEEP: 235 opmode |= SA2400_OPMODE_MODE_WAIT; 236 break; 237 case RTW_OFF: 238 opmode |= SA2400_OPMODE_MODE_SLEEP; 239 break; 240 } 241 242 if (sa->sa_digphy) 243 opmode |= SA2400_OPMODE_DIGIN; 244 245 return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 246 opmode); 247 } 248 249 static int 250 rtw_sa2400_manrx_init(struct rtw_sa2400 *sa) 251 { 252 uint32_t manrx; 253 254 /* XXX we are not supposed to be in RXMGC mode when we do 255 * this? 256 */ 257 manrx = SA2400_MANRX_AHSN; 258 manrx |= SA2400_MANRX_TEN; 259 manrx |= __SHIFTIN(1023, SA2400_MANRX_RXGAIN_MASK); 260 261 return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_MANRX, 262 manrx); 263 } 264 265 static int 266 rtw_sa2400_vcocal_start(struct rtw_sa2400 *sa, int start) 267 { 268 uint32_t opmode; 269 270 opmode = SA2400_OPMODE_DEFAULTS; 271 if (start) 272 opmode |= SA2400_OPMODE_MODE_VCOCALIB; 273 else 274 opmode |= SA2400_OPMODE_MODE_SLEEP; 275 276 if (sa->sa_digphy) 277 opmode |= SA2400_OPMODE_DIGIN; 278 279 return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 280 opmode); 281 } 282 283 static int 284 rtw_sa2400_vco_calibration(struct rtw_sa2400 *sa) 285 { 286 int rc; 287 /* calibrate VCO */ 288 if ((rc = rtw_sa2400_vcocal_start(sa, 1)) != 0) 289 return rc; 290 DELAY(2200); /* 2.2 milliseconds */ 291 /* XXX superfluous: SA2400 automatically entered SLEEP mode. */ 292 return rtw_sa2400_vcocal_start(sa, 0); 293 } 294 295 static int 296 rtw_sa2400_filter_calibration(struct rtw_sa2400 *sa) 297 { 298 uint32_t opmode; 299 300 opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB; 301 if (sa->sa_digphy) 302 opmode |= SA2400_OPMODE_DIGIN; 303 304 return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 305 opmode); 306 } 307 308 static int 309 rtw_sa2400_dc_calibration(struct rtw_sa2400 *sa) 310 { 311 struct rtw_rf *rf = &sa->sa_rf; 312 int rc; 313 uint32_t dccal; 314 315 (*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 1); 316 317 dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX; 318 319 rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 320 dccal); 321 if (rc != 0) 322 return rc; 323 324 DELAY(5); /* DCALIB after being in Tx mode for 5 325 * microseconds 326 */ 327 328 dccal &= ~SA2400_OPMODE_MODE_MASK; 329 dccal |= SA2400_OPMODE_MODE_DCALIB; 330 331 rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 332 dccal); 333 if (rc != 0) 334 return rc; 335 336 DELAY(20); /* calibration takes at most 20 microseconds */ 337 338 (*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 0); 339 340 return 0; 341 } 342 343 static int 344 rtw_sa2400_agc_init(struct rtw_sa2400 *sa) 345 { 346 uint32_t agc; 347 348 agc = __SHIFTIN(25, SA2400_AGC_MAXGAIN_MASK); 349 agc |= __SHIFTIN(7, SA2400_AGC_BBPDELAY_MASK); 350 agc |= __SHIFTIN(15, SA2400_AGC_LNADELAY_MASK); 351 agc |= __SHIFTIN(27, SA2400_AGC_RXONDELAY_MASK); 352 353 return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_AGC, 354 agc); 355 } 356 357 static void 358 rtw_sa2400_destroy(struct rtw_rf *rf) 359 { 360 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 361 memset(sa, 0, sizeof(*sa)); 362 free(sa, M_DEVBUF); 363 } 364 365 static int 366 rtw_sa2400_calibrate(struct rtw_rf *rf, u_int freq) 367 { 368 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 369 int i, rc; 370 371 /* XXX reference driver calibrates VCO twice. Is it a bug? */ 372 for (i = 0; i < 2; i++) { 373 if ((rc = rtw_sa2400_vco_calibration(sa)) != 0) 374 return rc; 375 } 376 /* VCO calibration erases synthesizer registers, so re-tune */ 377 if ((rc = rtw_sa2400_tune(rf, freq)) != 0) 378 return rc; 379 if ((rc = rtw_sa2400_filter_calibration(sa)) != 0) 380 return rc; 381 /* analog PHY needs DC calibration */ 382 if (!sa->sa_digphy) 383 return rtw_sa2400_dc_calibration(sa); 384 return 0; 385 } 386 387 static int 388 rtw_sa2400_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower, 389 enum rtw_pwrstate power) 390 { 391 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 392 int rc; 393 394 if ((rc = rtw_sa2400_txpower(rf, opaque_txpower)) != 0) 395 return rc; 396 397 /* skip configuration if it's time to sleep or to power-down. */ 398 if (power == RTW_SLEEP || power == RTW_OFF) 399 return rtw_sa2400_pwrstate(rf, power); 400 401 /* go to sleep for configuration */ 402 if ((rc = rtw_sa2400_pwrstate(rf, RTW_SLEEP)) != 0) 403 return rc; 404 405 if ((rc = rtw_sa2400_tune(rf, freq)) != 0) 406 return rc; 407 if ((rc = rtw_sa2400_agc_init(sa)) != 0) 408 return rc; 409 if ((rc = rtw_sa2400_manrx_init(sa)) != 0) 410 return rc; 411 if ((rc = rtw_sa2400_calibrate(rf, freq)) != 0) 412 return rc; 413 414 /* enter Tx/Rx mode */ 415 return rtw_sa2400_pwrstate(rf, power); 416 } 417 418 struct rtw_rf * 419 rtw_sa2400_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy) 420 { 421 struct rtw_sa2400 *sa; 422 struct rtw_rfbus *bus; 423 struct rtw_rf *rf; 424 struct rtw_bbpset *bb; 425 426 sa = malloc(sizeof(*sa), M_DEVBUF, M_NOWAIT | M_ZERO); 427 if (sa == NULL) 428 return NULL; 429 430 sa->sa_digphy = digphy; 431 432 rf = &sa->sa_rf; 433 bus = &sa->sa_bus; 434 435 rf->rf_init = rtw_sa2400_init; 436 rf->rf_destroy = rtw_sa2400_destroy; 437 rf->rf_txpower = rtw_sa2400_txpower; 438 rf->rf_tune = rtw_sa2400_tune; 439 rf->rf_pwrstate = rtw_sa2400_pwrstate; 440 bb = &rf->rf_bbpset; 441 442 /* XXX magic */ 443 bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC; 444 bb->bb_chestlim = 0x00; 445 bb->bb_chsqlim = 0xa0; 446 bb->bb_ifagcdet = 0x64; 447 bb->bb_ifagcini = 0x90; 448 bb->bb_ifagclimit = 0x1a; 449 bb->bb_lnadet = 0xe0; 450 bb->bb_sys1 = 0x98; 451 bb->bb_sys2 = 0x47; 452 bb->bb_sys3 = 0x90; 453 bb->bb_trl = 0x88; 454 bb->bb_txagc = 0x38; 455 456 bus->b_regs = regs; 457 bus->b_write = rf_write; 458 459 return &sa->sa_rf; 460 } 461 462 static int 463 rtw_grf5101_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 464 { 465 struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 466 467 GCT_WRITE(gr, 0x15, 0, err); 468 GCT_WRITE(gr, 0x06, opaque_txpower, err); 469 GCT_WRITE(gr, 0x15, 0x10, err); 470 GCT_WRITE(gr, 0x15, 0x00, err); 471 return 0; 472 err: 473 return -1; 474 } 475 476 static int 477 rtw_grf5101_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 478 { 479 struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 480 switch (power) { 481 case RTW_OFF: 482 case RTW_SLEEP: 483 GCT_WRITE(gr, 0x07, 0x0000, err); 484 GCT_WRITE(gr, 0x1f, 0x0045, err); 485 GCT_WRITE(gr, 0x1f, 0x0005, err); 486 GCT_WRITE(gr, 0x00, 0x08e4, err); 487 default: 488 break; 489 case RTW_ON: 490 GCT_WRITE(gr, 0x1f, 0x0001, err); 491 DELAY(10); 492 GCT_WRITE(gr, 0x1f, 0x0001, err); 493 DELAY(10); 494 GCT_WRITE(gr, 0x1f, 0x0041, err); 495 DELAY(10); 496 GCT_WRITE(gr, 0x1f, 0x0061, err); 497 DELAY(10); 498 GCT_WRITE(gr, 0x00, 0x0ae4, err); 499 DELAY(10); 500 GCT_WRITE(gr, 0x07, 0x1000, err); 501 DELAY(100); 502 break; 503 } 504 505 return 0; 506 err: 507 return -1; 508 } 509 510 static int 511 rtw_grf5101_tune(struct rtw_rf *rf, u_int freq) 512 { 513 int channel; 514 struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 515 516 if (freq == 2484) 517 channel = 14; 518 else if ((channel = (freq - 2412) / 5 + 1) < 1 || channel > 13) { 519 RTW_DPRINTF(RTW_DEBUG_PHY, 520 ("%s: invalid channel %d (freq %d)\n", __func__, channel, 521 freq)); 522 return -1; 523 } 524 525 GCT_WRITE(gr, 0x07, 0, err); 526 GCT_WRITE(gr, 0x0b, channel - 1, err); 527 GCT_WRITE(gr, 0x07, 0x1000, err); 528 return 0; 529 err: 530 return -1; 531 } 532 533 static int 534 rtw_grf5101_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower, 535 enum rtw_pwrstate power) 536 { 537 int rc; 538 struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 539 540 /* 541 * These values have been derived from the rtl8180-sa2400 542 * Linux driver. It is unknown what they all do, GCT refuse 543 * to release any documentation so these are more than 544 * likely sub optimal settings 545 */ 546 547 GCT_WRITE(gr, 0x01, 0x1a23, err); 548 GCT_WRITE(gr, 0x02, 0x4971, err); 549 GCT_WRITE(gr, 0x03, 0x41de, err); 550 GCT_WRITE(gr, 0x04, 0x2d80, err); 551 552 GCT_WRITE(gr, 0x05, 0x61ff, err); 553 554 GCT_WRITE(gr, 0x06, 0x0, err); 555 556 GCT_WRITE(gr, 0x08, 0x7533, err); 557 GCT_WRITE(gr, 0x09, 0xc401, err); 558 GCT_WRITE(gr, 0x0a, 0x0, err); 559 GCT_WRITE(gr, 0x0c, 0x1c7, err); 560 GCT_WRITE(gr, 0x0d, 0x29d3, err); 561 GCT_WRITE(gr, 0x0e, 0x2e8, err); 562 GCT_WRITE(gr, 0x10, 0x192, err); 563 GCT_WRITE(gr, 0x11, 0x248, err); 564 GCT_WRITE(gr, 0x12, 0x0, err); 565 GCT_WRITE(gr, 0x13, 0x20c4, err); 566 GCT_WRITE(gr, 0x14, 0xf4fc, err); 567 GCT_WRITE(gr, 0x15, 0x0, err); 568 GCT_WRITE(gr, 0x16, 0x1500, err); 569 570 if ((rc = rtw_grf5101_txpower(rf, opaque_txpower)) != 0) 571 return rc; 572 573 if ((rc = rtw_grf5101_tune(rf, freq)) != 0) 574 return rc; 575 576 return 0; 577 err: 578 return -1; 579 } 580 581 static void 582 rtw_grf5101_destroy(struct rtw_rf *rf) 583 { 584 struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 585 memset(gr, 0, sizeof(*gr)); 586 free(gr, M_DEVBUF); 587 } 588 589 struct rtw_rf * 590 rtw_grf5101_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, 591 int digphy) 592 { 593 struct rtw_grf5101 *gr; 594 struct rtw_rfbus *bus; 595 struct rtw_rf *rf; 596 struct rtw_bbpset *bb; 597 598 gr = malloc(sizeof(*gr), M_DEVBUF, M_NOWAIT | M_ZERO); 599 if (gr == NULL) 600 return NULL; 601 602 rf = &gr->gr_rf; 603 bus = &gr->gr_bus; 604 605 rf->rf_init = rtw_grf5101_init; 606 rf->rf_destroy = rtw_grf5101_destroy; 607 rf->rf_txpower = rtw_grf5101_txpower; 608 rf->rf_tune = rtw_grf5101_tune; 609 rf->rf_pwrstate = rtw_grf5101_pwrstate; 610 bb = &rf->rf_bbpset; 611 612 /* XXX magic */ 613 bb->bb_antatten = RTW_BBP_ANTATTEN_GCT_MAGIC; 614 bb->bb_chestlim = 0x00; 615 bb->bb_chsqlim = 0xa0; 616 bb->bb_ifagcdet = 0x64; 617 bb->bb_ifagcini = 0x90; 618 bb->bb_ifagclimit = 0x1e; 619 bb->bb_lnadet = 0xc0; 620 bb->bb_sys1 = 0xa8; 621 bb->bb_sys2 = 0x47; 622 bb->bb_sys3 = 0x9b; 623 bb->bb_trl = 0x88; 624 bb->bb_txagc = 0x08; 625 626 bus->b_regs = regs; 627 bus->b_write = rf_write; 628 629 return &gr->gr_rf; 630 } 631 632 /* freq is in MHz */ 633 static int 634 rtw_max2820_tune(struct rtw_rf *rf, u_int freq) 635 { 636 struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 637 struct rtw_rfbus *bus = &mx->mx_bus; 638 639 if (freq < 2400 || freq > 2499) 640 return -1; 641 642 return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_CHANNEL, 643 __SHIFTIN(freq - 2400, MAX2820_CHANNEL_CF_MASK)); 644 } 645 646 static void 647 rtw_max2820_destroy(struct rtw_rf *rf) 648 { 649 struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 650 memset(mx, 0, sizeof(*mx)); 651 free(mx, M_DEVBUF); 652 } 653 654 static int 655 rtw_max2820_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower, 656 enum rtw_pwrstate power) 657 { 658 struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 659 struct rtw_rfbus *bus = &mx->mx_bus; 660 int rc; 661 662 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TEST, 663 MAX2820_TEST_DEFAULT)) != 0) 664 return rc; 665 666 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE, 667 MAX2820_ENABLE_DEFAULT)) != 0) 668 return rc; 669 670 /* skip configuration if it's time to sleep or to power-down. */ 671 if ((rc = rtw_max2820_pwrstate(rf, power)) != 0) 672 return rc; 673 else if (power == RTW_OFF || power == RTW_SLEEP) 674 return 0; 675 676 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_SYNTH, 677 MAX2820_SYNTH_R_44MHZ)) != 0) 678 return rc; 679 680 if ((rc = rtw_max2820_tune(rf, freq)) != 0) 681 return rc; 682 683 /* XXX The MAX2820 datasheet indicates that 1C and 2C should not 684 * be changed from 7, however, the reference driver sets them 685 * to 4 and 1, respectively. 686 */ 687 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_RECEIVE, 688 MAX2820_RECEIVE_DL_DEFAULT | 689 __SHIFTIN(4, MAX2820A_RECEIVE_1C_MASK) | 690 __SHIFTIN(1, MAX2820A_RECEIVE_2C_MASK))) != 0) 691 return rc; 692 693 return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TRANSMIT, 694 MAX2820_TRANSMIT_PA_DEFAULT); 695 } 696 697 static int 698 rtw_max2820_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 699 { 700 /* TBD */ 701 return 0; 702 } 703 704 static int 705 rtw_max2820_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 706 { 707 uint32_t enable; 708 struct rtw_max2820 *mx; 709 struct rtw_rfbus *bus; 710 711 mx = (struct rtw_max2820 *)rf; 712 bus = &mx->mx_bus; 713 714 switch (power) { 715 case RTW_OFF: 716 case RTW_SLEEP: 717 default: 718 enable = 0x0; 719 break; 720 case RTW_ON: 721 enable = MAX2820_ENABLE_DEFAULT; 722 break; 723 } 724 return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE, enable); 725 } 726 727 struct rtw_rf * 728 rtw_max2820_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int is_a) 729 { 730 struct rtw_max2820 *mx; 731 struct rtw_rfbus *bus; 732 struct rtw_rf *rf; 733 struct rtw_bbpset *bb; 734 735 mx = malloc(sizeof(*mx), M_DEVBUF, M_NOWAIT | M_ZERO); 736 if (mx == NULL) 737 return NULL; 738 739 mx->mx_is_a = is_a; 740 741 rf = &mx->mx_rf; 742 bus = &mx->mx_bus; 743 744 rf->rf_init = rtw_max2820_init; 745 rf->rf_destroy = rtw_max2820_destroy; 746 rf->rf_txpower = rtw_max2820_txpower; 747 rf->rf_tune = rtw_max2820_tune; 748 rf->rf_pwrstate = rtw_max2820_pwrstate; 749 bb = &rf->rf_bbpset; 750 751 /* XXX magic */ 752 bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC; 753 bb->bb_chestlim = 0; 754 bb->bb_chsqlim = 159; 755 bb->bb_ifagcdet = 100; 756 bb->bb_ifagcini = 144; 757 bb->bb_ifagclimit = 26; 758 bb->bb_lnadet = 248; 759 bb->bb_sys1 = 136; 760 bb->bb_sys2 = 71; 761 bb->bb_sys3 = 155; 762 bb->bb_trl = 136; 763 bb->bb_txagc = 8; 764 765 bus->b_regs = regs; 766 bus->b_write = rf_write; 767 768 return &mx->mx_rf; 769 } 770 771 /* freq is in MHz */ 772 int 773 rtw_phy_init(struct rtw_regs *regs, struct rtw_rf *rf, uint8_t opaque_txpower, 774 uint8_t cs_threshold, u_int freq, int antdiv, int dflantb, 775 enum rtw_pwrstate power) 776 { 777 int rc; 778 RTW_DPRINTF(RTW_DEBUG_PHY, 779 ("%s: txpower %u csthresh %u freq %u antdiv %u dflantb %u " 780 "pwrstate %s\n", __func__, opaque_txpower, cs_threshold, freq, 781 antdiv, dflantb, rtw_pwrstate_string(power))); 782 783 /* XXX is this really necessary? */ 784 if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0) 785 return rc; 786 if ((rc = rtw_bbp_preinit(regs, rf->rf_bbpset.bb_antatten, dflantb, 787 freq)) != 0) 788 return rc; 789 if ((rc = rtw_rf_tune(rf, freq)) != 0) 790 return rc; 791 /* initialize RF */ 792 if ((rc = rtw_rf_init(rf, freq, opaque_txpower, power)) != 0) 793 return rc; 794 #if 0 /* what is this redundant tx power setting here for? */ 795 if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0) 796 return rc; 797 #endif 798 return rtw_bbp_init(regs, &rf->rf_bbpset, antdiv, dflantb, 799 cs_threshold, freq); 800 } 801