1/* zd_rf_al2230.c: Functions for the AL2230 RF controller 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18#include <linux/kernel.h> 19 20#include "zd_rf.h" 21#include "zd_usb.h" 22#include "zd_chip.h" 23 24static const u32 zd1211_al2230_table[][3] = { 25 RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, }, 26 RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, }, 27 RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, }, 28 RF_CHANNEL( 4) = { 0x03e790, 0x0b3331, 0x00000d, }, 29 RF_CHANNEL( 5) = { 0x03f7a0, 0x033331, 0x00000d, }, 30 RF_CHANNEL( 6) = { 0x03f7a0, 0x0b3331, 0x00000d, }, 31 RF_CHANNEL( 7) = { 0x03e7a0, 0x033331, 0x00000d, }, 32 RF_CHANNEL( 8) = { 0x03e7a0, 0x0b3331, 0x00000d, }, 33 RF_CHANNEL( 9) = { 0x03f7b0, 0x033331, 0x00000d, }, 34 RF_CHANNEL(10) = { 0x03f7b0, 0x0b3331, 0x00000d, }, 35 RF_CHANNEL(11) = { 0x03e7b0, 0x033331, 0x00000d, }, 36 RF_CHANNEL(12) = { 0x03e7b0, 0x0b3331, 0x00000d, }, 37 RF_CHANNEL(13) = { 0x03f7c0, 0x033331, 0x00000d, }, 38 RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, }, 39}; 40 41static const u32 zd1211b_al2230_table[][3] = { 42 RF_CHANNEL( 1) = { 0x09efc0, 0x8cccc0, 0xb00000, }, 43 RF_CHANNEL( 2) = { 0x09efc0, 0x8cccd0, 0xb00000, }, 44 RF_CHANNEL( 3) = { 0x09e7c0, 0x8cccc0, 0xb00000, }, 45 RF_CHANNEL( 4) = { 0x09e7c0, 0x8cccd0, 0xb00000, }, 46 RF_CHANNEL( 5) = { 0x05efc0, 0x8cccc0, 0xb00000, }, 47 RF_CHANNEL( 6) = { 0x05efc0, 0x8cccd0, 0xb00000, }, 48 RF_CHANNEL( 7) = { 0x05e7c0, 0x8cccc0, 0xb00000, }, 49 RF_CHANNEL( 8) = { 0x05e7c0, 0x8cccd0, 0xb00000, }, 50 RF_CHANNEL( 9) = { 0x0defc0, 0x8cccc0, 0xb00000, }, 51 RF_CHANNEL(10) = { 0x0defc0, 0x8cccd0, 0xb00000, }, 52 RF_CHANNEL(11) = { 0x0de7c0, 0x8cccc0, 0xb00000, }, 53 RF_CHANNEL(12) = { 0x0de7c0, 0x8cccd0, 0xb00000, }, 54 RF_CHANNEL(13) = { 0x03efc0, 0x8cccc0, 0xb00000, }, 55 RF_CHANNEL(14) = { 0x03e7c0, 0x866660, 0xb00000, }, 56}; 57 58static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = { 59 { CR240, 0x57 }, { CR9, 0xe0 }, 60}; 61 62static const struct zd_ioreq16 ioreqs_init_al2230s[] = { 63 { CR47, 0x1e }, /* MARK_002 */ 64 { CR106, 0x22 }, 65 { CR107, 0x2a }, /* MARK_002 */ 66 { CR109, 0x13 }, /* MARK_002 */ 67 { CR118, 0xf8 }, /* MARK_002 */ 68 { CR119, 0x12 }, { CR122, 0xe0 }, 69 { CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */ 70 { CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */ 71 { CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */ 72}; 73 74static int zd1211b_al2230_finalize_rf(struct zd_chip *chip) 75{ 76 int r; 77 static const struct zd_ioreq16 ioreqs[] = { 78 { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, 79 { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, 80 { CR203, 0x06 }, 81 { }, 82 83 { CR240, 0x80 }, 84 }; 85 86 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 87 if (r) 88 return r; 89 90 /* related to antenna selection? */ 91 if (chip->new_phy_layout) { 92 r = zd_iowrite16_locked(chip, 0xe1, CR9); 93 if (r) 94 return r; 95 } 96 97 return zd_iowrite16_locked(chip, 0x06, CR203); 98} 99 100static int zd1211_al2230_init_hw(struct zd_rf *rf) 101{ 102 int r; 103 struct zd_chip *chip = zd_rf_to_chip(rf); 104 105 static const struct zd_ioreq16 ioreqs_init[] = { 106 { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 }, 107 { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 }, 108 { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a }, 109 { CR109, 0x09 }, { CR110, 0x27 }, { CR111, 0x2b }, 110 { CR112, 0x2b }, { CR119, 0x0a }, { CR10, 0x89 }, 111 /* for newest (3rd cut) AL2300 */ 112 { CR17, 0x28 }, 113 { CR26, 0x93 }, { CR34, 0x30 }, 114 /* for newest (3rd cut) AL2300 */ 115 { CR35, 0x3e }, 116 { CR41, 0x24 }, { CR44, 0x32 }, 117 /* for newest (3rd cut) AL2300 */ 118 { CR46, 0x96 }, 119 { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 }, 120 { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, 121 { CR92, 0x0a }, { CR99, 0x28 }, { CR100, 0x00 }, 122 { CR101, 0x13 }, { CR102, 0x27 }, { CR106, 0x24 }, 123 { CR107, 0x2a }, { CR109, 0x09 }, { CR110, 0x13 }, 124 { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, 125 { CR114, 0x27 }, 126 /* for newest (3rd cut) AL2300 */ 127 { CR115, 0x24 }, 128 { CR116, 0x24 }, { CR117, 0xf4 }, { CR118, 0xfc }, 129 { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 }, 130 { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff }, 131 { CR253, 0xff }, 132 }; 133 134 static const struct zd_ioreq16 ioreqs_pll[] = { 135 /* shdnb(PLL_ON)=0 */ 136 { CR251, 0x2f }, 137 /* shdnb(PLL_ON)=1 */ 138 { CR251, 0x3f }, 139 { CR138, 0x28 }, { CR203, 0x06 }, 140 }; 141 142 static const u32 rv1[] = { 143 /* Channel 1 */ 144 0x03f790, 145 0x033331, 146 0x00000d, 147 148 0x0b3331, 149 0x03b812, 150 0x00fff3, 151 }; 152 153 static const u32 rv2[] = { 154 0x000da4, 155 0x0f4dc5, /* fix freq shift, 0x04edc5 */ 156 0x0805b6, 157 0x011687, 158 0x000688, 159 0x0403b9, /* external control TX power (CR31) */ 160 0x00dbba, 161 0x00099b, 162 0x0bdffc, 163 0x00000d, 164 0x00500f, 165 }; 166 167 static const u32 rv3[] = { 168 0x00d00f, 169 0x004c0f, 170 0x00540f, 171 0x00700f, 172 0x00500f, 173 }; 174 175 r = zd_iowrite16a_locked(chip, ioreqs_init, ARRAY_SIZE(ioreqs_init)); 176 if (r) 177 return r; 178 179 if (chip->al2230s_bit) { 180 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, 181 ARRAY_SIZE(ioreqs_init_al2230s)); 182 if (r) 183 return r; 184 } 185 186 r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS); 187 if (r) 188 return r; 189 190 /* improve band edge for AL2230S */ 191 if (chip->al2230s_bit) 192 r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS); 193 else 194 r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS); 195 if (r) 196 return r; 197 198 r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS); 199 if (r) 200 return r; 201 202 r = zd_iowrite16a_locked(chip, ioreqs_pll, ARRAY_SIZE(ioreqs_pll)); 203 if (r) 204 return r; 205 206 r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS); 207 if (r) 208 return r; 209 210 return 0; 211} 212 213static int zd1211b_al2230_init_hw(struct zd_rf *rf) 214{ 215 int r; 216 struct zd_chip *chip = zd_rf_to_chip(rf); 217 218 static const struct zd_ioreq16 ioreqs1[] = { 219 { CR10, 0x89 }, { CR15, 0x20 }, 220 { CR17, 0x2B }, /* for newest(3rd cut) AL2230 */ 221 { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 }, 222 { CR28, 0x3e }, { CR29, 0x00 }, 223 { CR33, 0x28 }, /* 5621 */ 224 { CR34, 0x30 }, 225 { CR35, 0x3e }, /* for newest(3rd cut) AL2230 */ 226 { CR41, 0x24 }, { CR44, 0x32 }, 227 { CR46, 0x99 }, /* for newest(3rd cut) AL2230 */ 228 { CR47, 0x1e }, 229 230 /* ZD1211B 05.06.10 */ 231 { CR48, 0x06 }, { CR49, 0xf9 }, { CR51, 0x01 }, 232 { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 }, 233 { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 }, 234 { CR69, 0x28 }, 235 236 { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 }, 237 { CR87, 0x0a }, { CR89, 0x04 }, 238 { CR91, 0x00 }, /* 5621 */ 239 { CR92, 0x0a }, 240 { CR98, 0x8d }, /* 4804, for 1212 new algorithm */ 241 { CR99, 0x00 }, /* 5621 */ 242 { CR101, 0x13 }, { CR102, 0x27 }, 243 { CR106, 0x24 }, /* for newest(3rd cut) AL2230 */ 244 { CR107, 0x2a }, 245 { CR109, 0x13 }, /* 4804, for 1212 new algorithm */ 246 { CR110, 0x1f }, /* 4804, for 1212 new algorithm */ 247 { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, 248 { CR114, 0x27 }, 249 { CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */ 250 { CR116, 0x24 }, 251 { CR117, 0xfa }, /* for 1211b */ 252 { CR118, 0xfa }, /* for 1211b */ 253 { CR119, 0x10 }, 254 { CR120, 0x4f }, 255 { CR121, 0x6c }, /* for 1211b */ 256 { CR122, 0xfc }, /* E0->FC at 4902 */ 257 { CR123, 0x57 }, /* 5623 */ 258 { CR125, 0xad }, /* 4804, for 1212 new algorithm */ 259 { CR126, 0x6c }, /* 5614 */ 260 { CR127, 0x03 }, /* 4804, for 1212 new algorithm */ 261 { CR137, 0x50 }, /* 5614 */ 262 { CR138, 0xa8 }, 263 { CR144, 0xac }, /* 5621 */ 264 { CR150, 0x0d }, { CR252, 0x34 }, { CR253, 0x34 }, 265 }; 266 267 static const u32 rv1[] = { 268 0x8cccd0, 269 0x481dc0, 270 0xcfff00, 271 0x25a000, 272 }; 273 274 static const u32 rv2[] = { 275 /* To improve AL2230 yield, improve phase noise, 4713 */ 276 0x25a000, 277 0xa3b2f0, 278 279 0x6da010, /* Reg6 update for MP versio */ 280 0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */ 281 0x116000, 282 0x9dc020, /* External control TX power (CR31) */ 283 0x5ddb00, /* RegA update for MP version */ 284 0xd99000, /* RegB update for MP version */ 285 0x3ffbd0, /* RegC update for MP version */ 286 0xb00000, /* RegD update for MP version */ 287 288 /* improve phase noise and remove phase calibration,4713 */ 289 0xf01a00, 290 }; 291 292 static const struct zd_ioreq16 ioreqs2[] = { 293 { CR251, 0x2f }, /* shdnb(PLL_ON)=0 */ 294 { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */ 295 }; 296 297 static const u32 rv3[] = { 298 /* To improve AL2230 yield, 4713 */ 299 0xf01b00, 300 0xf01e00, 301 0xf01a00, 302 }; 303 304 static const struct zd_ioreq16 ioreqs3[] = { 305 /* related to 6M band edge patching, happens unconditionally */ 306 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 307 }; 308 309 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, 310 ARRAY_SIZE(zd1211b_ioreqs_shared_1)); 311 if (r) 312 return r; 313 r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1)); 314 if (r) 315 return r; 316 317 if (chip->al2230s_bit) { 318 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, 319 ARRAY_SIZE(ioreqs_init_al2230s)); 320 if (r) 321 return r; 322 } 323 324 r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3); 325 if (r) 326 return r; 327 r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1)); 328 if (r) 329 return r; 330 331 if (chip->al2230s_bit) 332 r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS); 333 else 334 r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS); 335 if (r) 336 return r; 337 338 r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2)); 339 if (r) 340 return r; 341 r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2)); 342 if (r) 343 return r; 344 r = zd_rfwritev_cr_locked(chip, rv3, ARRAY_SIZE(rv3)); 345 if (r) 346 return r; 347 r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3)); 348 if (r) 349 return r; 350 return zd1211b_al2230_finalize_rf(chip); 351} 352 353static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel) 354{ 355 int r; 356 const u32 *rv = zd1211_al2230_table[channel-1]; 357 struct zd_chip *chip = zd_rf_to_chip(rf); 358 static const struct zd_ioreq16 ioreqs[] = { 359 { CR138, 0x28 }, 360 { CR203, 0x06 }, 361 }; 362 363 r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS); 364 if (r) 365 return r; 366 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 367} 368 369static int zd1211b_al2230_set_channel(struct zd_rf *rf, u8 channel) 370{ 371 int r; 372 const u32 *rv = zd1211b_al2230_table[channel-1]; 373 struct zd_chip *chip = zd_rf_to_chip(rf); 374 375 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, 376 ARRAY_SIZE(zd1211b_ioreqs_shared_1)); 377 if (r) 378 return r; 379 380 r = zd_rfwritev_cr_locked(chip, rv, 3); 381 if (r) 382 return r; 383 384 return zd1211b_al2230_finalize_rf(chip); 385} 386 387static int zd1211_al2230_switch_radio_on(struct zd_rf *rf) 388{ 389 struct zd_chip *chip = zd_rf_to_chip(rf); 390 static const struct zd_ioreq16 ioreqs[] = { 391 { CR11, 0x00 }, 392 { CR251, 0x3f }, 393 }; 394 395 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 396} 397 398static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf) 399{ 400 struct zd_chip *chip = zd_rf_to_chip(rf); 401 static const struct zd_ioreq16 ioreqs[] = { 402 { CR11, 0x00 }, 403 { CR251, 0x7f }, 404 }; 405 406 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 407} 408 409static int al2230_switch_radio_off(struct zd_rf *rf) 410{ 411 struct zd_chip *chip = zd_rf_to_chip(rf); 412 static const struct zd_ioreq16 ioreqs[] = { 413 { CR11, 0x04 }, 414 { CR251, 0x2f }, 415 }; 416 417 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 418} 419 420int zd_rf_init_al2230(struct zd_rf *rf) 421{ 422 struct zd_chip *chip = zd_rf_to_chip(rf); 423 424 rf->switch_radio_off = al2230_switch_radio_off; 425 if (chip->is_zd1211b) { 426 rf->init_hw = zd1211b_al2230_init_hw; 427 rf->set_channel = zd1211b_al2230_set_channel; 428 rf->switch_radio_on = zd1211b_al2230_switch_radio_on; 429 } else { 430 rf->init_hw = zd1211_al2230_init_hw; 431 rf->set_channel = zd1211_al2230_set_channel; 432 rf->switch_radio_on = zd1211_al2230_switch_radio_on; 433 } 434 rf->patch_6m_band_edge = zd_rf_generic_patch_6m; 435 return 0; 436} 437