1 /* $NetBSD: rtwphy.c,v 1.14 2008/03/03 12:30:57 tsutsui Exp $ */
3 * Copyright (c) 2004, 2005 David Young. All rights reserved.
5 * Programmed for NetBSD by David Young.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
16 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David
20 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 * Control the Philips SA2400 RF front-end and the baseband processor
31 * built into the Realtek RTL8180.
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: rtwphy.c,v 1.14 2008/03/03 12:30:57 tsutsui Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/types.h>
40 #include <sys/device.h>
45 #include <net/if_media.h>
46 #include <net/if_ether.h>
48 #include <net80211/ieee80211_netbsd.h>
49 #include <net80211/ieee80211_radiotap.h>
50 #include <net80211/ieee80211_var.h>
52 #include <dev/ic/rtwreg.h>
53 #include <dev/ic/max2820reg.h>
54 #include <dev/ic/sa2400reg.h>
55 #include <dev/ic/rtwvar.h>
56 #include <dev/ic/rtwphyio.h>
57 #include <dev/ic/rtwphy.h>
59 static int rtw_max2820_pwrstate(struct rtw_rf
*, enum rtw_pwrstate
);
60 static int rtw_sa2400_pwrstate(struct rtw_rf
*, enum rtw_pwrstate
);
62 #define GCT_WRITE(__gr, __addr, __val, __label) \
64 if (rtw_rfbus_write(&(__gr)->gr_bus, RTW_RFCHIPID_GCT, \
65 (__addr), (__val)) == -1) \
70 rtw_bbp_preinit(struct rtw_regs
*regs
, u_int antatten0
, int dflantb
,
73 u_int antatten
= antatten0
;
75 antatten
|= RTW_BBP_ANTATTEN_DFLANTB
;
76 if (freq
== 2484) /* channel 14 */
77 antatten
|= RTW_BBP_ANTATTEN_CHAN14
;
78 return rtw_bbp_write(regs
, RTW_BBP_ANTATTEN
, antatten
);
82 rtw_bbp_init(struct rtw_regs
*regs
, struct rtw_bbpset
*bb
, int antdiv
,
83 int dflantb
, uint8_t cs_threshold
, u_int freq
)
90 sys2
|= RTW_BBP_SYS2_ANTDIV
;
92 __SHIFTIN(cs_threshold
, RTW_BBP_SYS3_CSTHRESH_MASK
);
94 #define RTW_BBP_WRITE_OR_RETURN(reg, val) \
95 if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \
98 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1
, bb
->bb_sys1
);
99 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC
, bb
->bb_txagc
);
100 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET
, bb
->bb_lnadet
);
101 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI
, bb
->bb_ifagcini
);
102 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT
, bb
->bb_ifagclimit
);
103 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET
, bb
->bb_ifagcdet
);
105 if ((rc
= rtw_bbp_preinit(regs
, bb
->bb_antatten
, dflantb
, freq
)) != 0)
108 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL
, bb
->bb_trl
);
109 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2
, sys2
);
110 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3
, sys3
);
111 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM
, bb
->bb_chestlim
);
112 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM
, bb
->bb_chsqlim
);
117 rtw_sa2400_txpower(struct rtw_rf
*rf
, uint8_t opaque_txpower
)
119 struct rtw_sa2400
*sa
= (struct rtw_sa2400
*)rf
;
120 struct rtw_rfbus
*bus
= &sa
->sa_bus
;
122 return rtw_rfbus_write(bus
, RTW_RFCHIPID_PHILIPS
, SA2400_TX
,
126 /* make sure we're using the same settings as the reference driver */
128 verify_syna(u_int freq
, uint32_t val
)
130 uint32_t expected_val
= ~val
;
134 expected_val
= 0x0000096c; /* ch 1 */
137 expected_val
= 0x00080970; /* ch 2 */
140 expected_val
= 0x00100974; /* ch 3 */
143 expected_val
= 0x00180978; /* ch 4 */
146 expected_val
= 0x00000980; /* ch 5 */
149 expected_val
= 0x00080984; /* ch 6 */
152 expected_val
= 0x00100988; /* ch 7 */
155 expected_val
= 0x0018098c; /* ch 8 */
158 expected_val
= 0x00000994; /* ch 9 */
161 expected_val
= 0x00080998; /* ch 10 */
164 expected_val
= 0x0010099c; /* ch 11 */
167 expected_val
= 0x001809a0; /* ch 12 */
170 expected_val
= 0x000009a8; /* ch 13 */
173 expected_val
= 0x000009b4; /* ch 14 */
176 KASSERT(val
== expected_val
);
181 rtw_sa2400_tune(struct rtw_rf
*rf
, u_int freq
)
183 struct rtw_sa2400
*sa
= (struct rtw_sa2400
*)rf
;
184 struct rtw_rfbus
*bus
= &sa
->sa_bus
;
186 uint32_t syna
, synb
, sync
;
188 /* XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz.
190 * The channel spacing (5MHz) is not divisible by 4MHz, so
191 * we set the fractional part of N to compensate.
193 int n
= freq
/ 4, nf
= (freq
% 4) * 2;
195 syna
= __SHIFTIN(nf
, SA2400_SYNA_NF_MASK
) | __SHIFTIN(n
, SA2400_SYNA_N_MASK
);
196 verify_syna(freq
, syna
);
198 /* Divide the 44MHz crystal down to 4MHz. Set the fractional
199 * compensation charge pump value to agree with the fractional
202 synb
= __SHIFTIN(11, SA2400_SYNB_R_MASK
) | SA2400_SYNB_L_NORMAL
|
203 SA2400_SYNB_ON
| SA2400_SYNB_ONE
|
204 __SHIFTIN(80, SA2400_SYNB_FC_MASK
); /* agrees w/ SA2400_SYNA_FM = 0 */
206 sync
= SA2400_SYNC_CP_NORMAL
;
208 if ((rc
= rtw_rfbus_write(bus
, RTW_RFCHIPID_PHILIPS
, SA2400_SYNA
,
211 if ((rc
= rtw_rfbus_write(bus
, RTW_RFCHIPID_PHILIPS
, SA2400_SYNB
,
214 if ((rc
= rtw_rfbus_write(bus
, RTW_RFCHIPID_PHILIPS
, SA2400_SYNC
,
217 return rtw_rfbus_write(bus
, RTW_RFCHIPID_PHILIPS
, SA2400_SYND
, 0x0);
221 rtw_sa2400_pwrstate(struct rtw_rf
*rf
, enum rtw_pwrstate power
)
223 struct rtw_sa2400
*sa
= (struct rtw_sa2400
*)rf
;
224 struct rtw_rfbus
*bus
= &sa
->sa_bus
;
226 opmode
= SA2400_OPMODE_DEFAULTS
;
229 opmode
|= SA2400_OPMODE_MODE_TXRX
;
232 opmode
|= SA2400_OPMODE_MODE_WAIT
;
235 opmode
|= SA2400_OPMODE_MODE_SLEEP
;
240 opmode
|= SA2400_OPMODE_DIGIN
;
242 return rtw_rfbus_write(bus
, RTW_RFCHIPID_PHILIPS
, SA2400_OPMODE
,
247 rtw_sa2400_manrx_init(struct rtw_sa2400
*sa
)
251 /* XXX we are not supposed to be in RXMGC mode when we do
254 manrx
= SA2400_MANRX_AHSN
;
255 manrx
|= SA2400_MANRX_TEN
;
256 manrx
|= __SHIFTIN(1023, SA2400_MANRX_RXGAIN_MASK
);
258 return rtw_rfbus_write(&sa
->sa_bus
, RTW_RFCHIPID_PHILIPS
, SA2400_MANRX
,
263 rtw_sa2400_vcocal_start(struct rtw_sa2400
*sa
, int start
)
267 opmode
= SA2400_OPMODE_DEFAULTS
;
269 opmode
|= SA2400_OPMODE_MODE_VCOCALIB
;
271 opmode
|= SA2400_OPMODE_MODE_SLEEP
;
274 opmode
|= SA2400_OPMODE_DIGIN
;
276 return rtw_rfbus_write(&sa
->sa_bus
, RTW_RFCHIPID_PHILIPS
, SA2400_OPMODE
,
281 rtw_sa2400_vco_calibration(struct rtw_sa2400
*sa
)
285 if ((rc
= rtw_sa2400_vcocal_start(sa
, 1)) != 0)
287 DELAY(2200); /* 2.2 milliseconds */
288 /* XXX superfluous: SA2400 automatically entered SLEEP mode. */
289 return rtw_sa2400_vcocal_start(sa
, 0);
293 rtw_sa2400_filter_calibration(struct rtw_sa2400
*sa
)
297 opmode
= SA2400_OPMODE_DEFAULTS
| SA2400_OPMODE_MODE_FCALIB
;
299 opmode
|= SA2400_OPMODE_DIGIN
;
301 return rtw_rfbus_write(&sa
->sa_bus
, RTW_RFCHIPID_PHILIPS
, SA2400_OPMODE
,
306 rtw_sa2400_dc_calibration(struct rtw_sa2400
*sa
)
308 struct rtw_rf
*rf
= &sa
->sa_rf
;
312 (*rf
->rf_continuous_tx_cb
)(rf
->rf_continuous_tx_arg
, 1);
314 dccal
= SA2400_OPMODE_DEFAULTS
| SA2400_OPMODE_MODE_TXRX
;
316 rc
= rtw_rfbus_write(&sa
->sa_bus
, RTW_RFCHIPID_PHILIPS
, SA2400_OPMODE
,
321 DELAY(5); /* DCALIB after being in Tx mode for 5
325 dccal
&= ~SA2400_OPMODE_MODE_MASK
;
326 dccal
|= SA2400_OPMODE_MODE_DCALIB
;
328 rc
= rtw_rfbus_write(&sa
->sa_bus
, RTW_RFCHIPID_PHILIPS
, SA2400_OPMODE
,
333 DELAY(20); /* calibration takes at most 20 microseconds */
335 (*rf
->rf_continuous_tx_cb
)(rf
->rf_continuous_tx_arg
, 0);
341 rtw_sa2400_agc_init(struct rtw_sa2400
*sa
)
345 agc
= __SHIFTIN(25, SA2400_AGC_MAXGAIN_MASK
);
346 agc
|= __SHIFTIN(7, SA2400_AGC_BBPDELAY_MASK
);
347 agc
|= __SHIFTIN(15, SA2400_AGC_LNADELAY_MASK
);
348 agc
|= __SHIFTIN(27, SA2400_AGC_RXONDELAY_MASK
);
350 return rtw_rfbus_write(&sa
->sa_bus
, RTW_RFCHIPID_PHILIPS
, SA2400_AGC
,
355 rtw_sa2400_destroy(struct rtw_rf
*rf
)
357 struct rtw_sa2400
*sa
= (struct rtw_sa2400
*)rf
;
358 memset(sa
, 0, sizeof(*sa
));
363 rtw_sa2400_calibrate(struct rtw_rf
*rf
, u_int freq
)
365 struct rtw_sa2400
*sa
= (struct rtw_sa2400
*)rf
;
368 /* XXX reference driver calibrates VCO twice. Is it a bug? */
369 for (i
= 0; i
< 2; i
++) {
370 if ((rc
= rtw_sa2400_vco_calibration(sa
)) != 0)
373 /* VCO calibration erases synthesizer registers, so re-tune */
374 if ((rc
= rtw_sa2400_tune(rf
, freq
)) != 0)
376 if ((rc
= rtw_sa2400_filter_calibration(sa
)) != 0)
378 /* analog PHY needs DC calibration */
380 return rtw_sa2400_dc_calibration(sa
);
385 rtw_sa2400_init(struct rtw_rf
*rf
, u_int freq
, uint8_t opaque_txpower
,
386 enum rtw_pwrstate power
)
388 struct rtw_sa2400
*sa
= (struct rtw_sa2400
*)rf
;
391 if ((rc
= rtw_sa2400_txpower(rf
, opaque_txpower
)) != 0)
394 /* skip configuration if it's time to sleep or to power-down. */
395 if (power
== RTW_SLEEP
|| power
== RTW_OFF
)
396 return rtw_sa2400_pwrstate(rf
, power
);
398 /* go to sleep for configuration */
399 if ((rc
= rtw_sa2400_pwrstate(rf
, RTW_SLEEP
)) != 0)
402 if ((rc
= rtw_sa2400_tune(rf
, freq
)) != 0)
404 if ((rc
= rtw_sa2400_agc_init(sa
)) != 0)
406 if ((rc
= rtw_sa2400_manrx_init(sa
)) != 0)
408 if ((rc
= rtw_sa2400_calibrate(rf
, freq
)) != 0)
411 /* enter Tx/Rx mode */
412 return rtw_sa2400_pwrstate(rf
, power
);
416 rtw_sa2400_create(struct rtw_regs
*regs
, rtw_rf_write_t rf_write
, int digphy
)
418 struct rtw_sa2400
*sa
;
419 struct rtw_rfbus
*bus
;
421 struct rtw_bbpset
*bb
;
423 sa
= malloc(sizeof(*sa
), M_DEVBUF
, M_NOWAIT
| M_ZERO
);
427 sa
->sa_digphy
= digphy
;
432 rf
->rf_init
= rtw_sa2400_init
;
433 rf
->rf_destroy
= rtw_sa2400_destroy
;
434 rf
->rf_txpower
= rtw_sa2400_txpower
;
435 rf
->rf_tune
= rtw_sa2400_tune
;
436 rf
->rf_pwrstate
= rtw_sa2400_pwrstate
;
440 bb
->bb_antatten
= RTW_BBP_ANTATTEN_PHILIPS_MAGIC
;
441 bb
->bb_chestlim
= 0x00;
442 bb
->bb_chsqlim
= 0xa0;
443 bb
->bb_ifagcdet
= 0x64;
444 bb
->bb_ifagcini
= 0x90;
445 bb
->bb_ifagclimit
= 0x1a;
446 bb
->bb_lnadet
= 0xe0;
454 bus
->b_write
= rf_write
;
460 rtw_grf5101_txpower(struct rtw_rf
*rf
, uint8_t opaque_txpower
)
462 struct rtw_grf5101
*gr
= (struct rtw_grf5101
*)rf
;
464 GCT_WRITE(gr
, 0x15, 0, err
);
465 GCT_WRITE(gr
, 0x06, opaque_txpower
, err
);
466 GCT_WRITE(gr
, 0x15, 0x10, err
);
467 GCT_WRITE(gr
, 0x15, 0x00, err
);
474 rtw_grf5101_pwrstate(struct rtw_rf
*rf
, enum rtw_pwrstate power
)
476 struct rtw_grf5101
*gr
= (struct rtw_grf5101
*)rf
;
480 GCT_WRITE(gr
, 0x07, 0x0000, err
);
481 GCT_WRITE(gr
, 0x1f, 0x0045, err
);
482 GCT_WRITE(gr
, 0x1f, 0x0005, err
);
483 GCT_WRITE(gr
, 0x00, 0x08e4, err
);
487 GCT_WRITE(gr
, 0x1f, 0x0001, err
);
489 GCT_WRITE(gr
, 0x1f, 0x0001, err
);
491 GCT_WRITE(gr
, 0x1f, 0x0041, err
);
493 GCT_WRITE(gr
, 0x1f, 0x0061, err
);
495 GCT_WRITE(gr
, 0x00, 0x0ae4, err
);
497 GCT_WRITE(gr
, 0x07, 0x1000, err
);
508 rtw_grf5101_tune(struct rtw_rf
*rf
, u_int freq
)
511 struct rtw_grf5101
*gr
= (struct rtw_grf5101
*)rf
;
515 else if ((channel
= (freq
- 2412) / 5 + 1) < 1 || channel
> 13) {
516 RTW_DPRINTF(RTW_DEBUG_PHY
,
517 ("%s: invalid channel %d (freq %d)\n", __func__
, channel
,
522 GCT_WRITE(gr
, 0x07, 0, err
);
523 GCT_WRITE(gr
, 0x0b, channel
- 1, err
);
524 GCT_WRITE(gr
, 0x07, 0x1000, err
);
531 rtw_grf5101_init(struct rtw_rf
*rf
, u_int freq
, uint8_t opaque_txpower
,
532 enum rtw_pwrstate power
)
535 struct rtw_grf5101
*gr
= (struct rtw_grf5101
*)rf
;
538 * These values have been derived from the rtl8180-sa2400
539 * Linux driver. It is unknown what they all do, GCT refuse
540 * to release any documentation so these are more than
541 * likely sub optimal settings
544 GCT_WRITE(gr
, 0x01, 0x1a23, err
);
545 GCT_WRITE(gr
, 0x02, 0x4971, err
);
546 GCT_WRITE(gr
, 0x03, 0x41de, err
);
547 GCT_WRITE(gr
, 0x04, 0x2d80, err
);
549 GCT_WRITE(gr
, 0x05, 0x61ff, err
);
551 GCT_WRITE(gr
, 0x06, 0x0, err
);
553 GCT_WRITE(gr
, 0x08, 0x7533, err
);
554 GCT_WRITE(gr
, 0x09, 0xc401, err
);
555 GCT_WRITE(gr
, 0x0a, 0x0, err
);
556 GCT_WRITE(gr
, 0x0c, 0x1c7, err
);
557 GCT_WRITE(gr
, 0x0d, 0x29d3, err
);
558 GCT_WRITE(gr
, 0x0e, 0x2e8, err
);
559 GCT_WRITE(gr
, 0x10, 0x192, err
);
560 GCT_WRITE(gr
, 0x11, 0x248, err
);
561 GCT_WRITE(gr
, 0x12, 0x0, err
);
562 GCT_WRITE(gr
, 0x13, 0x20c4, err
);
563 GCT_WRITE(gr
, 0x14, 0xf4fc, err
);
564 GCT_WRITE(gr
, 0x15, 0x0, err
);
565 GCT_WRITE(gr
, 0x16, 0x1500, err
);
567 if ((rc
= rtw_grf5101_txpower(rf
, opaque_txpower
)) != 0)
570 if ((rc
= rtw_grf5101_tune(rf
, freq
)) != 0)
579 rtw_grf5101_destroy(struct rtw_rf
*rf
)
581 struct rtw_grf5101
*gr
= (struct rtw_grf5101
*)rf
;
582 memset(gr
, 0, sizeof(*gr
));
587 rtw_grf5101_create(struct rtw_regs
*regs
, rtw_rf_write_t rf_write
,
590 struct rtw_grf5101
*gr
;
591 struct rtw_rfbus
*bus
;
593 struct rtw_bbpset
*bb
;
595 gr
= malloc(sizeof(*gr
), M_DEVBUF
, M_NOWAIT
| M_ZERO
);
602 rf
->rf_init
= rtw_grf5101_init
;
603 rf
->rf_destroy
= rtw_grf5101_destroy
;
604 rf
->rf_txpower
= rtw_grf5101_txpower
;
605 rf
->rf_tune
= rtw_grf5101_tune
;
606 rf
->rf_pwrstate
= rtw_grf5101_pwrstate
;
610 bb
->bb_antatten
= RTW_BBP_ANTATTEN_GCT_MAGIC
;
611 bb
->bb_chestlim
= 0x00;
612 bb
->bb_chsqlim
= 0xa0;
613 bb
->bb_ifagcdet
= 0x64;
614 bb
->bb_ifagcini
= 0x90;
615 bb
->bb_ifagclimit
= 0x1e;
616 bb
->bb_lnadet
= 0xc0;
624 bus
->b_write
= rf_write
;
631 rtw_max2820_tune(struct rtw_rf
*rf
, u_int freq
)
633 struct rtw_max2820
*mx
= (struct rtw_max2820
*)rf
;
634 struct rtw_rfbus
*bus
= &mx
->mx_bus
;
636 if (freq
< 2400 || freq
> 2499)
639 return rtw_rfbus_write(bus
, RTW_RFCHIPID_MAXIM
, MAX2820_CHANNEL
,
640 __SHIFTIN(freq
- 2400, MAX2820_CHANNEL_CF_MASK
));
644 rtw_max2820_destroy(struct rtw_rf
*rf
)
646 struct rtw_max2820
*mx
= (struct rtw_max2820
*)rf
;
647 memset(mx
, 0, sizeof(*mx
));
652 rtw_max2820_init(struct rtw_rf
*rf
, u_int freq
, uint8_t opaque_txpower
,
653 enum rtw_pwrstate power
)
655 struct rtw_max2820
*mx
= (struct rtw_max2820
*)rf
;
656 struct rtw_rfbus
*bus
= &mx
->mx_bus
;
659 if ((rc
= rtw_rfbus_write(bus
, RTW_RFCHIPID_MAXIM
, MAX2820_TEST
,
660 MAX2820_TEST_DEFAULT
)) != 0)
663 if ((rc
= rtw_rfbus_write(bus
, RTW_RFCHIPID_MAXIM
, MAX2820_ENABLE
,
664 MAX2820_ENABLE_DEFAULT
)) != 0)
667 /* skip configuration if it's time to sleep or to power-down. */
668 if ((rc
= rtw_max2820_pwrstate(rf
, power
)) != 0)
670 else if (power
== RTW_OFF
|| power
== RTW_SLEEP
)
673 if ((rc
= rtw_rfbus_write(bus
, RTW_RFCHIPID_MAXIM
, MAX2820_SYNTH
,
674 MAX2820_SYNTH_R_44MHZ
)) != 0)
677 if ((rc
= rtw_max2820_tune(rf
, freq
)) != 0)
680 /* XXX The MAX2820 datasheet indicates that 1C and 2C should not
681 * be changed from 7, however, the reference driver sets them
682 * to 4 and 1, respectively.
684 if ((rc
= rtw_rfbus_write(bus
, RTW_RFCHIPID_MAXIM
, MAX2820_RECEIVE
,
685 MAX2820_RECEIVE_DL_DEFAULT
|
686 __SHIFTIN(4, MAX2820A_RECEIVE_1C_MASK
) |
687 __SHIFTIN(1, MAX2820A_RECEIVE_2C_MASK
))) != 0)
690 return rtw_rfbus_write(bus
, RTW_RFCHIPID_MAXIM
, MAX2820_TRANSMIT
,
691 MAX2820_TRANSMIT_PA_DEFAULT
);
695 rtw_max2820_txpower(struct rtw_rf
*rf
, uint8_t opaque_txpower
)
702 rtw_max2820_pwrstate(struct rtw_rf
*rf
, enum rtw_pwrstate power
)
705 struct rtw_max2820
*mx
;
706 struct rtw_rfbus
*bus
;
708 mx
= (struct rtw_max2820
*)rf
;
718 enable
= MAX2820_ENABLE_DEFAULT
;
721 return rtw_rfbus_write(bus
, RTW_RFCHIPID_MAXIM
, MAX2820_ENABLE
, enable
);
725 rtw_max2820_create(struct rtw_regs
*regs
, rtw_rf_write_t rf_write
, int is_a
)
727 struct rtw_max2820
*mx
;
728 struct rtw_rfbus
*bus
;
730 struct rtw_bbpset
*bb
;
732 mx
= malloc(sizeof(*mx
), M_DEVBUF
, M_NOWAIT
| M_ZERO
);
741 rf
->rf_init
= rtw_max2820_init
;
742 rf
->rf_destroy
= rtw_max2820_destroy
;
743 rf
->rf_txpower
= rtw_max2820_txpower
;
744 rf
->rf_tune
= rtw_max2820_tune
;
745 rf
->rf_pwrstate
= rtw_max2820_pwrstate
;
749 bb
->bb_antatten
= RTW_BBP_ANTATTEN_MAXIM_MAGIC
;
751 bb
->bb_chsqlim
= 159;
752 bb
->bb_ifagcdet
= 100;
753 bb
->bb_ifagcini
= 144;
754 bb
->bb_ifagclimit
= 26;
763 bus
->b_write
= rf_write
;
770 rtw_phy_init(struct rtw_regs
*regs
, struct rtw_rf
*rf
, uint8_t opaque_txpower
,
771 uint8_t cs_threshold
, u_int freq
, int antdiv
, int dflantb
,
772 enum rtw_pwrstate power
)
775 RTW_DPRINTF(RTW_DEBUG_PHY
,
776 ("%s: txpower %u csthresh %u freq %u antdiv %u dflantb %u "
777 "pwrstate %s\n", __func__
, opaque_txpower
, cs_threshold
, freq
,
778 antdiv
, dflantb
, rtw_pwrstate_string(power
)));
780 /* XXX is this really necessary? */
781 if ((rc
= rtw_rf_txpower(rf
, opaque_txpower
)) != 0)
783 if ((rc
= rtw_bbp_preinit(regs
, rf
->rf_bbpset
.bb_antatten
, dflantb
,
786 if ((rc
= rtw_rf_tune(rf
, freq
)) != 0)
789 if ((rc
= rtw_rf_init(rf
, freq
, opaque_txpower
, power
)) != 0)
791 #if 0 /* what is this redundant tx power setting here for? */
792 if ((rc
= rtw_rf_txpower(rf
, opaque_txpower
)) != 0)
795 return rtw_bbp_init(regs
, &rf
->rf_bbpset
, antdiv
, dflantb
,