0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/slab.h>
0010
0011 #include "zd_rf.h"
0012 #include "zd_usb.h"
0013 #include "zd_chip.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022 #define UW2453_REGWRITE(reg, val) ((((reg) & 0xf) << 20) | ((val) & 0xfffff))
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 static const u8 uw2453_std_synth[] = {
0042 RF_CHANNEL( 1) = 0x47,
0043 RF_CHANNEL( 2) = 0x47,
0044 RF_CHANNEL( 3) = 0x67,
0045 RF_CHANNEL( 4) = 0x67,
0046 RF_CHANNEL( 5) = 0x67,
0047 RF_CHANNEL( 6) = 0x67,
0048 RF_CHANNEL( 7) = 0x57,
0049 RF_CHANNEL( 8) = 0x57,
0050 RF_CHANNEL( 9) = 0x57,
0051 RF_CHANNEL(10) = 0x57,
0052 RF_CHANNEL(11) = 0x77,
0053 RF_CHANNEL(12) = 0x77,
0054 RF_CHANNEL(13) = 0x77,
0055 RF_CHANNEL(14) = 0x4f,
0056 };
0057
0058
0059
0060
0061 static const u16 uw2453_synth_divide[] = {
0062 RF_CHANNEL( 1) = 0x999,
0063 RF_CHANNEL( 2) = 0x99b,
0064 RF_CHANNEL( 3) = 0x998,
0065 RF_CHANNEL( 4) = 0x99a,
0066 RF_CHANNEL( 5) = 0x999,
0067 RF_CHANNEL( 6) = 0x99b,
0068 RF_CHANNEL( 7) = 0x998,
0069 RF_CHANNEL( 8) = 0x99a,
0070 RF_CHANNEL( 9) = 0x999,
0071 RF_CHANNEL(10) = 0x99b,
0072 RF_CHANNEL(11) = 0x998,
0073 RF_CHANNEL(12) = 0x99a,
0074 RF_CHANNEL(13) = 0x999,
0075 RF_CHANNEL(14) = 0xccc,
0076 };
0077
0078
0079
0080
0081
0082
0083 #define CHAN_TO_PAIRIDX(a) ((a - 1) / 2)
0084 #define RF_CHANPAIR(a,b) [CHAN_TO_PAIRIDX(a)]
0085 static const u16 uw2453_std_vco_cfg[][7] = {
0086 {
0087 RF_CHANPAIR( 1, 2) = 0x664d,
0088 RF_CHANPAIR( 3, 4) = 0x604d,
0089 RF_CHANPAIR( 5, 6) = 0x6675,
0090 RF_CHANPAIR( 7, 8) = 0x6475,
0091 RF_CHANPAIR( 9, 10) = 0x6655,
0092 RF_CHANPAIR(11, 12) = 0x6455,
0093 RF_CHANPAIR(13, 14) = 0x6665,
0094 },
0095 {
0096 RF_CHANPAIR( 1, 2) = 0x666d,
0097 RF_CHANPAIR( 3, 4) = 0x606d,
0098 RF_CHANPAIR( 5, 6) = 0x664d,
0099 RF_CHANPAIR( 7, 8) = 0x644d,
0100 RF_CHANPAIR( 9, 10) = 0x6675,
0101 RF_CHANPAIR(11, 12) = 0x6475,
0102 RF_CHANPAIR(13, 14) = 0x6655,
0103 },
0104 {
0105 RF_CHANPAIR( 1, 2) = 0x665d,
0106 RF_CHANPAIR( 3, 4) = 0x605d,
0107 RF_CHANPAIR( 5, 6) = 0x666d,
0108 RF_CHANPAIR( 7, 8) = 0x646d,
0109 RF_CHANPAIR( 9, 10) = 0x664d,
0110 RF_CHANPAIR(11, 12) = 0x644d,
0111 RF_CHANPAIR(13, 14) = 0x6675,
0112 },
0113 {
0114 RF_CHANPAIR( 1, 2) = 0x667d,
0115 RF_CHANPAIR( 3, 4) = 0x607d,
0116 RF_CHANPAIR( 5, 6) = 0x665d,
0117 RF_CHANPAIR( 7, 8) = 0x645d,
0118 RF_CHANPAIR( 9, 10) = 0x666d,
0119 RF_CHANPAIR(11, 12) = 0x646d,
0120 RF_CHANPAIR(13, 14) = 0x664d,
0121 },
0122 {
0123 RF_CHANPAIR( 1, 2) = 0x6643,
0124 RF_CHANPAIR( 3, 4) = 0x6043,
0125 RF_CHANPAIR( 5, 6) = 0x667d,
0126 RF_CHANPAIR( 7, 8) = 0x647d,
0127 RF_CHANPAIR( 9, 10) = 0x665d,
0128 RF_CHANPAIR(11, 12) = 0x645d,
0129 RF_CHANPAIR(13, 14) = 0x666d,
0130 },
0131 {
0132 RF_CHANPAIR( 1, 2) = 0x6663,
0133 RF_CHANPAIR( 3, 4) = 0x6063,
0134 RF_CHANPAIR( 5, 6) = 0x6643,
0135 RF_CHANPAIR( 7, 8) = 0x6443,
0136 RF_CHANPAIR( 9, 10) = 0x667d,
0137 RF_CHANPAIR(11, 12) = 0x647d,
0138 RF_CHANPAIR(13, 14) = 0x665d,
0139 },
0140 {
0141 RF_CHANPAIR( 1, 2) = 0x6653,
0142 RF_CHANPAIR( 3, 4) = 0x6053,
0143 RF_CHANPAIR( 5, 6) = 0x6663,
0144 RF_CHANPAIR( 7, 8) = 0x6463,
0145 RF_CHANPAIR( 9, 10) = 0x6643,
0146 RF_CHANPAIR(11, 12) = 0x6443,
0147 RF_CHANPAIR(13, 14) = 0x667d,
0148 },
0149 {
0150 RF_CHANPAIR( 1, 2) = 0x6673,
0151 RF_CHANPAIR( 3, 4) = 0x6073,
0152 RF_CHANPAIR( 5, 6) = 0x6653,
0153 RF_CHANPAIR( 7, 8) = 0x6453,
0154 RF_CHANPAIR( 9, 10) = 0x6663,
0155 RF_CHANPAIR(11, 12) = 0x6463,
0156 RF_CHANPAIR(13, 14) = 0x6643,
0157 },
0158 {
0159 RF_CHANPAIR( 1, 2) = 0x664b,
0160 RF_CHANPAIR( 3, 4) = 0x604b,
0161 RF_CHANPAIR( 5, 6) = 0x6673,
0162 RF_CHANPAIR( 7, 8) = 0x6473,
0163 RF_CHANPAIR( 9, 10) = 0x6653,
0164 RF_CHANPAIR(11, 12) = 0x6453,
0165 RF_CHANPAIR(13, 14) = 0x6663,
0166 },
0167 {
0168 RF_CHANPAIR( 1, 2) = 0x666b,
0169 RF_CHANPAIR( 3, 4) = 0x606b,
0170 RF_CHANPAIR( 5, 6) = 0x664b,
0171 RF_CHANPAIR( 7, 8) = 0x644b,
0172 RF_CHANPAIR( 9, 10) = 0x6673,
0173 RF_CHANPAIR(11, 12) = 0x6473,
0174 RF_CHANPAIR(13, 14) = 0x6653,
0175 },
0176 {
0177 RF_CHANPAIR( 1, 2) = 0x665b,
0178 RF_CHANPAIR( 3, 4) = 0x605b,
0179 RF_CHANPAIR( 5, 6) = 0x666b,
0180 RF_CHANPAIR( 7, 8) = 0x646b,
0181 RF_CHANPAIR( 9, 10) = 0x664b,
0182 RF_CHANPAIR(11, 12) = 0x644b,
0183 RF_CHANPAIR(13, 14) = 0x6673,
0184 },
0185
0186 };
0187
0188
0189 static const u16 uw2453_autocal_synth[] = {
0190 RF_CHANNEL( 1) = 0x6847,
0191 RF_CHANNEL( 2) = 0x6847,
0192 RF_CHANNEL( 3) = 0x6867,
0193 RF_CHANNEL( 4) = 0x6867,
0194 RF_CHANNEL( 5) = 0x6867,
0195 RF_CHANNEL( 6) = 0x6867,
0196 RF_CHANNEL( 7) = 0x6857,
0197 RF_CHANNEL( 8) = 0x6857,
0198 RF_CHANNEL( 9) = 0x6857,
0199 RF_CHANNEL(10) = 0x6857,
0200 RF_CHANNEL(11) = 0x6877,
0201 RF_CHANNEL(12) = 0x6877,
0202 RF_CHANNEL(13) = 0x6877,
0203 RF_CHANNEL(14) = 0x684f,
0204 };
0205
0206
0207 static const u16 UW2453_AUTOCAL_VCO_CFG = 0x6662;
0208
0209
0210
0211 static u32 uw2453_txgain[] = {
0212 [0x00] = 0x0e313,
0213 [0x01] = 0x0fb13,
0214 [0x02] = 0x0e093,
0215 [0x03] = 0x0f893,
0216 [0x04] = 0x0ea93,
0217 [0x05] = 0x1f093,
0218 [0x06] = 0x1f493,
0219 [0x07] = 0x1f693,
0220 [0x08] = 0x1f393,
0221 [0x09] = 0x1f35b,
0222 [0x0a] = 0x1e6db,
0223 [0x0b] = 0x1ff3f,
0224 [0x0c] = 0x1ffff,
0225 [0x0d] = 0x361d7,
0226 [0x0e] = 0x37fbf,
0227 [0x0f] = 0x3ff8b,
0228 [0x10] = 0x3ff33,
0229 [0x11] = 0x3fb3f,
0230 [0x12] = 0x3ffff,
0231 };
0232
0233
0234 struct uw2453_priv {
0235
0236
0237 int config;
0238 };
0239
0240 #define UW2453_PRIV(rf) ((struct uw2453_priv *) (rf)->priv)
0241
0242 static int uw2453_synth_set_channel(struct zd_chip *chip, int channel,
0243 bool autocal)
0244 {
0245 int r;
0246 int idx = channel - 1;
0247 u32 val;
0248
0249 if (autocal)
0250 val = UW2453_REGWRITE(1, uw2453_autocal_synth[idx]);
0251 else
0252 val = UW2453_REGWRITE(1, uw2453_std_synth[idx]);
0253
0254 r = zd_rfwrite_locked(chip, val, RF_RV_BITS);
0255 if (r)
0256 return r;
0257
0258 return zd_rfwrite_locked(chip,
0259 UW2453_REGWRITE(2, uw2453_synth_divide[idx]), RF_RV_BITS);
0260 }
0261
0262 static int uw2453_write_vco_cfg(struct zd_chip *chip, u16 value)
0263 {
0264
0265
0266 u32 val = 0x40000 | value;
0267 return zd_rfwrite_locked(chip, UW2453_REGWRITE(3, val), RF_RV_BITS);
0268 }
0269
0270 static int uw2453_init_mode(struct zd_chip *chip)
0271 {
0272 static const u32 rv[] = {
0273 UW2453_REGWRITE(0, 0x25f98),
0274 UW2453_REGWRITE(0, 0x25f9a),
0275 UW2453_REGWRITE(0, 0x25f94),
0276 UW2453_REGWRITE(0, 0x27fd4),
0277 };
0278
0279 return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
0280 }
0281
0282 static int uw2453_set_tx_gain_level(struct zd_chip *chip, int channel)
0283 {
0284 u8 int_value = chip->pwr_int_values[channel - 1];
0285
0286 if (int_value >= ARRAY_SIZE(uw2453_txgain)) {
0287 dev_dbg_f(zd_chip_dev(chip), "can't configure TX gain for "
0288 "int value %x on channel %d\n", int_value, channel);
0289 return 0;
0290 }
0291
0292 return zd_rfwrite_locked(chip,
0293 UW2453_REGWRITE(7, uw2453_txgain[int_value]), RF_RV_BITS);
0294 }
0295
0296 static int uw2453_init_hw(struct zd_rf *rf)
0297 {
0298 int i, r;
0299 int found_config = -1;
0300 u16 intr_status;
0301 struct zd_chip *chip = zd_rf_to_chip(rf);
0302
0303 static const struct zd_ioreq16 ioreqs[] = {
0304 { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 },
0305 { ZD_CR17, 0x28 },
0306 { ZD_CR23, 0x38 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
0307 { ZD_CR27, 0x15 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
0308 { ZD_CR33, 0x28 }, { ZD_CR34, 0x30 },
0309 { ZD_CR35, 0x43 },
0310 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
0311 { ZD_CR46, 0x92 },
0312 { ZD_CR47, 0x1e },
0313 { ZD_CR48, 0x04 },
0314 { ZD_CR49, 0xfa }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
0315 { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
0316 { ZD_CR91, 0x00 }, { ZD_CR92, 0x0a }, { ZD_CR98, 0x8d },
0317 { ZD_CR99, 0x28 }, { ZD_CR100, 0x02 },
0318 { ZD_CR101, 0x09 },
0319 { ZD_CR102, 0x27 },
0320 { ZD_CR106, 0x1c },
0321
0322
0323 { ZD_CR107, 0x1c },
0324 { ZD_CR109, 0x13 },
0325 { ZD_CR110, 0x1f },
0326 { ZD_CR111, 0x13 }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
0327 { ZD_CR114, 0x23 },
0328 { ZD_CR115, 0x24 },
0329 { ZD_CR116, 0x24 },
0330 { ZD_CR117, 0xfa },
0331 { ZD_CR118, 0xf0 },
0332 { ZD_CR119, 0x1a },
0333 { ZD_CR120, 0x4f },
0334 { ZD_CR121, 0x1f },
0335 { ZD_CR122, 0xf0 }, { ZD_CR123, 0x57 }, { ZD_CR125, 0xad },
0336 { ZD_CR126, 0x6c }, { ZD_CR127, 0x03 },
0337 { ZD_CR128, 0x14 },
0338 { ZD_CR129, 0x12 },
0339 { ZD_CR130, 0x10 }, { ZD_CR137, 0x50 }, { ZD_CR138, 0xa8 },
0340 { ZD_CR144, 0xac }, { ZD_CR146, 0x20 }, { ZD_CR252, 0xff },
0341 { ZD_CR253, 0xff },
0342 };
0343
0344 static const u32 rv[] = {
0345 UW2453_REGWRITE(4, 0x2b),
0346 UW2453_REGWRITE(5, 0x19e4f),
0347 UW2453_REGWRITE(6, 0xf81ad),
0348 UW2453_REGWRITE(7, 0x3fffe),
0349
0350
0351
0352 UW2453_REGWRITE(0, 0x25f9c),
0353
0354
0355 UW2453_REGWRITE(1, 0x47),
0356 UW2453_REGWRITE(2, 0x999),
0357
0358
0359 UW2453_REGWRITE(3, 0x7602),
0360
0361
0362 UW2453_REGWRITE(3, 0x46063),
0363 };
0364
0365 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
0366 if (r)
0367 return r;
0368
0369 r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
0370 if (r)
0371 return r;
0372
0373 r = uw2453_init_mode(chip);
0374 if (r)
0375 return r;
0376
0377
0378 for (i = 0; i < ARRAY_SIZE(uw2453_std_vco_cfg) - 1; i++) {
0379
0380 r = uw2453_synth_set_channel(chip, 1, false);
0381 if (r)
0382 return r;
0383
0384
0385 r = uw2453_write_vco_cfg(chip, uw2453_std_vco_cfg[i][0]);
0386 if (r)
0387 return r;
0388
0389
0390 r = zd_iowrite16_locked(chip, 0x0f, UW2453_INTR_REG);
0391 if (r)
0392 return r;
0393
0394
0395 r = zd_ioread16_locked(chip, &intr_status, UW2453_INTR_REG);
0396 if (r)
0397 return r;
0398
0399 if (!(intr_status & 0xf)) {
0400 dev_dbg_f(zd_chip_dev(chip),
0401 "PLL locked on configuration %d\n", i);
0402 found_config = i;
0403 break;
0404 }
0405 }
0406
0407 if (found_config == -1) {
0408
0409 dev_dbg_f(zd_chip_dev(chip),
0410 "PLL did not lock, using autocal\n");
0411
0412 r = uw2453_synth_set_channel(chip, 1, true);
0413 if (r)
0414 return r;
0415
0416 r = uw2453_write_vco_cfg(chip, UW2453_AUTOCAL_VCO_CFG);
0417 if (r)
0418 return r;
0419 }
0420
0421
0422
0423 UW2453_PRIV(rf)->config = found_config + 1;
0424
0425 return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
0426 }
0427
0428 static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
0429 {
0430 int r;
0431 u16 vco_cfg;
0432 int config = UW2453_PRIV(rf)->config;
0433 bool autocal = (config == -1);
0434 struct zd_chip *chip = zd_rf_to_chip(rf);
0435
0436 static const struct zd_ioreq16 ioreqs[] = {
0437 { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
0438 { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
0439 };
0440
0441 r = uw2453_synth_set_channel(chip, channel, autocal);
0442 if (r)
0443 return r;
0444
0445 if (autocal)
0446 vco_cfg = UW2453_AUTOCAL_VCO_CFG;
0447 else
0448 vco_cfg = uw2453_std_vco_cfg[config][CHAN_TO_PAIRIDX(channel)];
0449
0450 r = uw2453_write_vco_cfg(chip, vco_cfg);
0451 if (r)
0452 return r;
0453
0454 r = uw2453_init_mode(chip);
0455 if (r)
0456 return r;
0457
0458 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
0459 if (r)
0460 return r;
0461
0462 r = uw2453_set_tx_gain_level(chip, channel);
0463 if (r)
0464 return r;
0465
0466 return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
0467 }
0468
0469 static int uw2453_switch_radio_on(struct zd_rf *rf)
0470 {
0471 int r;
0472 struct zd_chip *chip = zd_rf_to_chip(rf);
0473 struct zd_ioreq16 ioreqs[] = {
0474 { ZD_CR11, 0x00 }, { ZD_CR251, 0x3f },
0475 };
0476
0477
0478 r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f94), RF_RV_BITS);
0479 if (r)
0480 return r;
0481
0482 if (zd_chip_is_zd1211b(chip))
0483 ioreqs[1].value = 0x7f;
0484
0485 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
0486 }
0487
0488 static int uw2453_switch_radio_off(struct zd_rf *rf)
0489 {
0490 int r;
0491 struct zd_chip *chip = zd_rf_to_chip(rf);
0492 static const struct zd_ioreq16 ioreqs[] = {
0493 { ZD_CR11, 0x04 }, { ZD_CR251, 0x2f },
0494 };
0495
0496
0497
0498 r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f90), RF_RV_BITS);
0499 if (r)
0500 return r;
0501
0502 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
0503 }
0504
0505 static void uw2453_clear(struct zd_rf *rf)
0506 {
0507 kfree(rf->priv);
0508 }
0509
0510 int zd_rf_init_uw2453(struct zd_rf *rf)
0511 {
0512 rf->init_hw = uw2453_init_hw;
0513 rf->set_channel = uw2453_set_channel;
0514 rf->switch_radio_on = uw2453_switch_radio_on;
0515 rf->switch_radio_off = uw2453_switch_radio_off;
0516 rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
0517 rf->clear = uw2453_clear;
0518
0519 rf->update_channel_int = 0;
0520
0521 rf->priv = kmalloc(sizeof(struct uw2453_priv), GFP_KERNEL);
0522 if (rf->priv == NULL)
0523 return -ENOMEM;
0524
0525 return 0;
0526 }
0527