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