36 #include <linux/sched.h>
37 #include <linux/slab.h>
47 if (!b43_compare_bbatt(&c->
bbatt, bbatt))
49 if (!b43_compare_rfatt(&c->
rfatt, rfatt))
65 b43dbg(dev->
wl,
"Invalid LO control pair "
66 "(I: %d, Q: %d)\n", control->
i, control->
q);
73 value = (
u8) (control->
q);
74 value |= ((
u8) (control->
i)) << 8;
141 static u16 lo_txctl_register_table(
struct b43_wldev *dev,
142 u16 *value,
u16 *pad_mix_gain)
170 *pad_mix_gain = padmix;
175 static void lo_measure_txctl_values(
struct b43_wldev *dev)
184 static const u8 tx_bias_values[] = {
185 0x09, 0x08, 0x0A, 0x01, 0x00,
186 0x02, 0x05, 0x04, 0x06,
188 static const u8 tx_magn_values[] = {
203 pga =
abs(10 - lb_gain) / 6;
211 if ((phy->
rev >= 2) &&
215 if ((10 - lb_gain) < cmp_val)
216 tmp = (10 - lb_gain);
224 radio_pctl_reg = cmp_val;
226 radio_pctl_reg =
tmp;
232 reg = lo_txctl_register_table(dev, &mask,
NULL);
239 int min_feedth = 0xFFFF;
242 for (i = 0; i <
ARRAY_SIZE(tx_magn_values); i++) {
243 tx_magn = tx_magn_values[
i];
245 for (j = 0; j <
ARRAY_SIZE(tx_bias_values); j++) {
246 tx_bias = tx_bias_values[
j];
249 lo_measure_feedthrough(dev, 0, pga,
251 if (feedthrough < min_feedth) {
254 min_feedth = feedthrough;
272 static void lo_read_power_vector(
struct b43_wldev *dev)
281 for (i = 0; i < 8; i += 2) {
283 power_vector |= (tmp << (i * 8));
293 static void lo_measure_gain_values(
struct b43_wldev *dev,
294 s16 max_rx_gain,
int use_trsw_rx)
308 if (max_rx_gain >= trsw_rx_gain) {
312 trsw_rx_gain = max_rx_gain;
313 if (trsw_rx_gain < 9) {
319 trsw_rx_gain =
clamp_val(trsw_rx_gain, 0, 0x2D);
329 if (max_rx_gain >= 0x14) {
332 }
else if (max_rx_gain >= 0x12) {
335 }
else if (max_rx_gain >= 0xF) {
385 static void lo_measure_setup(
struct b43_wldev *dev,
426 if ((phy->
rev >= 7) &&
437 sav->
reg_3F4 = b43_read16(dev, 0x3F4);
438 sav->
reg_3E2 = b43_read16(dev, 0x3E2);
456 b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2)
459 b43_write16(dev, 0x3F4, b43_read16(dev, 0x3F4)
488 lo_measure_txctl_values(dev);
500 static void lo_measure_restore(
struct b43_wldev *dev,
529 b43_write16(dev, 0x3F4, sav->
reg_3F4);
540 b43_write16(dev, 0x3E2, sav->
reg_3E2);
576 static int lo_probe_possible_loctls(
struct b43_wldev *dev,
593 static const struct b43_loctl modifiers[] = {
627 if ((test_loctl.i != prev_loctl.
i ||
628 test_loctl.q != prev_loctl.
q) &&
629 (
abs(test_loctl.i) <= 16 &&
abs(test_loctl.q) <= 16)) {
630 b43_lo_write(dev, &test_loctl);
631 feedth = lo_measure_feedthrough(dev, gphy->
lna_gain,
634 if (feedth < d->lowest_feedth) {
635 memcpy(probe_loctl, &test_loctl,
644 memcpy(&prev_loctl, &test_loctl,
sizeof(prev_loctl));
657 static void lo_probe_loctls_statemachine(
struct b43_wldev *dev,
667 int max_repeat = 1, repeat_cnt = 0;
679 feedth = lo_measure_feedthrough(dev, gphy->
lna_gain,
682 if (feedth < 0x258) {
687 feedth = lo_measure_feedthrough(dev, gphy->
lna_gain,
701 lo_probe_possible_loctls(dev, &probe_loctl, &d);
718 if (repeat_cnt == 0) {
724 }
else if (repeat_cnt == 2)
727 lo_measure_gain_values(dev, *max_rx_gain,
729 }
while (++repeat_cnt < max_repeat);
755 txctl_reg = lo_txctl_register_table(dev, &txctl_value, &pad_mix_gain);
760 max_rx_gain = rfatt->
att * 2;
761 max_rx_gain += bbatt->
att / 2;
763 max_rx_gain -= pad_mix_gain;
766 lo_measure_gain_values(dev, max_rx_gain,
770 lo_probe_loctls_statemachine(dev, &loctl, &max_rx_gain);
776 b43dbg(dev->
wl,
"LO: Calibrated for BB(%u), RF(%u,%u) "
784 b43warn(dev->
wl,
"LO calib: out of memory\n");
789 memcpy(&cal->
ctl, &loctl,
sizeof(loctl));
791 INIT_LIST_HEAD(&cal->
list);
806 c = b43_find_lo_calib(lo, bbatt, rfatt);
811 c = b43_calibrate_lo_setting(dev, bbatt, rfatt);
825 int rf_offset, bb_offset;
829 bool table_changed =
false;
835 if (!update_all && !power_vector)
847 if (!update_all && !(power_vector & (((
u64)1ULL) << i)))
856 cal = b43_calibrate_lo_setting(dev, bbatt, rfatt);
859 "calibrate DC table entry\n");
863 val = (
u8)(cal->
ctl.q);
864 val |= ((
u8)(cal->
ctl.i)) << 4;
873 | ((val & 0x00FF) << 8);
879 table_changed =
true;
891 static inline void b43_lo_fixup_rfatt(
struct b43_rfatt *rf)
895 if ((rf->
att != 1) && (rf->
att != 2) && (rf->
att != 3))
906 b43_lo_fixup_rfatt(&rf);
908 cal = b43_get_calib_lo_settings(dev, &gphy->
bbatt, &rf);
911 b43_lo_write(dev, &cal->
ctl);
921 memset(&rf, 0,
sizeof(rf));
922 memset(&bb, 0,
sizeof(bb));
925 b43_lo_fixup_rfatt(&rf);
926 cal = b43_get_calib_lo_settings(dev, &bb, &rf);
929 b43_lo_write(dev, &cal->
ctl);
939 unsigned long expire;
941 bool current_item_expired =
false;
953 lo_read_power_vector(dev);
968 if (b43_compare_bbatt(&cal->
bbatt, &gphy->
bbatt) &&
969 b43_compare_rfatt(&cal->
rfatt, &gphy->
rfatt)) {
971 current_item_expired =
true;
974 b43dbg(dev->
wl,
"LO: Item BB(%u), RF(%u,%u), "
975 "I=%d, Q=%d expired\n",
977 cal->
rfatt.with_padmix,
986 b43dbg(dev->
wl,
"LO: Recalibrating current LO setting\n");
987 cal = b43_calibrate_lo_setting(dev, &gphy->
bbatt, &gphy->
rfatt);
990 b43_lo_write(dev, &cal->
ctl);
992 b43warn(dev->
wl,
"Failed to recalibrate current LO setting\n");
1013 lo_read_power_vector(dev);