1 /* 2 * arch/arm/mach-orion5x/dns323-setup.c 3 * 4 * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> 5 * 6 * Support for HW Rev C1: 7 * 8 * Copyright (C) 2010 Benjamin Herrenschmidt <benh@kernel.crashing.org> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License as 12 * published by the Free Software Foundation; either version 2 of the 13 * License, or (at your option) any later version. 14 * 15 */ 16 #include <linux/gpio.h> 17 #include <linux/gpio/machine.h> 18 #include <linux/kernel.h> 19 #include <linux/init.h> 20 #include <linux/delay.h> 21 #include <linux/platform_device.h> 22 #include <linux/pci.h> 23 #include <linux/irq.h> 24 #include <linux/mtd/physmap.h> 25 #include <linux/mv643xx_eth.h> 26 #include <linux/leds.h> 27 #include <linux/gpio_keys.h> 28 #include <linux/input.h> 29 #include <linux/i2c.h> 30 #include <linux/ata_platform.h> 31 #include <linux/phy.h> 32 #include <linux/marvell_phy.h> 33 #include <asm/mach-types.h> 34 #include <asm/mach/arch.h> 35 #include <asm/mach/pci.h> 36 #include <asm/system_info.h> 37 #include <plat/orion-gpio.h> 38 #include "orion5x.h" 39 #include "common.h" 40 #include "mpp.h" 41 42 /* Rev A1 and B1 */ 43 #define DNS323_GPIO_LED_RIGHT_AMBER 1 44 #define DNS323_GPIO_LED_LEFT_AMBER 2 45 #define DNS323_GPIO_SYSTEM_UP 3 46 #define DNS323_GPIO_LED_POWER1 4 47 #define DNS323_GPIO_LED_POWER2 5 48 #define DNS323_GPIO_OVERTEMP 6 49 #define DNS323_GPIO_RTC 7 50 #define DNS323_GPIO_POWER_OFF 8 51 #define DNS323_GPIO_KEY_POWER 9 52 #define DNS323_GPIO_KEY_RESET 10 53 54 /* Rev C1 */ 55 #define DNS323C_GPIO_KEY_POWER 1 56 #define DNS323C_GPIO_POWER_OFF 2 57 #define DNS323C_GPIO_LED_RIGHT_AMBER 8 58 #define DNS323C_GPIO_LED_LEFT_AMBER 9 59 #define DNS323C_GPIO_LED_POWER 17 60 #define DNS323C_GPIO_FAN_BIT1 18 61 #define DNS323C_GPIO_FAN_BIT0 19 62 63 /* Exposed to userspace, do not change */ 64 enum { 65 DNS323_REV_A1, /* 0 */ 66 DNS323_REV_B1, /* 1 */ 67 DNS323_REV_C1, /* 2 */ 68 }; 69 70 71 /**************************************************************************** 72 * PCI setup 73 */ 74 75 static int __init dns323_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 76 { 77 int irq; 78 79 /* 80 * Check for devices with hard-wired IRQs. 81 */ 82 irq = orion5x_pci_map_irq(dev, slot, pin); 83 if (irq != -1) 84 return irq; 85 86 return -1; 87 } 88 89 static struct hw_pci dns323_pci __initdata = { 90 .nr_controllers = 2, 91 .setup = orion5x_pci_sys_setup, 92 .scan = orion5x_pci_sys_scan_bus, 93 .map_irq = dns323_pci_map_irq, 94 }; 95 96 static int __init dns323_pci_init(void) 97 { 98 /* Rev B1 and C1 doesn't really use its PCI bus, and initialising PCI 99 * gets in the way of initialising the SATA controller. 100 */ 101 if (machine_is_dns323() && system_rev == DNS323_REV_A1) 102 pci_common_init(&dns323_pci); 103 104 return 0; 105 } 106 107 subsys_initcall(dns323_pci_init); 108 109 /**************************************************************************** 110 * 8MiB NOR flash (Spansion S29GL064M90TFIR4) 111 * 112 * Layout as used by D-Link: 113 * 0x00000000-0x00010000 : "MTD1" 114 * 0x00010000-0x00020000 : "MTD2" 115 * 0x00020000-0x001a0000 : "Linux Kernel" 116 * 0x001a0000-0x007d0000 : "File System" 117 * 0x007d0000-0x00800000 : "u-boot" 118 */ 119 120 #define DNS323_NOR_BOOT_BASE 0xf4000000 121 #define DNS323_NOR_BOOT_SIZE SZ_8M 122 123 static struct mtd_partition dns323_partitions[] = { 124 { 125 .name = "MTD1", 126 .size = 0x00010000, 127 .offset = 0, 128 }, { 129 .name = "MTD2", 130 .size = 0x00010000, 131 .offset = 0x00010000, 132 }, { 133 .name = "Linux Kernel", 134 .size = 0x00180000, 135 .offset = 0x00020000, 136 }, { 137 .name = "File System", 138 .size = 0x00630000, 139 .offset = 0x001A0000, 140 }, { 141 .name = "u-boot", 142 .size = 0x00030000, 143 .offset = 0x007d0000, 144 }, 145 }; 146 147 static struct physmap_flash_data dns323_nor_flash_data = { 148 .width = 1, 149 .parts = dns323_partitions, 150 .nr_parts = ARRAY_SIZE(dns323_partitions) 151 }; 152 153 static struct resource dns323_nor_flash_resource = { 154 .flags = IORESOURCE_MEM, 155 .start = DNS323_NOR_BOOT_BASE, 156 .end = DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1, 157 }; 158 159 static struct platform_device dns323_nor_flash = { 160 .name = "physmap-flash", 161 .id = 0, 162 .dev = { 163 .platform_data = &dns323_nor_flash_data, 164 }, 165 .resource = &dns323_nor_flash_resource, 166 .num_resources = 1, 167 }; 168 169 /**************************************************************************** 170 * Ethernet 171 */ 172 173 static struct mv643xx_eth_platform_data dns323_eth_data = { 174 .phy_addr = MV643XX_ETH_PHY_ADDR(8), 175 }; 176 177 /* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these 178 * functions be kept somewhere? 179 */ 180 static int __init dns323_parse_hex_nibble(char n) 181 { 182 if (n >= '0' && n <= '9') 183 return n - '0'; 184 185 if (n >= 'A' && n <= 'F') 186 return n - 'A' + 10; 187 188 if (n >= 'a' && n <= 'f') 189 return n - 'a' + 10; 190 191 return -1; 192 } 193 194 static int __init dns323_parse_hex_byte(const char *b) 195 { 196 int hi; 197 int lo; 198 199 hi = dns323_parse_hex_nibble(b[0]); 200 lo = dns323_parse_hex_nibble(b[1]); 201 202 if (hi < 0 || lo < 0) 203 return -1; 204 205 return (hi << 4) | lo; 206 } 207 208 static int __init dns323_read_mac_addr(void) 209 { 210 u_int8_t addr[6]; 211 int i; 212 char *mac_page; 213 214 /* MAC address is stored as a regular ol' string in /dev/mtdblock4 215 * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80). 216 */ 217 mac_page = ioremap(DNS323_NOR_BOOT_BASE + 0x7d0000 + 196480, 1024); 218 if (!mac_page) 219 return -ENOMEM; 220 221 /* Sanity check the string we're looking at */ 222 for (i = 0; i < 5; i++) { 223 if (*(mac_page + (i * 3) + 2) != ':') { 224 goto error_fail; 225 } 226 } 227 228 for (i = 0; i < 6; i++) { 229 int byte; 230 231 byte = dns323_parse_hex_byte(mac_page + (i * 3)); 232 if (byte < 0) { 233 goto error_fail; 234 } 235 236 addr[i] = byte; 237 } 238 239 iounmap(mac_page); 240 printk("DNS-323: Found ethernet MAC address: %pM\n", addr); 241 242 memcpy(dns323_eth_data.mac_addr, addr, 6); 243 244 return 0; 245 246 error_fail: 247 iounmap(mac_page); 248 return -EINVAL; 249 } 250 251 /**************************************************************************** 252 * GPIO LEDs (simple - doesn't use hardware blinking support) 253 */ 254 255 static struct gpio_led dns323ab_leds[] = { 256 { 257 .name = "power:blue", 258 .default_trigger = "default-on", 259 }, { 260 .name = "right:amber", 261 }, { 262 .name = "left:amber", 263 }, 264 }; 265 266 static struct gpiod_lookup_table dns323a1_leds_gpio_table = { 267 .dev_id = "leds-gpio", 268 .table = { 269 GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_POWER2, NULL, 270 0, GPIO_ACTIVE_LOW), 271 GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_RIGHT_AMBER, NULL, 272 1, GPIO_ACTIVE_LOW), 273 GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_LEFT_AMBER, NULL, 274 2, GPIO_ACTIVE_LOW), 275 { }, 276 }, 277 }; 278 279 /* B1 is the same but power LED is active high */ 280 static struct gpiod_lookup_table dns323b1_leds_gpio_table = { 281 .dev_id = "leds-gpio", 282 .table = { 283 GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_POWER2, NULL, 284 0, GPIO_ACTIVE_HIGH), 285 GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_RIGHT_AMBER, NULL, 286 1, GPIO_ACTIVE_LOW), 287 GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_LEFT_AMBER, NULL, 288 2, GPIO_ACTIVE_LOW), 289 { }, 290 }, 291 }; 292 293 static struct gpio_led dns323c_leds[] = { 294 { 295 .name = "power:blue", 296 .default_trigger = "timer", 297 }, { 298 .name = "right:amber", 299 }, { 300 .name = "left:amber", 301 }, 302 }; 303 304 static struct gpiod_lookup_table dns323c_leds_gpio_table = { 305 .dev_id = "leds-gpio", 306 .table = { 307 GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_POWER, NULL, 308 0, GPIO_ACTIVE_LOW), 309 GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_RIGHT_AMBER, NULL, 310 1, GPIO_ACTIVE_LOW), 311 GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_LEFT_AMBER, NULL, 312 2, GPIO_ACTIVE_LOW), 313 { }, 314 }, 315 }; 316 317 static struct gpio_led_platform_data dns323ab_led_data = { 318 .num_leds = ARRAY_SIZE(dns323ab_leds), 319 .leds = dns323ab_leds, 320 .gpio_blink_set = orion_gpio_led_blink_set, 321 }; 322 323 static struct gpio_led_platform_data dns323c_led_data = { 324 .num_leds = ARRAY_SIZE(dns323c_leds), 325 .leds = dns323c_leds, 326 .gpio_blink_set = orion_gpio_led_blink_set, 327 }; 328 329 static struct platform_device dns323_gpio_leds = { 330 .name = "leds-gpio", 331 .id = -1, 332 .dev = { 333 .platform_data = &dns323ab_led_data, 334 }, 335 }; 336 337 /**************************************************************************** 338 * GPIO Attached Keys 339 */ 340 341 static struct gpio_keys_button dns323ab_buttons[] = { 342 { 343 .code = KEY_RESTART, 344 .gpio = DNS323_GPIO_KEY_RESET, 345 .desc = "Reset Button", 346 .active_low = 1, 347 }, { 348 .code = KEY_POWER, 349 .gpio = DNS323_GPIO_KEY_POWER, 350 .desc = "Power Button", 351 .active_low = 1, 352 }, 353 }; 354 355 static struct gpio_keys_platform_data dns323ab_button_data = { 356 .buttons = dns323ab_buttons, 357 .nbuttons = ARRAY_SIZE(dns323ab_buttons), 358 }; 359 360 static struct gpio_keys_button dns323c_buttons[] = { 361 { 362 .code = KEY_POWER, 363 .gpio = DNS323C_GPIO_KEY_POWER, 364 .desc = "Power Button", 365 .active_low = 1, 366 }, 367 }; 368 369 static struct gpio_keys_platform_data dns323c_button_data = { 370 .buttons = dns323c_buttons, 371 .nbuttons = ARRAY_SIZE(dns323c_buttons), 372 }; 373 374 static struct platform_device dns323_button_device = { 375 .name = "gpio-keys", 376 .id = -1, 377 .num_resources = 0, 378 .dev = { 379 .platform_data = &dns323ab_button_data, 380 }, 381 }; 382 383 /***************************************************************************** 384 * SATA 385 */ 386 static struct mv_sata_platform_data dns323_sata_data = { 387 .n_ports = 2, 388 }; 389 390 /**************************************************************************** 391 * General Setup 392 */ 393 static unsigned int dns323a_mpp_modes[] __initdata = { 394 MPP0_PCIE_RST_OUTn, 395 MPP1_GPIO, /* right amber LED (sata ch0) */ 396 MPP2_GPIO, /* left amber LED (sata ch1) */ 397 MPP3_UNUSED, 398 MPP4_GPIO, /* power button LED */ 399 MPP5_GPIO, /* power button LED */ 400 MPP6_GPIO, /* GMT G751-2f overtemp */ 401 MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */ 402 MPP8_GPIO, /* triggers power off */ 403 MPP9_GPIO, /* power button switch */ 404 MPP10_GPIO, /* reset button switch */ 405 MPP11_UNUSED, 406 MPP12_UNUSED, 407 MPP13_UNUSED, 408 MPP14_UNUSED, 409 MPP15_UNUSED, 410 MPP16_UNUSED, 411 MPP17_UNUSED, 412 MPP18_UNUSED, 413 MPP19_UNUSED, 414 0, 415 }; 416 417 static unsigned int dns323b_mpp_modes[] __initdata = { 418 MPP0_UNUSED, 419 MPP1_GPIO, /* right amber LED (sata ch0) */ 420 MPP2_GPIO, /* left amber LED (sata ch1) */ 421 MPP3_GPIO, /* system up flag */ 422 MPP4_GPIO, /* power button LED */ 423 MPP5_GPIO, /* power button LED */ 424 MPP6_GPIO, /* GMT G751-2f overtemp */ 425 MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */ 426 MPP8_GPIO, /* triggers power off */ 427 MPP9_GPIO, /* power button switch */ 428 MPP10_GPIO, /* reset button switch */ 429 MPP11_UNUSED, 430 MPP12_SATA_LED, 431 MPP13_SATA_LED, 432 MPP14_SATA_LED, 433 MPP15_SATA_LED, 434 MPP16_UNUSED, 435 MPP17_UNUSED, 436 MPP18_UNUSED, 437 MPP19_UNUSED, 438 0, 439 }; 440 441 static unsigned int dns323c_mpp_modes[] __initdata = { 442 MPP0_GPIO, /* ? input */ 443 MPP1_GPIO, /* input power switch (0 = pressed) */ 444 MPP2_GPIO, /* output power off */ 445 MPP3_UNUSED, /* ? output */ 446 MPP4_UNUSED, /* ? output */ 447 MPP5_UNUSED, /* ? output */ 448 MPP6_UNUSED, /* ? output */ 449 MPP7_UNUSED, /* ? output */ 450 MPP8_GPIO, /* i/o right amber LED */ 451 MPP9_GPIO, /* i/o left amber LED */ 452 MPP10_GPIO, /* input */ 453 MPP11_UNUSED, 454 MPP12_SATA_LED, 455 MPP13_SATA_LED, 456 MPP14_SATA_LED, 457 MPP15_SATA_LED, 458 MPP16_UNUSED, 459 MPP17_GPIO, /* power button LED */ 460 MPP18_GPIO, /* fan speed bit 0 */ 461 MPP19_GPIO, /* fan speed bit 1 */ 462 0, 463 }; 464 465 /* Rev C1 Fan speed notes: 466 * 467 * The fan is controlled by 2 GPIOs on this board. The settings 468 * of the bits is as follow: 469 * 470 * GPIO 18 GPIO 19 Fan 471 * 472 * 0 0 stopped 473 * 0 1 low speed 474 * 1 0 high speed 475 * 1 1 don't do that (*) 476 * 477 * (*) I think the two bits control two feed-in resistors into a fixed 478 * PWN circuit, setting both bits will basically go a 'bit' faster 479 * than high speed, but d-link doesn't do it and you may get out of 480 * HW spec so don't do it. 481 */ 482 483 /* 484 * On the DNS-323 A1 and B1 the following devices are attached via I2C: 485 * 486 * i2c addr | chip | description 487 * 0x3e | GMT G760Af | fan speed PWM controller 488 * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible) 489 * 0x68 | ST M41T80 | RTC w/ alarm 490 */ 491 static struct i2c_board_info __initdata dns323ab_i2c_devices[] = { 492 { 493 I2C_BOARD_INFO("g760a", 0x3e), 494 }, { 495 I2C_BOARD_INFO("lm75", 0x48), 496 }, { 497 I2C_BOARD_INFO("m41t80", 0x68), 498 }, 499 }; 500 501 /* 502 * On the DNS-323 C1 the following devices are attached via I2C: 503 * 504 * i2c addr | chip | description 505 * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible) 506 * 0x68 | ST M41T80 | RTC w/ alarm 507 */ 508 static struct i2c_board_info __initdata dns323c_i2c_devices[] = { 509 { 510 I2C_BOARD_INFO("lm75", 0x48), 511 }, { 512 I2C_BOARD_INFO("m41t80", 0x68), 513 }, 514 }; 515 516 /* DNS-323 rev. A specific power off method */ 517 static void dns323a_power_off(void) 518 { 519 pr_info("DNS-323: Triggering power-off...\n"); 520 gpio_set_value(DNS323_GPIO_POWER_OFF, 1); 521 } 522 523 /* DNS-323 rev B specific power off method */ 524 static void dns323b_power_off(void) 525 { 526 pr_info("DNS-323: Triggering power-off...\n"); 527 /* Pin has to be changed to 1 and back to 0 to do actual power off. */ 528 gpio_set_value(DNS323_GPIO_POWER_OFF, 1); 529 mdelay(100); 530 gpio_set_value(DNS323_GPIO_POWER_OFF, 0); 531 } 532 533 /* DNS-323 rev. C specific power off method */ 534 static void dns323c_power_off(void) 535 { 536 pr_info("DNS-323: Triggering power-off...\n"); 537 gpio_set_value(DNS323C_GPIO_POWER_OFF, 1); 538 } 539 540 static int dns323c_phy_fixup(struct phy_device *phy) 541 { 542 phy->dev_flags |= MARVELL_PHY_M1118_DNS323_LEDS; 543 544 return 0; 545 } 546 547 static int __init dns323_identify_rev(void) 548 { 549 u32 dev, rev, i, reg; 550 551 pr_debug("DNS-323: Identifying board ... \n"); 552 553 /* Rev A1 has a 5181 */ 554 orion5x_pcie_id(&dev, &rev); 555 if (dev == MV88F5181_DEV_ID) { 556 pr_debug("DNS-323: 5181 found, board is A1\n"); 557 return DNS323_REV_A1; 558 } 559 pr_debug("DNS-323: 5182 found, board is B1 or C1, checking PHY...\n"); 560 561 /* Rev B1 and C1 both have 5182, let's poke at the eth PHY. This is 562 * a bit gross but we want to do that without links into the eth 563 * driver so let's poke at it directly. We default to rev B1 in 564 * case the accesses fail 565 */ 566 567 #define ETH_SMI_REG (ORION5X_ETH_VIRT_BASE + 0x2000 + 0x004) 568 #define SMI_BUSY 0x10000000 569 #define SMI_READ_VALID 0x08000000 570 #define SMI_OPCODE_READ 0x04000000 571 #define SMI_OPCODE_WRITE 0x00000000 572 573 for (i = 0; i < 1000; i++) { 574 reg = readl(ETH_SMI_REG); 575 if (!(reg & SMI_BUSY)) 576 break; 577 } 578 if (i >= 1000) { 579 pr_warn("DNS-323: Timeout accessing PHY, assuming rev B1\n"); 580 return DNS323_REV_B1; 581 } 582 writel((3 << 21) /* phy ID reg */ | 583 (8 << 16) /* phy addr */ | 584 SMI_OPCODE_READ, ETH_SMI_REG); 585 for (i = 0; i < 1000; i++) { 586 reg = readl(ETH_SMI_REG); 587 if (reg & SMI_READ_VALID) 588 break; 589 } 590 if (i >= 1000) { 591 pr_warn("DNS-323: Timeout reading PHY, assuming rev B1\n"); 592 return DNS323_REV_B1; 593 } 594 pr_debug("DNS-323: Ethernet PHY ID 0x%x\n", reg & 0xffff); 595 596 /* Note: the Marvell tools mask the ID with 0x3f0 before comparison 597 * but I don't see that making a difference here, at least with 598 * any known Marvell PHY ID 599 */ 600 switch(reg & 0xfff0) { 601 case 0x0cc0: /* MV88E1111 */ 602 return DNS323_REV_B1; 603 case 0x0e10: /* MV88E1118 */ 604 return DNS323_REV_C1; 605 default: 606 pr_warn("DNS-323: Unknown PHY ID 0x%04x, assuming rev B1\n", 607 reg & 0xffff); 608 } 609 return DNS323_REV_B1; 610 } 611 612 static void __init dns323_init(void) 613 { 614 /* Setup basic Orion functions. Need to be called early. */ 615 orion5x_init(); 616 617 /* Identify revision */ 618 system_rev = dns323_identify_rev(); 619 pr_info("DNS-323: Identified HW revision %c1\n", 'A' + system_rev); 620 621 /* Just to be tricky, the 5182 has a completely different 622 * set of MPP modes to the 5181. 623 */ 624 switch(system_rev) { 625 case DNS323_REV_A1: 626 orion5x_mpp_conf(dns323a_mpp_modes); 627 writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */ 628 break; 629 case DNS323_REV_B1: 630 orion5x_mpp_conf(dns323b_mpp_modes); 631 break; 632 case DNS323_REV_C1: 633 orion5x_mpp_conf(dns323c_mpp_modes); 634 break; 635 } 636 637 /* setup flash mapping 638 * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 639 */ 640 mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET, 641 ORION_MBUS_DEVBUS_BOOT_ATTR, 642 DNS323_NOR_BOOT_BASE, 643 DNS323_NOR_BOOT_SIZE); 644 platform_device_register(&dns323_nor_flash); 645 646 /* Sort out LEDs, Buttons and i2c devices */ 647 switch(system_rev) { 648 case DNS323_REV_A1: 649 /* The 5181 power LED is active low and requires 650 * DNS323_GPIO_LED_POWER1 to also be low. 651 */ 652 gpiod_add_lookup_table(&dns323a1_leds_gpio_table); 653 gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable"); 654 gpio_direction_output(DNS323_GPIO_LED_POWER1, 0); 655 i2c_register_board_info(0, dns323ab_i2c_devices, 656 ARRAY_SIZE(dns323ab_i2c_devices)); 657 658 break; 659 case DNS323_REV_B1: 660 gpiod_add_lookup_table(&dns323b1_leds_gpio_table); 661 i2c_register_board_info(0, dns323ab_i2c_devices, 662 ARRAY_SIZE(dns323ab_i2c_devices)); 663 break; 664 case DNS323_REV_C1: 665 /* Hookup LEDs & Buttons */ 666 gpiod_add_lookup_table(&dns323c_leds_gpio_table); 667 dns323_gpio_leds.dev.platform_data = &dns323c_led_data; 668 dns323_button_device.dev.platform_data = &dns323c_button_data; 669 670 /* Hookup i2c devices and fan driver */ 671 i2c_register_board_info(0, dns323c_i2c_devices, 672 ARRAY_SIZE(dns323c_i2c_devices)); 673 platform_device_register_simple("dns323c-fan", 0, NULL, 0); 674 675 /* Register fixup for the PHY LEDs */ 676 if (!IS_BUILTIN(CONFIG_PHYLIB)) 677 break; 678 phy_register_fixup_for_uid(MARVELL_PHY_ID_88E1118, 679 MARVELL_PHY_ID_MASK, 680 dns323c_phy_fixup); 681 } 682 683 platform_device_register(&dns323_gpio_leds); 684 platform_device_register(&dns323_button_device); 685 686 /* 687 * Configure peripherals. 688 */ 689 if (dns323_read_mac_addr() < 0) 690 printk("DNS-323: Failed to read MAC address\n"); 691 orion5x_ehci0_init(); 692 orion5x_eth_init(&dns323_eth_data); 693 orion5x_i2c_init(); 694 orion5x_uart0_init(); 695 696 /* Remaining GPIOs */ 697 switch(system_rev) { 698 case DNS323_REV_A1: 699 /* Poweroff GPIO */ 700 if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || 701 gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) 702 pr_err("DNS-323: failed to setup power-off GPIO\n"); 703 pm_power_off = dns323a_power_off; 704 break; 705 case DNS323_REV_B1: 706 /* 5182 built-in SATA init */ 707 orion5x_sata_init(&dns323_sata_data); 708 709 /* The DNS323 rev B1 has flag to indicate the system is up. 710 * Without this flag set, power LED will flash and cannot be 711 * controlled via leds-gpio. 712 */ 713 if (gpio_request(DNS323_GPIO_SYSTEM_UP, "SYS_READY") == 0) 714 gpio_direction_output(DNS323_GPIO_SYSTEM_UP, 1); 715 716 /* Poweroff GPIO */ 717 if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || 718 gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) 719 pr_err("DNS-323: failed to setup power-off GPIO\n"); 720 pm_power_off = dns323b_power_off; 721 break; 722 case DNS323_REV_C1: 723 /* 5182 built-in SATA init */ 724 orion5x_sata_init(&dns323_sata_data); 725 726 /* Poweroff GPIO */ 727 if (gpio_request(DNS323C_GPIO_POWER_OFF, "POWEROFF") != 0 || 728 gpio_direction_output(DNS323C_GPIO_POWER_OFF, 0) != 0) 729 pr_err("DNS-323: failed to setup power-off GPIO\n"); 730 pm_power_off = dns323c_power_off; 731 732 /* Now, -this- should theoretically be done by the sata_mv driver 733 * once I figure out what's going on there. Maybe the behaviour 734 * of the LEDs should be somewhat passed via the platform_data. 735 * for now, just whack the register and make the LEDs happy 736 * 737 * Note: AFAIK, rev B1 needs the same treatment but I'll let 738 * somebody else test it. 739 */ 740 writel(0x5, ORION5X_SATA_VIRT_BASE + 0x2c); 741 break; 742 } 743 } 744 745 /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ 746 MACHINE_START(DNS323, "D-Link DNS-323") 747 /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */ 748 .atag_offset = 0x100, 749 .nr_irqs = ORION5X_NR_IRQS, 750 .init_machine = dns323_init, 751 .map_io = orion5x_map_io, 752 .init_early = orion5x_init_early, 753 .init_irq = orion5x_init_irq, 754 .init_time = orion5x_timer_init, 755 .fixup = tag_fixup_mem32, 756 .restart = orion5x_restart, 757 MACHINE_END 758