linux/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
<<
>>
Prefs
   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
  26static const u32 chan_rv[][2] = {
  27        RF_CHANNEL( 1) = { 0x09ec00, 0x8cccc8 },
  28        RF_CHANNEL( 2) = { 0x09ec00, 0x8cccd8 },
  29        RF_CHANNEL( 3) = { 0x09ec00, 0x8cccc0 },
  30        RF_CHANNEL( 4) = { 0x09ec00, 0x8cccd0 },
  31        RF_CHANNEL( 5) = { 0x05ec00, 0x8cccc8 },
  32        RF_CHANNEL( 6) = { 0x05ec00, 0x8cccd8 },
  33        RF_CHANNEL( 7) = { 0x05ec00, 0x8cccc0 },
  34        RF_CHANNEL( 8) = { 0x05ec00, 0x8cccd0 },
  35        RF_CHANNEL( 9) = { 0x0dec00, 0x8cccc8 },
  36        RF_CHANNEL(10) = { 0x0dec00, 0x8cccd8 },
  37        RF_CHANNEL(11) = { 0x0dec00, 0x8cccc0 },
  38        RF_CHANNEL(12) = { 0x0dec00, 0x8cccd0 },
  39        RF_CHANNEL(13) = { 0x03ec00, 0x8cccc8 },
  40        RF_CHANNEL(14) = { 0x03ec00, 0x866660 },
  41};
  42
  43static const u32 std_rv[] = {
  44        0x4ff821,
  45        0xc5fbfc,
  46        0x21ebfe,
  47        0xafd401, /* freq shift 0xaad401 */
  48        0x6cf56a,
  49        0xe04073,
  50        0x193d76,
  51        0x9dd844,
  52        0x500007,
  53        0xd8c010,
  54};
  55
  56static const u32 rv_init1[] = {
  57        0x3c9000,
  58        0xbfffff,
  59        0x700000,
  60        0xf15d58,
  61};
  62
  63static const u32 rv_init2[] = {
  64        0xf15d59,
  65        0xf15d5c,
  66        0xf15d58,
  67};
  68
  69static const struct zd_ioreq16 ioreqs_sw[] = {
  70        { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
  71        { ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
  72};
  73
  74static int zd1211b_al7230b_finalize(struct zd_chip *chip)
  75{
  76        int r;
  77        static const struct zd_ioreq16 ioreqs[] = {
  78                { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 }, { ZD_CR79,  0x58 },
  79                { ZD_CR12,  0xf0 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x58 },
  80                { ZD_CR203, 0x04 },
  81                { },
  82                { ZD_CR240, 0x80 },
  83        };
  84
  85        r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
  86        if (r)
  87                return r;
  88
  89        if (chip->new_phy_layout) {
  90                /* antenna selection? */
  91                r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9);
  92                if (r)
  93                        return r;
  94        }
  95
  96        return zd_iowrite16_locked(chip, 0x04, ZD_CR203);
  97}
  98
  99static int zd1211_al7230b_init_hw(struct zd_rf *rf)
 100{
 101        int r;
 102        struct zd_chip *chip = zd_rf_to_chip(rf);
 103
 104        /* All of these writes are identical to AL2230 unless otherwise
 105         * specified */
 106        static const struct zd_ioreq16 ioreqs_1[] = {
 107                /* This one is 7230-specific, and happens before the rest */
 108                { ZD_CR240,  0x57 },
 109                { },
 110
 111                { ZD_CR15,   0x20 }, { ZD_CR23,   0x40 }, { ZD_CR24,  0x20 },
 112                { ZD_CR26,   0x11 }, { ZD_CR28,   0x3e }, { ZD_CR29,  0x00 },
 113                { ZD_CR44,   0x33 },
 114                /* This value is different for 7230 (was: 0x2a) */
 115                { ZD_CR106,  0x22 },
 116                { ZD_CR107,  0x1a }, { ZD_CR109,  0x09 }, { ZD_CR110,  0x27 },
 117                { ZD_CR111,  0x2b }, { ZD_CR112,  0x2b }, { ZD_CR119,  0x0a },
 118                /* This happened further down in AL2230,
 119                 * and the value changed (was: 0xe0) */
 120                { ZD_CR122,  0xfc },
 121                { ZD_CR10,   0x89 },
 122                /* for newest (3rd cut) AL2300 */
 123                { ZD_CR17,   0x28 },
 124                { ZD_CR26,   0x93 }, { ZD_CR34,   0x30 },
 125                /* for newest (3rd cut) AL2300 */
 126                { ZD_CR35,   0x3e },
 127                { ZD_CR41,   0x24 }, { ZD_CR44,   0x32 },
 128                /* for newest (3rd cut) AL2300 */
 129                { ZD_CR46,   0x96 },
 130                { ZD_CR47,   0x1e }, { ZD_CR79,   0x58 }, { ZD_CR80,  0x30 },
 131                { ZD_CR81,   0x30 }, { ZD_CR87,   0x0a }, { ZD_CR89,  0x04 },
 132                { ZD_CR92,   0x0a }, { ZD_CR99,   0x28 },
 133                /* This value is different for 7230 (was: 0x00) */
 134                { ZD_CR100,  0x02 },
 135                { ZD_CR101,  0x13 }, { ZD_CR102,  0x27 },
 136                /* This value is different for 7230 (was: 0x24) */
 137                { ZD_CR106,  0x22 },
 138                /* This value is different for 7230 (was: 0x2a) */
 139                { ZD_CR107,  0x3f },
 140                { ZD_CR109,  0x09 },
 141                /* This value is different for 7230 (was: 0x13) */
 142                { ZD_CR110,  0x1f },
 143                { ZD_CR111,  0x1f }, { ZD_CR112,  0x1f }, { ZD_CR113, 0x27 },
 144                { ZD_CR114,  0x27 },
 145                /* for newest (3rd cut) AL2300 */
 146                { ZD_CR115,  0x24 },
 147                /* This value is different for 7230 (was: 0x24) */
 148                { ZD_CR116,  0x3f },
 149                /* This value is different for 7230 (was: 0xf4) */
 150                { ZD_CR117,  0xfa },
 151                { ZD_CR118,  0xfc }, { ZD_CR119,  0x10 }, { ZD_CR120, 0x4f },
 152                { ZD_CR121,  0x77 }, { ZD_CR137,  0x88 },
 153                /* This one is 7230-specific */
 154                { ZD_CR138,  0xa8 },
 155                /* This value is different for 7230 (was: 0xff) */
 156                { ZD_CR252,  0x34 },
 157                /* This value is different for 7230 (was: 0xff) */
 158                { ZD_CR253,  0x34 },
 159
 160                /* PLL_OFF */
 161                { ZD_CR251, 0x2f },
 162        };
 163
 164        static const struct zd_ioreq16 ioreqs_2[] = {
 165                { ZD_CR251, 0x3f }, /* PLL_ON */
 166                { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
 167                { ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
 168        };
 169
 170        r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
 171        if (r)
 172                return r;
 173
 174        r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
 175        if (r)
 176                return r;
 177
 178        r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
 179        if (r)
 180                return r;
 181
 182        r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
 183        if (r)
 184                return r;
 185
 186        r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
 187        if (r)
 188                return r;
 189
 190        r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
 191        if (r)
 192                return r;
 193
 194        r = zd_iowrite16_locked(chip, 0x06, ZD_CR203);
 195        if (r)
 196                return r;
 197        r = zd_iowrite16_locked(chip, 0x80, ZD_CR240);
 198        if (r)
 199                return r;
 200
 201        return 0;
 202}
 203
 204static int zd1211b_al7230b_init_hw(struct zd_rf *rf)
 205{
 206        int r;
 207        struct zd_chip *chip = zd_rf_to_chip(rf);
 208
 209        static const struct zd_ioreq16 ioreqs_1[] = {
 210                { ZD_CR240, 0x57 }, { ZD_CR9,   0x9 },
 211                { },
 212                { ZD_CR10,  0x8b }, { ZD_CR15,  0x20 },
 213                { ZD_CR17,  0x2B }, /* for newest (3rd cut) AL2230 */
 214                { ZD_CR20,  0x10 }, /* 4N25->Stone Request */
 215                { ZD_CR23,  0x40 }, { ZD_CR24,  0x20 }, { ZD_CR26,  0x93 },
 216                { ZD_CR28,  0x3e }, { ZD_CR29,  0x00 },
 217                { ZD_CR33,  0x28 }, /* 5613 */
 218                { ZD_CR34,  0x30 },
 219                { ZD_CR35,  0x3e }, /* for newest (3rd cut) AL2230 */
 220                { ZD_CR41,  0x24 }, { ZD_CR44,  0x32 },
 221                { ZD_CR46,  0x99 }, /* for newest (3rd cut) AL2230 */
 222                { ZD_CR47,  0x1e },
 223
 224                /* ZD1215 5610 */
 225                { ZD_CR48,  0x00 }, { ZD_CR49,  0x00 }, { ZD_CR51,  0x01 },
 226                { ZD_CR52,  0x80 }, { ZD_CR53,  0x7e }, { ZD_CR65,  0x00 },
 227                { ZD_CR66,  0x00 }, { ZD_CR67,  0x00 }, { ZD_CR68,  0x00 },
 228                { ZD_CR69,  0x28 },
 229
 230                { ZD_CR79,  0x58 }, { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 },
 231                { ZD_CR87,  0x0A }, { ZD_CR89,  0x04 },
 232                { ZD_CR90,  0x58 }, /* 5112 */
 233                { ZD_CR91,  0x00 }, /* 5613 */
 234                { ZD_CR92,  0x0a },
 235                { ZD_CR98,  0x8d }, /* 4804, for 1212 new algorithm */
 236                { ZD_CR99,  0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 },
 237                { ZD_CR102, 0x27 },
 238                { ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */
 239                { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
 240                { ZD_CR112, 0x1f },
 241        };
 242
 243        static const struct zd_ioreq16 ioreqs_new_phy[] = {
 244                { ZD_CR107, 0x28 },
 245                { ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */
 246                { ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
 247                { ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 },
 248                { ZD_CR121, 0x6c }, /* 5613 */
 249        };
 250
 251        static const struct zd_ioreq16 ioreqs_old_phy[] = {
 252                { ZD_CR107, 0x24 },
 253                { ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */
 254                { ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
 255                { ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 },
 256                { ZD_CR121, 0x6a }, /* 5613 */
 257        };
 258
 259        static const struct zd_ioreq16 ioreqs_2[] = {
 260                { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 },
 261                { ZD_CR117, 0xfa }, { ZD_CR120, 0x4f },
 262                { ZD_CR122, 0xfc }, /* E0->FCh at 4901 */
 263                { ZD_CR123, 0x57 }, /* 5613 */
 264                { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
 265                { ZD_CR126, 0x6c }, /* 5613 */
 266                { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
 267                { ZD_CR130, 0x10 },
 268                { ZD_CR131, 0x00 }, /* 5112 */
 269                { ZD_CR137, 0x50 }, /* 5613 */
 270                { ZD_CR138, 0xa8 }, /* 5112 */
 271                { ZD_CR144, 0xac }, /* 5613 */
 272                { ZD_CR148, 0x40 }, /* 5112 */
 273                { ZD_CR149, 0x40 }, /* 4O07, 50->40 */
 274                { ZD_CR150, 0x1a }, /* 5112, 0C->1A */
 275                { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
 276                { ZD_CR251, 0x2f }, /* PLL_OFF */
 277        };
 278
 279        static const struct zd_ioreq16 ioreqs_3[] = {
 280                { ZD_CR251, 0x7f }, /* PLL_ON */
 281                { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
 282                { ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
 283        };
 284
 285        r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
 286        if (r)
 287                return r;
 288
 289        if (chip->new_phy_layout)
 290                r = zd_iowrite16a_locked(chip, ioreqs_new_phy,
 291                        ARRAY_SIZE(ioreqs_new_phy));
 292        else
 293                r = zd_iowrite16a_locked(chip, ioreqs_old_phy,
 294                        ARRAY_SIZE(ioreqs_old_phy));
 295        if (r)
 296                return r;
 297
 298        r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
 299        if (r)
 300                return r;
 301
 302        r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
 303        if (r)
 304                return r;
 305
 306        r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
 307        if (r)
 308                return r;
 309
 310        r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
 311        if (r)
 312                return r;
 313
 314        r = zd_iowrite16a_locked(chip, ioreqs_3, ARRAY_SIZE(ioreqs_3));
 315        if (r)
 316                return r;
 317
 318        r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
 319        if (r)
 320                return r;
 321
 322        return zd1211b_al7230b_finalize(chip);
 323}
 324
 325static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel)
 326{
 327        int r;
 328        const u32 *rv = chan_rv[channel-1];
 329        struct zd_chip *chip = zd_rf_to_chip(rf);
 330
 331        static const struct zd_ioreq16 ioreqs[] = {
 332                /* PLL_ON */
 333                { ZD_CR251, 0x3f },
 334                { ZD_CR203, 0x06 }, { ZD_CR240, 0x08 },
 335        };
 336
 337        r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
 338        if (r)
 339                return r;
 340
 341        /* PLL_OFF */
 342        r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
 343        if (r)
 344                return r;
 345
 346        r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
 347        if (r)
 348                return r;
 349
 350        r = zd_rfwrite_cr_locked(chip, 0x3c9000);
 351        if (r)
 352                return r;
 353        r = zd_rfwrite_cr_locked(chip, 0xf15d58);
 354        if (r)
 355                return r;
 356
 357        r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
 358        if (r)
 359                return r;
 360
 361        r = zd_rfwritev_cr_locked(chip, rv, 2);
 362        if (r)
 363                return r;
 364
 365        r = zd_rfwrite_cr_locked(chip, 0x3c9000);
 366        if (r)
 367                return r;
 368
 369        return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
 370}
 371
 372static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
 373{
 374        int r;
 375        const u32 *rv = chan_rv[channel-1];
 376        struct zd_chip *chip = zd_rf_to_chip(rf);
 377
 378        r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
 379        if (r)
 380                return r;
 381        r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9);
 382        if (r)
 383                return r;
 384
 385        /* PLL_OFF */
 386        r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
 387        if (r)
 388                return r;
 389        r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
 390        if (r)
 391                return r;
 392
 393        r = zd_rfwrite_cr_locked(chip, 0x3c9000);
 394        if (r)
 395                return r;
 396        r = zd_rfwrite_cr_locked(chip, 0xf15d58);
 397        if (r)
 398                return r;
 399
 400        r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
 401        if (r)
 402                return r;
 403
 404        r = zd_rfwritev_cr_locked(chip, rv, 2);
 405        if (r)
 406                return r;
 407
 408        r = zd_rfwrite_cr_locked(chip, 0x3c9000);
 409        if (r)
 410                return r;
 411
 412        r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251);
 413        if (r)
 414                return r;
 415
 416        return zd1211b_al7230b_finalize(chip);
 417}
 418
 419static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf)
 420{
 421        struct zd_chip *chip = zd_rf_to_chip(rf);
 422        static const struct zd_ioreq16 ioreqs[] = {
 423                { ZD_CR11,  0x00 },
 424                { ZD_CR251, 0x3f },
 425        };
 426
 427        return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
 428}
 429
 430static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf)
 431{
 432        struct zd_chip *chip = zd_rf_to_chip(rf);
 433        static const struct zd_ioreq16 ioreqs[] = {
 434                { ZD_CR11,  0x00 },
 435                { ZD_CR251, 0x7f },
 436        };
 437
 438        return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
 439}
 440
 441static int al7230b_switch_radio_off(struct zd_rf *rf)
 442{
 443        struct zd_chip *chip = zd_rf_to_chip(rf);
 444        static const struct zd_ioreq16 ioreqs[] = {
 445                { ZD_CR11,  0x04 },
 446                { ZD_CR251, 0x2f },
 447        };
 448
 449        return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
 450}
 451
 452/* ZD1211B+AL7230B 6m band edge patching differs slightly from other
 453 * configurations */
 454static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel)
 455{
 456        struct zd_chip *chip = zd_rf_to_chip(rf);
 457        struct zd_ioreq16 ioreqs[] = {
 458                { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 },
 459        };
 460
 461        /* FIXME: Channel 11 is not the edge for all regulatory domains. */
 462        if (channel == 1) {
 463                ioreqs[0].value = 0x0e;
 464                ioreqs[1].value = 0x10;
 465        } else if (channel == 11) {
 466                ioreqs[0].value = 0x10;
 467                ioreqs[1].value = 0x10;
 468        }
 469
 470        dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
 471        return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
 472}
 473
 474int zd_rf_init_al7230b(struct zd_rf *rf)
 475{
 476        struct zd_chip *chip = zd_rf_to_chip(rf);
 477
 478        if (zd_chip_is_zd1211b(chip)) {
 479                rf->init_hw = zd1211b_al7230b_init_hw;
 480                rf->switch_radio_on = zd1211b_al7230b_switch_radio_on;
 481                rf->set_channel = zd1211b_al7230b_set_channel;
 482                rf->patch_6m_band_edge = zd1211b_al7230b_patch_6m;
 483        } else {
 484                rf->init_hw = zd1211_al7230b_init_hw;
 485                rf->switch_radio_on = zd1211_al7230b_switch_radio_on;
 486                rf->set_channel = zd1211_al7230b_set_channel;
 487                rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
 488                rf->patch_cck_gain = 1;
 489        }
 490
 491        rf->switch_radio_off = al7230b_switch_radio_off;
 492
 493        return 0;
 494}
 495