1 /* 2 * Sonics Silicon Backplane 3 * PCMCIA-Hostbus related functions 4 * 5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> 6 * Copyright 2007-2008 Michael Buesch <m@bues.ch> 7 * 8 * Licensed under the GNU/GPL. See COPYING for details. 9 */ 10 11 #include <linux/ssb/ssb.h> 12 #include <linux/delay.h> 13 #include <linux/io.h> 14 #include <linux/etherdevice.h> 15 16 #include <pcmcia/cistpl.h> 17 #include <pcmcia/ciscode.h> 18 #include <pcmcia/ds.h> 19 #include <pcmcia/cisreg.h> 20 21 #include "ssb_private.h" 22 23 24 /* Define the following to 1 to enable a printk on each coreswitch. */ 25 #define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0 26 27 28 /* PCMCIA configuration registers */ 29 #define SSB_PCMCIA_ADDRESS0 0x2E 30 #define SSB_PCMCIA_ADDRESS1 0x30 31 #define SSB_PCMCIA_ADDRESS2 0x32 32 #define SSB_PCMCIA_MEMSEG 0x34 33 #define SSB_PCMCIA_SPROMCTL 0x36 34 #define SSB_PCMCIA_SPROMCTL_IDLE 0 35 #define SSB_PCMCIA_SPROMCTL_WRITE 1 36 #define SSB_PCMCIA_SPROMCTL_READ 2 37 #define SSB_PCMCIA_SPROMCTL_WRITEEN 4 38 #define SSB_PCMCIA_SPROMCTL_WRITEDIS 7 39 #define SSB_PCMCIA_SPROMCTL_DONE 8 40 #define SSB_PCMCIA_SPROM_DATALO 0x38 41 #define SSB_PCMCIA_SPROM_DATAHI 0x3A 42 #define SSB_PCMCIA_SPROM_ADDRLO 0x3C 43 #define SSB_PCMCIA_SPROM_ADDRHI 0x3E 44 45 /* Hardware invariants CIS tuples */ 46 #define SSB_PCMCIA_CIS 0x80 47 #define SSB_PCMCIA_CIS_ID 0x01 48 #define SSB_PCMCIA_CIS_BOARDREV 0x02 49 #define SSB_PCMCIA_CIS_PA 0x03 50 #define SSB_PCMCIA_CIS_PA_PA0B0_LO 0 51 #define SSB_PCMCIA_CIS_PA_PA0B0_HI 1 52 #define SSB_PCMCIA_CIS_PA_PA0B1_LO 2 53 #define SSB_PCMCIA_CIS_PA_PA0B1_HI 3 54 #define SSB_PCMCIA_CIS_PA_PA0B2_LO 4 55 #define SSB_PCMCIA_CIS_PA_PA0B2_HI 5 56 #define SSB_PCMCIA_CIS_PA_ITSSI 6 57 #define SSB_PCMCIA_CIS_PA_MAXPOW 7 58 #define SSB_PCMCIA_CIS_OEMNAME 0x04 59 #define SSB_PCMCIA_CIS_CCODE 0x05 60 #define SSB_PCMCIA_CIS_ANTENNA 0x06 61 #define SSB_PCMCIA_CIS_ANTGAIN 0x07 62 #define SSB_PCMCIA_CIS_BFLAGS 0x08 63 #define SSB_PCMCIA_CIS_LEDS 0x09 64 65 /* PCMCIA SPROM size. */ 66 #define SSB_PCMCIA_SPROM_SIZE 256 67 #define SSB_PCMCIA_SPROM_SIZE_BYTES (SSB_PCMCIA_SPROM_SIZE * sizeof(u16)) 68 69 70 /* Write to a PCMCIA configuration register. */ 71 static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value) 72 { 73 int res; 74 75 res = pcmcia_write_config_byte(bus->host_pcmcia, offset, value); 76 if (unlikely(res != 0)) 77 return -EBUSY; 78 79 return 0; 80 } 81 82 /* Read from a PCMCIA configuration register. */ 83 static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value) 84 { 85 int res; 86 87 res = pcmcia_read_config_byte(bus->host_pcmcia, offset, value); 88 if (unlikely(res != 0)) 89 return -EBUSY; 90 91 return 0; 92 } 93 94 int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus, 95 u8 coreidx) 96 { 97 int err; 98 int attempts = 0; 99 u32 cur_core; 100 u32 addr; 101 u32 read_addr; 102 u8 val; 103 104 addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE; 105 while (1) { 106 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS0, 107 (addr & 0x0000F000) >> 12); 108 if (err) 109 goto error; 110 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS1, 111 (addr & 0x00FF0000) >> 16); 112 if (err) 113 goto error; 114 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS2, 115 (addr & 0xFF000000) >> 24); 116 if (err) 117 goto error; 118 119 read_addr = 0; 120 121 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS0, &val); 122 if (err) 123 goto error; 124 read_addr |= ((u32)(val & 0x0F)) << 12; 125 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS1, &val); 126 if (err) 127 goto error; 128 read_addr |= ((u32)val) << 16; 129 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS2, &val); 130 if (err) 131 goto error; 132 read_addr |= ((u32)val) << 24; 133 134 cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE; 135 if (cur_core == coreidx) 136 break; 137 138 err = -ETIMEDOUT; 139 if (attempts++ > SSB_BAR0_MAX_RETRIES) 140 goto error; 141 udelay(10); 142 } 143 144 return 0; 145 error: 146 ssb_err("Failed to switch to core %u\n", coreidx); 147 return err; 148 } 149 150 static int ssb_pcmcia_switch_core(struct ssb_bus *bus, struct ssb_device *dev) 151 { 152 int err; 153 154 #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 155 ssb_info("Switching to %s core, index %d\n", 156 ssb_core_name(dev->id.coreid), 157 dev->core_index); 158 #endif 159 160 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index); 161 if (!err) 162 bus->mapped_device = dev; 163 164 return err; 165 } 166 167 int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg) 168 { 169 int attempts = 0; 170 int err; 171 u8 val; 172 173 SSB_WARN_ON((seg != 0) && (seg != 1)); 174 while (1) { 175 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_MEMSEG, seg); 176 if (err) 177 goto error; 178 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_MEMSEG, &val); 179 if (err) 180 goto error; 181 if (val == seg) 182 break; 183 184 err = -ETIMEDOUT; 185 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES)) 186 goto error; 187 udelay(10); 188 } 189 bus->mapped_pcmcia_seg = seg; 190 191 return 0; 192 error: 193 ssb_err("Failed to switch pcmcia segment\n"); 194 return err; 195 } 196 197 static int select_core_and_segment(struct ssb_device *dev, 198 u16 *offset) 199 { 200 struct ssb_bus *bus = dev->bus; 201 int err; 202 u8 need_segment; 203 204 if (*offset >= 0x800) { 205 *offset -= 0x800; 206 need_segment = 1; 207 } else 208 need_segment = 0; 209 210 if (unlikely(dev != bus->mapped_device)) { 211 err = ssb_pcmcia_switch_core(bus, dev); 212 if (unlikely(err)) 213 return err; 214 } 215 if (unlikely(need_segment != bus->mapped_pcmcia_seg)) { 216 err = ssb_pcmcia_switch_segment(bus, need_segment); 217 if (unlikely(err)) 218 return err; 219 } 220 221 return 0; 222 } 223 224 static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset) 225 { 226 struct ssb_bus *bus = dev->bus; 227 unsigned long flags; 228 int err; 229 u8 value = 0xFF; 230 231 spin_lock_irqsave(&bus->bar_lock, flags); 232 err = select_core_and_segment(dev, &offset); 233 if (likely(!err)) 234 value = readb(bus->mmio + offset); 235 spin_unlock_irqrestore(&bus->bar_lock, flags); 236 237 return value; 238 } 239 240 static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) 241 { 242 struct ssb_bus *bus = dev->bus; 243 unsigned long flags; 244 int err; 245 u16 value = 0xFFFF; 246 247 spin_lock_irqsave(&bus->bar_lock, flags); 248 err = select_core_and_segment(dev, &offset); 249 if (likely(!err)) 250 value = readw(bus->mmio + offset); 251 spin_unlock_irqrestore(&bus->bar_lock, flags); 252 253 return value; 254 } 255 256 static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset) 257 { 258 struct ssb_bus *bus = dev->bus; 259 unsigned long flags; 260 int err; 261 u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF; 262 263 spin_lock_irqsave(&bus->bar_lock, flags); 264 err = select_core_and_segment(dev, &offset); 265 if (likely(!err)) { 266 lo = readw(bus->mmio + offset); 267 hi = readw(bus->mmio + offset + 2); 268 } 269 spin_unlock_irqrestore(&bus->bar_lock, flags); 270 271 return (lo | (hi << 16)); 272 } 273 274 #ifdef CONFIG_SSB_BLOCKIO 275 static void ssb_pcmcia_block_read(struct ssb_device *dev, void *buffer, 276 size_t count, u16 offset, u8 reg_width) 277 { 278 struct ssb_bus *bus = dev->bus; 279 unsigned long flags; 280 void __iomem *addr = bus->mmio + offset; 281 int err; 282 283 spin_lock_irqsave(&bus->bar_lock, flags); 284 err = select_core_and_segment(dev, &offset); 285 if (unlikely(err)) { 286 memset(buffer, 0xFF, count); 287 goto unlock; 288 } 289 switch (reg_width) { 290 case sizeof(u8): { 291 u8 *buf = buffer; 292 293 while (count) { 294 *buf = __raw_readb(addr); 295 buf++; 296 count--; 297 } 298 break; 299 } 300 case sizeof(u16): { 301 __le16 *buf = buffer; 302 303 SSB_WARN_ON(count & 1); 304 while (count) { 305 *buf = (__force __le16)__raw_readw(addr); 306 buf++; 307 count -= 2; 308 } 309 break; 310 } 311 case sizeof(u32): { 312 __le16 *buf = buffer; 313 314 SSB_WARN_ON(count & 3); 315 while (count) { 316 *buf = (__force __le16)__raw_readw(addr); 317 buf++; 318 *buf = (__force __le16)__raw_readw(addr + 2); 319 buf++; 320 count -= 4; 321 } 322 break; 323 } 324 default: 325 SSB_WARN_ON(1); 326 } 327 unlock: 328 spin_unlock_irqrestore(&bus->bar_lock, flags); 329 } 330 #endif /* CONFIG_SSB_BLOCKIO */ 331 332 static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value) 333 { 334 struct ssb_bus *bus = dev->bus; 335 unsigned long flags; 336 int err; 337 338 spin_lock_irqsave(&bus->bar_lock, flags); 339 err = select_core_and_segment(dev, &offset); 340 if (likely(!err)) 341 writeb(value, bus->mmio + offset); 342 mmiowb(); 343 spin_unlock_irqrestore(&bus->bar_lock, flags); 344 } 345 346 static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) 347 { 348 struct ssb_bus *bus = dev->bus; 349 unsigned long flags; 350 int err; 351 352 spin_lock_irqsave(&bus->bar_lock, flags); 353 err = select_core_and_segment(dev, &offset); 354 if (likely(!err)) 355 writew(value, bus->mmio + offset); 356 mmiowb(); 357 spin_unlock_irqrestore(&bus->bar_lock, flags); 358 } 359 360 static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value) 361 { 362 struct ssb_bus *bus = dev->bus; 363 unsigned long flags; 364 int err; 365 366 spin_lock_irqsave(&bus->bar_lock, flags); 367 err = select_core_and_segment(dev, &offset); 368 if (likely(!err)) { 369 writew((value & 0x0000FFFF), bus->mmio + offset); 370 writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2); 371 } 372 mmiowb(); 373 spin_unlock_irqrestore(&bus->bar_lock, flags); 374 } 375 376 #ifdef CONFIG_SSB_BLOCKIO 377 static void ssb_pcmcia_block_write(struct ssb_device *dev, const void *buffer, 378 size_t count, u16 offset, u8 reg_width) 379 { 380 struct ssb_bus *bus = dev->bus; 381 unsigned long flags; 382 void __iomem *addr = bus->mmio + offset; 383 int err; 384 385 spin_lock_irqsave(&bus->bar_lock, flags); 386 err = select_core_and_segment(dev, &offset); 387 if (unlikely(err)) 388 goto unlock; 389 switch (reg_width) { 390 case sizeof(u8): { 391 const u8 *buf = buffer; 392 393 while (count) { 394 __raw_writeb(*buf, addr); 395 buf++; 396 count--; 397 } 398 break; 399 } 400 case sizeof(u16): { 401 const __le16 *buf = buffer; 402 403 SSB_WARN_ON(count & 1); 404 while (count) { 405 __raw_writew((__force u16)(*buf), addr); 406 buf++; 407 count -= 2; 408 } 409 break; 410 } 411 case sizeof(u32): { 412 const __le16 *buf = buffer; 413 414 SSB_WARN_ON(count & 3); 415 while (count) { 416 __raw_writew((__force u16)(*buf), addr); 417 buf++; 418 __raw_writew((__force u16)(*buf), addr + 2); 419 buf++; 420 count -= 4; 421 } 422 break; 423 } 424 default: 425 SSB_WARN_ON(1); 426 } 427 unlock: 428 mmiowb(); 429 spin_unlock_irqrestore(&bus->bar_lock, flags); 430 } 431 #endif /* CONFIG_SSB_BLOCKIO */ 432 433 /* Not "static", as it's used in main.c */ 434 const struct ssb_bus_ops ssb_pcmcia_ops = { 435 .read8 = ssb_pcmcia_read8, 436 .read16 = ssb_pcmcia_read16, 437 .read32 = ssb_pcmcia_read32, 438 .write8 = ssb_pcmcia_write8, 439 .write16 = ssb_pcmcia_write16, 440 .write32 = ssb_pcmcia_write32, 441 #ifdef CONFIG_SSB_BLOCKIO 442 .block_read = ssb_pcmcia_block_read, 443 .block_write = ssb_pcmcia_block_write, 444 #endif 445 }; 446 447 static int ssb_pcmcia_sprom_command(struct ssb_bus *bus, u8 command) 448 { 449 unsigned int i; 450 int err; 451 u8 value; 452 453 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROMCTL, command); 454 if (err) 455 return err; 456 for (i = 0; i < 1000; i++) { 457 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROMCTL, &value); 458 if (err) 459 return err; 460 if (value & SSB_PCMCIA_SPROMCTL_DONE) 461 return 0; 462 udelay(10); 463 } 464 465 return -ETIMEDOUT; 466 } 467 468 /* offset is the 16bit word offset */ 469 static int ssb_pcmcia_sprom_read(struct ssb_bus *bus, u16 offset, u16 *value) 470 { 471 int err; 472 u8 lo, hi; 473 474 offset *= 2; /* Make byte offset */ 475 476 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO, 477 (offset & 0x00FF)); 478 if (err) 479 return err; 480 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI, 481 (offset & 0xFF00) >> 8); 482 if (err) 483 return err; 484 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_READ); 485 if (err) 486 return err; 487 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATALO, &lo); 488 if (err) 489 return err; 490 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATAHI, &hi); 491 if (err) 492 return err; 493 *value = (lo | (((u16)hi) << 8)); 494 495 return 0; 496 } 497 498 /* offset is the 16bit word offset */ 499 static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value) 500 { 501 int err; 502 503 offset *= 2; /* Make byte offset */ 504 505 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO, 506 (offset & 0x00FF)); 507 if (err) 508 return err; 509 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI, 510 (offset & 0xFF00) >> 8); 511 if (err) 512 return err; 513 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATALO, 514 (value & 0x00FF)); 515 if (err) 516 return err; 517 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATAHI, 518 (value & 0xFF00) >> 8); 519 if (err) 520 return err; 521 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITE); 522 if (err) 523 return err; 524 msleep(20); 525 526 return 0; 527 } 528 529 /* Read the SPROM image. bufsize is in 16bit words. */ 530 static int ssb_pcmcia_sprom_read_all(struct ssb_bus *bus, u16 *sprom) 531 { 532 int err, i; 533 534 for (i = 0; i < SSB_PCMCIA_SPROM_SIZE; i++) { 535 err = ssb_pcmcia_sprom_read(bus, i, &sprom[i]); 536 if (err) 537 return err; 538 } 539 540 return 0; 541 } 542 543 /* Write the SPROM image. size is in 16bit words. */ 544 static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom) 545 { 546 int i, err; 547 bool failed = 0; 548 size_t size = SSB_PCMCIA_SPROM_SIZE; 549 550 ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n"); 551 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN); 552 if (err) { 553 ssb_notice("Could not enable SPROM write access\n"); 554 return -EBUSY; 555 } 556 ssb_notice("[ 0%%"); 557 msleep(500); 558 for (i = 0; i < size; i++) { 559 if (i == size / 4) 560 ssb_cont("25%%"); 561 else if (i == size / 2) 562 ssb_cont("50%%"); 563 else if (i == (size * 3) / 4) 564 ssb_cont("75%%"); 565 else if (i % 2) 566 ssb_cont("."); 567 err = ssb_pcmcia_sprom_write(bus, i, sprom[i]); 568 if (err) { 569 ssb_notice("Failed to write to SPROM\n"); 570 failed = 1; 571 break; 572 } 573 } 574 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS); 575 if (err) { 576 ssb_notice("Could not disable SPROM write access\n"); 577 failed = 1; 578 } 579 msleep(500); 580 if (!failed) { 581 ssb_cont("100%% ]\n"); 582 ssb_notice("SPROM written\n"); 583 } 584 585 return failed ? -EBUSY : 0; 586 } 587 588 static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size) 589 { 590 //TODO 591 return 0; 592 } 593 594 #define GOTO_ERROR_ON(condition, description) do { \ 595 if (unlikely(condition)) { \ 596 error_description = description; \ 597 goto error; \ 598 } \ 599 } while (0) 600 601 static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev, 602 tuple_t *tuple, 603 void *priv) 604 { 605 struct ssb_sprom *sprom = priv; 606 607 if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID) 608 return -EINVAL; 609 if (tuple->TupleDataLen != ETH_ALEN + 2) 610 return -EINVAL; 611 if (tuple->TupleData[1] != ETH_ALEN) 612 return -EINVAL; 613 memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN); 614 return 0; 615 }; 616 617 static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev, 618 tuple_t *tuple, 619 void *priv) 620 { 621 struct ssb_init_invariants *iv = priv; 622 struct ssb_sprom *sprom = &iv->sprom; 623 struct ssb_boardinfo *bi = &iv->boardinfo; 624 const char *error_description; 625 626 GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1"); 627 switch (tuple->TupleData[0]) { 628 case SSB_PCMCIA_CIS_ID: 629 GOTO_ERROR_ON((tuple->TupleDataLen != 5) && 630 (tuple->TupleDataLen != 7), 631 "id tpl size"); 632 bi->vendor = tuple->TupleData[1] | 633 ((u16)tuple->TupleData[2] << 8); 634 break; 635 case SSB_PCMCIA_CIS_BOARDREV: 636 GOTO_ERROR_ON(tuple->TupleDataLen != 2, 637 "boardrev tpl size"); 638 sprom->board_rev = tuple->TupleData[1]; 639 break; 640 case SSB_PCMCIA_CIS_PA: 641 GOTO_ERROR_ON((tuple->TupleDataLen != 9) && 642 (tuple->TupleDataLen != 10), 643 "pa tpl size"); 644 sprom->pa0b0 = tuple->TupleData[1] | 645 ((u16)tuple->TupleData[2] << 8); 646 sprom->pa0b1 = tuple->TupleData[3] | 647 ((u16)tuple->TupleData[4] << 8); 648 sprom->pa0b2 = tuple->TupleData[5] | 649 ((u16)tuple->TupleData[6] << 8); 650 sprom->itssi_a = tuple->TupleData[7]; 651 sprom->itssi_bg = tuple->TupleData[7]; 652 sprom->maxpwr_a = tuple->TupleData[8]; 653 sprom->maxpwr_bg = tuple->TupleData[8]; 654 break; 655 case SSB_PCMCIA_CIS_OEMNAME: 656 /* We ignore this. */ 657 break; 658 case SSB_PCMCIA_CIS_CCODE: 659 GOTO_ERROR_ON(tuple->TupleDataLen != 2, 660 "ccode tpl size"); 661 sprom->country_code = tuple->TupleData[1]; 662 break; 663 case SSB_PCMCIA_CIS_ANTENNA: 664 GOTO_ERROR_ON(tuple->TupleDataLen != 2, 665 "ant tpl size"); 666 sprom->ant_available_a = tuple->TupleData[1]; 667 sprom->ant_available_bg = tuple->TupleData[1]; 668 break; 669 case SSB_PCMCIA_CIS_ANTGAIN: 670 GOTO_ERROR_ON(tuple->TupleDataLen != 2, 671 "antg tpl size"); 672 sprom->antenna_gain.a0 = tuple->TupleData[1]; 673 sprom->antenna_gain.a1 = tuple->TupleData[1]; 674 sprom->antenna_gain.a2 = tuple->TupleData[1]; 675 sprom->antenna_gain.a3 = tuple->TupleData[1]; 676 break; 677 case SSB_PCMCIA_CIS_BFLAGS: 678 GOTO_ERROR_ON((tuple->TupleDataLen != 3) && 679 (tuple->TupleDataLen != 5), 680 "bfl tpl size"); 681 sprom->boardflags_lo = tuple->TupleData[1] | 682 ((u16)tuple->TupleData[2] << 8); 683 break; 684 case SSB_PCMCIA_CIS_LEDS: 685 GOTO_ERROR_ON(tuple->TupleDataLen != 5, 686 "leds tpl size"); 687 sprom->gpio0 = tuple->TupleData[1]; 688 sprom->gpio1 = tuple->TupleData[2]; 689 sprom->gpio2 = tuple->TupleData[3]; 690 sprom->gpio3 = tuple->TupleData[4]; 691 break; 692 } 693 return -ENOSPC; /* continue with next entry */ 694 695 error: 696 ssb_err( 697 "PCMCIA: Failed to fetch device invariants: %s\n", 698 error_description); 699 return -ENODEV; 700 } 701 702 703 int ssb_pcmcia_get_invariants(struct ssb_bus *bus, 704 struct ssb_init_invariants *iv) 705 { 706 struct ssb_sprom *sprom = &iv->sprom; 707 int res; 708 709 memset(sprom, 0xFF, sizeof(*sprom)); 710 sprom->revision = 1; 711 sprom->boardflags_lo = 0; 712 sprom->boardflags_hi = 0; 713 714 /* First fetch the MAC address. */ 715 res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE, 716 ssb_pcmcia_get_mac, sprom); 717 if (res != 0) { 718 ssb_err( 719 "PCMCIA: Failed to fetch MAC address\n"); 720 return -ENODEV; 721 } 722 723 /* Fetch the vendor specific tuples. */ 724 res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS, 725 ssb_pcmcia_do_get_invariants, iv); 726 if ((res == 0) || (res == -ENOSPC)) 727 return 0; 728 729 ssb_err( 730 "PCMCIA: Failed to fetch device invariants\n"); 731 return -ENODEV; 732 } 733 734 static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev, 735 struct device_attribute *attr, 736 char *buf) 737 { 738 struct pcmcia_device *pdev = 739 container_of(pcmciadev, struct pcmcia_device, dev); 740 struct ssb_bus *bus; 741 742 bus = ssb_pcmcia_dev_to_bus(pdev); 743 if (!bus) 744 return -ENODEV; 745 746 return ssb_attr_sprom_show(bus, buf, 747 ssb_pcmcia_sprom_read_all); 748 } 749 750 static ssize_t ssb_pcmcia_attr_sprom_store(struct device *pcmciadev, 751 struct device_attribute *attr, 752 const char *buf, size_t count) 753 { 754 struct pcmcia_device *pdev = 755 container_of(pcmciadev, struct pcmcia_device, dev); 756 struct ssb_bus *bus; 757 758 bus = ssb_pcmcia_dev_to_bus(pdev); 759 if (!bus) 760 return -ENODEV; 761 762 return ssb_attr_sprom_store(bus, buf, count, 763 ssb_pcmcia_sprom_check_crc, 764 ssb_pcmcia_sprom_write_all); 765 } 766 767 static DEVICE_ATTR(ssb_sprom, 0600, 768 ssb_pcmcia_attr_sprom_show, 769 ssb_pcmcia_attr_sprom_store); 770 771 static int ssb_pcmcia_cor_setup(struct ssb_bus *bus, u8 cor) 772 { 773 u8 val; 774 int err; 775 776 err = ssb_pcmcia_cfg_read(bus, cor, &val); 777 if (err) 778 return err; 779 val &= ~COR_SOFT_RESET; 780 val |= COR_FUNC_ENA | COR_IREQ_ENA | COR_LEVEL_REQ; 781 err = ssb_pcmcia_cfg_write(bus, cor, val); 782 if (err) 783 return err; 784 msleep(40); 785 786 return 0; 787 } 788 789 /* Initialize the PCMCIA hardware. This is called on Init and Resume. */ 790 int ssb_pcmcia_hardware_setup(struct ssb_bus *bus) 791 { 792 int err; 793 794 if (bus->bustype != SSB_BUSTYPE_PCMCIA) 795 return 0; 796 797 /* Switch segment to a known state and sync 798 * bus->mapped_pcmcia_seg with hardware state. */ 799 ssb_pcmcia_switch_segment(bus, 0); 800 /* Init the COR register. */ 801 err = ssb_pcmcia_cor_setup(bus, CISREG_COR); 802 if (err) 803 return err; 804 /* Some cards also need this register to get poked. */ 805 err = ssb_pcmcia_cor_setup(bus, CISREG_COR + 0x80); 806 if (err) 807 return err; 808 809 return 0; 810 } 811 812 void ssb_pcmcia_exit(struct ssb_bus *bus) 813 { 814 if (bus->bustype != SSB_BUSTYPE_PCMCIA) 815 return; 816 817 device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom); 818 } 819 820 int ssb_pcmcia_init(struct ssb_bus *bus) 821 { 822 int err; 823 824 if (bus->bustype != SSB_BUSTYPE_PCMCIA) 825 return 0; 826 827 err = ssb_pcmcia_hardware_setup(bus); 828 if (err) 829 goto error; 830 831 bus->sprom_size = SSB_PCMCIA_SPROM_SIZE; 832 mutex_init(&bus->sprom_mutex); 833 err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom); 834 if (err) 835 goto error; 836 837 return 0; 838 error: 839 ssb_err("Failed to initialize PCMCIA host device\n"); 840 return err; 841 } 842