1/* ZD1211 USB-WLAN driver for Linux 2 * 3 * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> 4 * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20#include <linux/kernel.h> 21 22#include "zd_rf.h" 23#include "zd_usb.h" 24#include "zd_chip.h" 25 26#define IS_AL2230S(chip) ((chip)->al2230s_bit || (chip)->rf.type == AL2230S_RF) 27 28static const u32 zd1211_al2230_table[][3] = { 29 RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, }, 30 RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, }, 31 RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, }, 32 RF_CHANNEL( 4) = { 0x03e790, 0x0b3331, 0x00000d, }, 33 RF_CHANNEL( 5) = { 0x03f7a0, 0x033331, 0x00000d, }, 34 RF_CHANNEL( 6) = { 0x03f7a0, 0x0b3331, 0x00000d, }, 35 RF_CHANNEL( 7) = { 0x03e7a0, 0x033331, 0x00000d, }, 36 RF_CHANNEL( 8) = { 0x03e7a0, 0x0b3331, 0x00000d, }, 37 RF_CHANNEL( 9) = { 0x03f7b0, 0x033331, 0x00000d, }, 38 RF_CHANNEL(10) = { 0x03f7b0, 0x0b3331, 0x00000d, }, 39 RF_CHANNEL(11) = { 0x03e7b0, 0x033331, 0x00000d, }, 40 RF_CHANNEL(12) = { 0x03e7b0, 0x0b3331, 0x00000d, }, 41 RF_CHANNEL(13) = { 0x03f7c0, 0x033331, 0x00000d, }, 42 RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, }, 43}; 44 45static const u32 zd1211b_al2230_table[][3] = { 46 RF_CHANNEL( 1) = { 0x09efc0, 0x8cccc0, 0xb00000, }, 47 RF_CHANNEL( 2) = { 0x09efc0, 0x8cccd0, 0xb00000, }, 48 RF_CHANNEL( 3) = { 0x09e7c0, 0x8cccc0, 0xb00000, }, 49 RF_CHANNEL( 4) = { 0x09e7c0, 0x8cccd0, 0xb00000, }, 50 RF_CHANNEL( 5) = { 0x05efc0, 0x8cccc0, 0xb00000, }, 51 RF_CHANNEL( 6) = { 0x05efc0, 0x8cccd0, 0xb00000, }, 52 RF_CHANNEL( 7) = { 0x05e7c0, 0x8cccc0, 0xb00000, }, 53 RF_CHANNEL( 8) = { 0x05e7c0, 0x8cccd0, 0xb00000, }, 54 RF_CHANNEL( 9) = { 0x0defc0, 0x8cccc0, 0xb00000, }, 55 RF_CHANNEL(10) = { 0x0defc0, 0x8cccd0, 0xb00000, }, 56 RF_CHANNEL(11) = { 0x0de7c0, 0x8cccc0, 0xb00000, }, 57 RF_CHANNEL(12) = { 0x0de7c0, 0x8cccd0, 0xb00000, }, 58 RF_CHANNEL(13) = { 0x03efc0, 0x8cccc0, 0xb00000, }, 59 RF_CHANNEL(14) = { 0x03e7c0, 0x866660, 0xb00000, }, 60}; 61 62static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = { 63 { ZD_CR240, 0x57 }, { ZD_CR9, 0xe0 }, 64}; 65 66static const struct zd_ioreq16 ioreqs_init_al2230s[] = { 67 { ZD_CR47, 0x1e }, /* MARK_002 */ 68 { ZD_CR106, 0x22 }, 69 { ZD_CR107, 0x2a }, /* MARK_002 */ 70 { ZD_CR109, 0x13 }, /* MARK_002 */ 71 { ZD_CR118, 0xf8 }, /* MARK_002 */ 72 { ZD_CR119, 0x12 }, { ZD_CR122, 0xe0 }, 73 { ZD_CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */ 74 { ZD_CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */ 75 { ZD_CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */ 76}; 77 78static int zd1211b_al2230_finalize_rf(struct zd_chip *chip) 79{ 80 int r; 81 static const struct zd_ioreq16 ioreqs[] = { 82 { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 }, 83 { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 }, 84 { ZD_CR203, 0x06 }, 85 { }, 86 87 { ZD_CR240, 0x80 }, 88 }; 89 90 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 91 if (r) 92 return r; 93 94 /* related to antenna selection? */ 95 if (chip->new_phy_layout) { 96 r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9); 97 if (r) 98 return r; 99 } 100 101 return zd_iowrite16_locked(chip, 0x06, ZD_CR203); 102} 103 104static int zd1211_al2230_init_hw(struct zd_rf *rf) 105{ 106 int r; 107 struct zd_chip *chip = zd_rf_to_chip(rf); 108 109 static const struct zd_ioreq16 ioreqs_init[] = { 110 { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, 111 { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, 112 { ZD_CR44, 0x33 }, { ZD_CR106, 0x2a }, { ZD_CR107, 0x1a }, 113 { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, { ZD_CR111, 0x2b }, 114 { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, { ZD_CR10, 0x89 }, 115 /* for newest (3rd cut) AL2300 */ 116 { ZD_CR17, 0x28 }, 117 { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 }, 118 /* for newest (3rd cut) AL2300 */ 119 { ZD_CR35, 0x3e }, 120 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, 121 /* for newest (3rd cut) AL2300 */ 122 { ZD_CR46, 0x96 }, 123 { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, 124 { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, 125 { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 }, 126 { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR106, 0x24 }, 127 { ZD_CR107, 0x2a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x13 }, 128 { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, 129 { ZD_CR114, 0x27 }, 130 /* for newest (3rd cut) AL2300 */ 131 { ZD_CR115, 0x24 }, 132 { ZD_CR116, 0x24 }, { ZD_CR117, 0xf4 }, { ZD_CR118, 0xfc }, 133 { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, { ZD_CR121, 0x77 }, 134 { ZD_CR122, 0xe0 }, { ZD_CR137, 0x88 }, { ZD_CR252, 0xff }, 135 { ZD_CR253, 0xff }, 136 }; 137 138 static const struct zd_ioreq16 ioreqs_pll[] = { 139 /* shdnb(PLL_ON)=0 */ 140 { ZD_CR251, 0x2f }, 141 /* shdnb(PLL_ON)=1 */ 142 { ZD_CR251, 0x3f }, 143 { ZD_CR138, 0x28 }, { ZD_CR203, 0x06 }, 144 }; 145 146 static const u32 rv1[] = { 147 /* Channel 1 */ 148 0x03f790, 149 0x033331, 150 0x00000d, 151 152 0x0b3331, 153 0x03b812, 154 0x00fff3, 155 }; 156 157 static const u32 rv2[] = { 158 0x000da4, 159 0x0f4dc5, /* fix freq shift, 0x04edc5 */ 160 0x0805b6, 161 0x011687, 162 0x000688, 163 0x0403b9, /* external control TX power (ZD_CR31) */ 164 0x00dbba, 165 0x00099b, 166 0x0bdffc, 167 0x00000d, 168 0x00500f, 169 }; 170 171 static const u32 rv3[] = { 172 0x00d00f, 173 0x004c0f, 174 0x00540f, 175 0x00700f, 176 0x00500f, 177 }; 178 179 r = zd_iowrite16a_locked(chip, ioreqs_init, ARRAY_SIZE(ioreqs_init)); 180 if (r) 181 return r; 182 183 if (IS_AL2230S(chip)) { 184 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, 185 ARRAY_SIZE(ioreqs_init_al2230s)); 186 if (r) 187 return r; 188 } 189 190 r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS); 191 if (r) 192 return r; 193 194 /* improve band edge for AL2230S */ 195 if (IS_AL2230S(chip)) 196 r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS); 197 else 198 r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS); 199 if (r) 200 return r; 201 202 r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS); 203 if (r) 204 return r; 205 206 r = zd_iowrite16a_locked(chip, ioreqs_pll, ARRAY_SIZE(ioreqs_pll)); 207 if (r) 208 return r; 209 210 r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS); 211 if (r) 212 return r; 213 214 return 0; 215} 216 217static int zd1211b_al2230_init_hw(struct zd_rf *rf) 218{ 219 int r; 220 struct zd_chip *chip = zd_rf_to_chip(rf); 221 222 static const struct zd_ioreq16 ioreqs1[] = { 223 { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 }, 224 { ZD_CR17, 0x2B }, /* for newest(3rd cut) AL2230 */ 225 { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 }, 226 { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, 227 { ZD_CR33, 0x28 }, /* 5621 */ 228 { ZD_CR34, 0x30 }, 229 { ZD_CR35, 0x3e }, /* for newest(3rd cut) AL2230 */ 230 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, 231 { ZD_CR46, 0x99 }, /* for newest(3rd cut) AL2230 */ 232 { ZD_CR47, 0x1e }, 233 234 /* ZD1211B 05.06.10 */ 235 { ZD_CR48, 0x06 }, { ZD_CR49, 0xf9 }, { ZD_CR51, 0x01 }, 236 { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 }, 237 { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 }, 238 { ZD_CR69, 0x28 }, 239 240 { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, 241 { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, 242 { ZD_CR91, 0x00 }, /* 5621 */ 243 { ZD_CR92, 0x0a }, 244 { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */ 245 { ZD_CR99, 0x00 }, /* 5621 */ 246 { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, 247 { ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */ 248 { ZD_CR107, 0x2a }, 249 { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */ 250 { ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */ 251 { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, 252 { ZD_CR114, 0x27 }, 253 { ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) 254 * AL2230 255 */ 256 { ZD_CR116, 0x24 }, 257 { ZD_CR117, 0xfa }, /* for 1211b */ 258 { ZD_CR118, 0xfa }, /* for 1211b */ 259 { ZD_CR119, 0x10 }, 260 { ZD_CR120, 0x4f }, 261 { ZD_CR121, 0x6c }, /* for 1211b */ 262 { ZD_CR122, 0xfc }, /* E0->FC at 4902 */ 263 { ZD_CR123, 0x57 }, /* 5623 */ 264 { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */ 265 { ZD_CR126, 0x6c }, /* 5614 */ 266 { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */ 267 { ZD_CR137, 0x50 }, /* 5614 */ 268 { ZD_CR138, 0xa8 }, 269 { ZD_CR144, 0xac }, /* 5621 */ 270 { ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 }, 271 }; 272 273 static const u32 rv1[] = { 274 0x8cccd0, 275 0x481dc0, 276 0xcfff00, 277 0x25a000, 278 }; 279 280 static const u32 rv2[] = { 281 /* To improve AL2230 yield, improve phase noise, 4713 */ 282 0x25a000, 283 0xa3b2f0, 284 285 0x6da010, /* Reg6 update for MP versio */ 286 0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */ 287 0x116000, 288 0x9dc020, /* External control TX power (ZD_CR31) */ 289 0x5ddb00, /* RegA update for MP version */ 290 0xd99000, /* RegB update for MP version */ 291 0x3ffbd0, /* RegC update for MP version */ 292 0xb00000, /* RegD update for MP version */ 293 294 /* improve phase noise and remove phase calibration,4713 */ 295 0xf01a00, 296 }; 297 298 static const struct zd_ioreq16 ioreqs2[] = { 299 { ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */ 300 { ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */ 301 }; 302 303 static const u32 rv3[] = { 304 /* To improve AL2230 yield, 4713 */ 305 0xf01b00, 306 0xf01e00, 307 0xf01a00, 308 }; 309 310 static const struct zd_ioreq16 ioreqs3[] = { 311 /* related to 6M band edge patching, happens unconditionally */ 312 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, 313 }; 314 315 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, 316 ARRAY_SIZE(zd1211b_ioreqs_shared_1)); 317 if (r) 318 return r; 319 r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1)); 320 if (r) 321 return r; 322 323 if (IS_AL2230S(chip)) { 324 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, 325 ARRAY_SIZE(ioreqs_init_al2230s)); 326 if (r) 327 return r; 328 } 329 330 r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3); 331 if (r) 332 return r; 333 r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1)); 334 if (r) 335 return r; 336 337 if (IS_AL2230S(chip)) 338 r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS); 339 else 340 r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS); 341 if (r) 342 return r; 343 344 r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2)); 345 if (r) 346 return r; 347 r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2)); 348 if (r) 349 return r; 350 r = zd_rfwritev_cr_locked(chip, rv3, ARRAY_SIZE(rv3)); 351 if (r) 352 return r; 353 r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3)); 354 if (r) 355 return r; 356 return zd1211b_al2230_finalize_rf(chip); 357} 358 359static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel) 360{ 361 int r; 362 const u32 *rv = zd1211_al2230_table[channel-1]; 363 struct zd_chip *chip = zd_rf_to_chip(rf); 364 static const struct zd_ioreq16 ioreqs[] = { 365 { ZD_CR138, 0x28 }, 366 { ZD_CR203, 0x06 }, 367 }; 368 369 r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS); 370 if (r) 371 return r; 372 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 373} 374 375static int zd1211b_al2230_set_channel(struct zd_rf *rf, u8 channel) 376{ 377 int r; 378 const u32 *rv = zd1211b_al2230_table[channel-1]; 379 struct zd_chip *chip = zd_rf_to_chip(rf); 380 381 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, 382 ARRAY_SIZE(zd1211b_ioreqs_shared_1)); 383 if (r) 384 return r; 385 386 r = zd_rfwritev_cr_locked(chip, rv, 3); 387 if (r) 388 return r; 389 390 return zd1211b_al2230_finalize_rf(chip); 391} 392 393static int zd1211_al2230_switch_radio_on(struct zd_rf *rf) 394{ 395 struct zd_chip *chip = zd_rf_to_chip(rf); 396 static const struct zd_ioreq16 ioreqs[] = { 397 { ZD_CR11, 0x00 }, 398 { ZD_CR251, 0x3f }, 399 }; 400 401 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 402} 403 404static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf) 405{ 406 struct zd_chip *chip = zd_rf_to_chip(rf); 407 static const struct zd_ioreq16 ioreqs[] = { 408 { ZD_CR11, 0x00 }, 409 { ZD_CR251, 0x7f }, 410 }; 411 412 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 413} 414 415static int al2230_switch_radio_off(struct zd_rf *rf) 416{ 417 struct zd_chip *chip = zd_rf_to_chip(rf); 418 static const struct zd_ioreq16 ioreqs[] = { 419 { ZD_CR11, 0x04 }, 420 { ZD_CR251, 0x2f }, 421 }; 422 423 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 424} 425 426int zd_rf_init_al2230(struct zd_rf *rf) 427{ 428 struct zd_chip *chip = zd_rf_to_chip(rf); 429 430 rf->switch_radio_off = al2230_switch_radio_off; 431 if (zd_chip_is_zd1211b(chip)) { 432 rf->init_hw = zd1211b_al2230_init_hw; 433 rf->set_channel = zd1211b_al2230_set_channel; 434 rf->switch_radio_on = zd1211b_al2230_switch_radio_on; 435 } else { 436 rf->init_hw = zd1211_al2230_init_hw; 437 rf->set_channel = zd1211_al2230_set_channel; 438 rf->switch_radio_on = zd1211_al2230_switch_radio_on; 439 } 440 rf->patch_6m_band_edge = zd_rf_generic_patch_6m; 441 rf->patch_cck_gain = 1; 442 return 0; 443} 444