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