1*47e9cffdSSylver Bruneau /* 2*47e9cffdSSylver Bruneau * QNAP TS-409 Board Setup 3*47e9cffdSSylver Bruneau * 4*47e9cffdSSylver Bruneau * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> 5*47e9cffdSSylver Bruneau * 6*47e9cffdSSylver Bruneau * This program is free software; you can redistribute it and/or 7*47e9cffdSSylver Bruneau * modify it under the terms of the GNU General Public License 8*47e9cffdSSylver Bruneau * as published by the Free Software Foundation; either version 9*47e9cffdSSylver Bruneau * 2 of the License, or (at your option) any later version. 10*47e9cffdSSylver Bruneau */ 11*47e9cffdSSylver Bruneau 12*47e9cffdSSylver Bruneau #include <linux/kernel.h> 13*47e9cffdSSylver Bruneau #include <linux/init.h> 14*47e9cffdSSylver Bruneau #include <linux/platform_device.h> 15*47e9cffdSSylver Bruneau #include <linux/pci.h> 16*47e9cffdSSylver Bruneau #include <linux/irq.h> 17*47e9cffdSSylver Bruneau #include <linux/mtd/physmap.h> 18*47e9cffdSSylver Bruneau #include <linux/mv643xx_eth.h> 19*47e9cffdSSylver Bruneau #include <linux/gpio_keys.h> 20*47e9cffdSSylver Bruneau #include <linux/input.h> 21*47e9cffdSSylver Bruneau #include <linux/i2c.h> 22*47e9cffdSSylver Bruneau #include <linux/serial_reg.h> 23*47e9cffdSSylver Bruneau #include <asm/mach-types.h> 24*47e9cffdSSylver Bruneau #include <asm/gpio.h> 25*47e9cffdSSylver Bruneau #include <asm/mach/arch.h> 26*47e9cffdSSylver Bruneau #include <asm/mach/pci.h> 27*47e9cffdSSylver Bruneau #include <asm/arch/orion5x.h> 28*47e9cffdSSylver Bruneau #include "common.h" 29*47e9cffdSSylver Bruneau #include "mpp.h" 30*47e9cffdSSylver Bruneau 31*47e9cffdSSylver Bruneau /***************************************************************************** 32*47e9cffdSSylver Bruneau * QNAP TS-409 Info 33*47e9cffdSSylver Bruneau ****************************************************************************/ 34*47e9cffdSSylver Bruneau 35*47e9cffdSSylver Bruneau /* 36*47e9cffdSSylver Bruneau * QNAP TS-409 hardware : 37*47e9cffdSSylver Bruneau * - Marvell 88F5281-D0 38*47e9cffdSSylver Bruneau * - Marvell 88SX7042 SATA controller (PCIe) 39*47e9cffdSSylver Bruneau * - Marvell 88E1118 Gigabit Ethernet PHY 40*47e9cffdSSylver Bruneau * - RTC S35390A (@0x30) on I2C bus 41*47e9cffdSSylver Bruneau * - 8MB NOR flash 42*47e9cffdSSylver Bruneau * - 256MB of DDR-2 RAM 43*47e9cffdSSylver Bruneau */ 44*47e9cffdSSylver Bruneau 45*47e9cffdSSylver Bruneau /* 46*47e9cffdSSylver Bruneau * 8MB NOR flash Device bus boot chip select 47*47e9cffdSSylver Bruneau */ 48*47e9cffdSSylver Bruneau 49*47e9cffdSSylver Bruneau #define QNAP_TS409_NOR_BOOT_BASE 0xff800000 50*47e9cffdSSylver Bruneau #define QNAP_TS409_NOR_BOOT_SIZE SZ_8M 51*47e9cffdSSylver Bruneau 52*47e9cffdSSylver Bruneau /**************************************************************************** 53*47e9cffdSSylver Bruneau * 8MiB NOR flash. The struct mtd_partition is not in the same order as the 54*47e9cffdSSylver Bruneau * partitions on the device because we want to keep compatability with 55*47e9cffdSSylver Bruneau * existing QNAP firmware. 56*47e9cffdSSylver Bruneau * 57*47e9cffdSSylver Bruneau * Layout as used by QNAP: 58*47e9cffdSSylver Bruneau * [2] 0x00000000-0x00200000 : "Kernel" 59*47e9cffdSSylver Bruneau * [3] 0x00200000-0x00600000 : "RootFS1" 60*47e9cffdSSylver Bruneau * [4] 0x00600000-0x00700000 : "RootFS2" 61*47e9cffdSSylver Bruneau * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) 62*47e9cffdSSylver Bruneau * [5] 0x00760000-0x00780000 : "U-Boot Config" 63*47e9cffdSSylver Bruneau * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) 64*47e9cffdSSylver Bruneau ***************************************************************************/ 65*47e9cffdSSylver Bruneau static struct mtd_partition qnap_ts409_partitions[] = { 66*47e9cffdSSylver Bruneau { 67*47e9cffdSSylver Bruneau .name = "U-Boot", 68*47e9cffdSSylver Bruneau .size = 0x00080000, 69*47e9cffdSSylver Bruneau .offset = 0x00780000, 70*47e9cffdSSylver Bruneau .mask_flags = MTD_WRITEABLE, 71*47e9cffdSSylver Bruneau }, { 72*47e9cffdSSylver Bruneau .name = "Kernel", 73*47e9cffdSSylver Bruneau .size = 0x00200000, 74*47e9cffdSSylver Bruneau .offset = 0, 75*47e9cffdSSylver Bruneau }, { 76*47e9cffdSSylver Bruneau .name = "RootFS1", 77*47e9cffdSSylver Bruneau .size = 0x00400000, 78*47e9cffdSSylver Bruneau .offset = 0x00200000, 79*47e9cffdSSylver Bruneau }, { 80*47e9cffdSSylver Bruneau .name = "RootFS2", 81*47e9cffdSSylver Bruneau .size = 0x00100000, 82*47e9cffdSSylver Bruneau .offset = 0x00600000, 83*47e9cffdSSylver Bruneau }, { 84*47e9cffdSSylver Bruneau .name = "U-Boot Config", 85*47e9cffdSSylver Bruneau .size = 0x00020000, 86*47e9cffdSSylver Bruneau .offset = 0x00760000, 87*47e9cffdSSylver Bruneau }, { 88*47e9cffdSSylver Bruneau .name = "NAS Config", 89*47e9cffdSSylver Bruneau .size = 0x00060000, 90*47e9cffdSSylver Bruneau .offset = 0x00700000, 91*47e9cffdSSylver Bruneau .mask_flags = MTD_WRITEABLE, 92*47e9cffdSSylver Bruneau }, 93*47e9cffdSSylver Bruneau }; 94*47e9cffdSSylver Bruneau 95*47e9cffdSSylver Bruneau static struct physmap_flash_data qnap_ts409_nor_flash_data = { 96*47e9cffdSSylver Bruneau .width = 1, 97*47e9cffdSSylver Bruneau .parts = qnap_ts409_partitions, 98*47e9cffdSSylver Bruneau .nr_parts = ARRAY_SIZE(qnap_ts409_partitions) 99*47e9cffdSSylver Bruneau }; 100*47e9cffdSSylver Bruneau 101*47e9cffdSSylver Bruneau static struct resource qnap_ts409_nor_flash_resource = { 102*47e9cffdSSylver Bruneau .flags = IORESOURCE_MEM, 103*47e9cffdSSylver Bruneau .start = QNAP_TS409_NOR_BOOT_BASE, 104*47e9cffdSSylver Bruneau .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1, 105*47e9cffdSSylver Bruneau }; 106*47e9cffdSSylver Bruneau 107*47e9cffdSSylver Bruneau static struct platform_device qnap_ts409_nor_flash = { 108*47e9cffdSSylver Bruneau .name = "physmap-flash", 109*47e9cffdSSylver Bruneau .id = 0, 110*47e9cffdSSylver Bruneau .dev = { .platform_data = &qnap_ts409_nor_flash_data, }, 111*47e9cffdSSylver Bruneau .num_resources = 1, 112*47e9cffdSSylver Bruneau .resource = &qnap_ts409_nor_flash_resource, 113*47e9cffdSSylver Bruneau }; 114*47e9cffdSSylver Bruneau 115*47e9cffdSSylver Bruneau /***************************************************************************** 116*47e9cffdSSylver Bruneau * PCI 117*47e9cffdSSylver Bruneau ****************************************************************************/ 118*47e9cffdSSylver Bruneau 119*47e9cffdSSylver Bruneau static int __init qnap_ts409_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 120*47e9cffdSSylver Bruneau { 121*47e9cffdSSylver Bruneau int irq; 122*47e9cffdSSylver Bruneau 123*47e9cffdSSylver Bruneau /* 124*47e9cffdSSylver Bruneau * Check for devices with hard-wired IRQs. 125*47e9cffdSSylver Bruneau */ 126*47e9cffdSSylver Bruneau irq = orion5x_pci_map_irq(dev, slot, pin); 127*47e9cffdSSylver Bruneau if (irq != -1) 128*47e9cffdSSylver Bruneau return irq; 129*47e9cffdSSylver Bruneau 130*47e9cffdSSylver Bruneau /* 131*47e9cffdSSylver Bruneau * PCI isn't used on the TS-409 132*47e9cffdSSylver Bruneau */ 133*47e9cffdSSylver Bruneau return -1; 134*47e9cffdSSylver Bruneau } 135*47e9cffdSSylver Bruneau 136*47e9cffdSSylver Bruneau static struct hw_pci qnap_ts409_pci __initdata = { 137*47e9cffdSSylver Bruneau .nr_controllers = 2, 138*47e9cffdSSylver Bruneau .swizzle = pci_std_swizzle, 139*47e9cffdSSylver Bruneau .setup = orion5x_pci_sys_setup, 140*47e9cffdSSylver Bruneau .scan = orion5x_pci_sys_scan_bus, 141*47e9cffdSSylver Bruneau .map_irq = qnap_ts409_pci_map_irq, 142*47e9cffdSSylver Bruneau }; 143*47e9cffdSSylver Bruneau 144*47e9cffdSSylver Bruneau static int __init qnap_ts409_pci_init(void) 145*47e9cffdSSylver Bruneau { 146*47e9cffdSSylver Bruneau if (machine_is_ts409()) 147*47e9cffdSSylver Bruneau pci_common_init(&qnap_ts409_pci); 148*47e9cffdSSylver Bruneau 149*47e9cffdSSylver Bruneau return 0; 150*47e9cffdSSylver Bruneau } 151*47e9cffdSSylver Bruneau 152*47e9cffdSSylver Bruneau subsys_initcall(qnap_ts409_pci_init); 153*47e9cffdSSylver Bruneau 154*47e9cffdSSylver Bruneau /***************************************************************************** 155*47e9cffdSSylver Bruneau * Ethernet 156*47e9cffdSSylver Bruneau ****************************************************************************/ 157*47e9cffdSSylver Bruneau 158*47e9cffdSSylver Bruneau static struct mv643xx_eth_platform_data qnap_ts409_eth_data = { 159*47e9cffdSSylver Bruneau .phy_addr = 8, 160*47e9cffdSSylver Bruneau }; 161*47e9cffdSSylver Bruneau 162*47e9cffdSSylver Bruneau static int __init parse_hex_nibble(char n) 163*47e9cffdSSylver Bruneau { 164*47e9cffdSSylver Bruneau if (n >= '0' && n <= '9') 165*47e9cffdSSylver Bruneau return n - '0'; 166*47e9cffdSSylver Bruneau 167*47e9cffdSSylver Bruneau if (n >= 'A' && n <= 'F') 168*47e9cffdSSylver Bruneau return n - 'A' + 10; 169*47e9cffdSSylver Bruneau 170*47e9cffdSSylver Bruneau if (n >= 'a' && n <= 'f') 171*47e9cffdSSylver Bruneau return n - 'a' + 10; 172*47e9cffdSSylver Bruneau 173*47e9cffdSSylver Bruneau return -1; 174*47e9cffdSSylver Bruneau } 175*47e9cffdSSylver Bruneau 176*47e9cffdSSylver Bruneau static int __init parse_hex_byte(const char *b) 177*47e9cffdSSylver Bruneau { 178*47e9cffdSSylver Bruneau int hi; 179*47e9cffdSSylver Bruneau int lo; 180*47e9cffdSSylver Bruneau 181*47e9cffdSSylver Bruneau hi = parse_hex_nibble(b[0]); 182*47e9cffdSSylver Bruneau lo = parse_hex_nibble(b[1]); 183*47e9cffdSSylver Bruneau 184*47e9cffdSSylver Bruneau if (hi < 0 || lo < 0) 185*47e9cffdSSylver Bruneau return -1; 186*47e9cffdSSylver Bruneau 187*47e9cffdSSylver Bruneau return (hi << 4) | lo; 188*47e9cffdSSylver Bruneau } 189*47e9cffdSSylver Bruneau 190*47e9cffdSSylver Bruneau static int __init check_mac_addr(const char *addr_str) 191*47e9cffdSSylver Bruneau { 192*47e9cffdSSylver Bruneau u_int8_t addr[6]; 193*47e9cffdSSylver Bruneau int i; 194*47e9cffdSSylver Bruneau 195*47e9cffdSSylver Bruneau for (i = 0; i < 6; i++) { 196*47e9cffdSSylver Bruneau int byte; 197*47e9cffdSSylver Bruneau 198*47e9cffdSSylver Bruneau /* 199*47e9cffdSSylver Bruneau * Enforce "xx:xx:xx:xx:xx:xx\n" format. 200*47e9cffdSSylver Bruneau */ 201*47e9cffdSSylver Bruneau if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n')) 202*47e9cffdSSylver Bruneau return -1; 203*47e9cffdSSylver Bruneau 204*47e9cffdSSylver Bruneau byte = parse_hex_byte(addr_str + (i * 3)); 205*47e9cffdSSylver Bruneau if (byte < 0) 206*47e9cffdSSylver Bruneau return -1; 207*47e9cffdSSylver Bruneau addr[i] = byte; 208*47e9cffdSSylver Bruneau } 209*47e9cffdSSylver Bruneau 210*47e9cffdSSylver Bruneau printk(KERN_INFO "ts409: found ethernet mac address "); 211*47e9cffdSSylver Bruneau for (i = 0; i < 6; i++) 212*47e9cffdSSylver Bruneau printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n"); 213*47e9cffdSSylver Bruneau 214*47e9cffdSSylver Bruneau memcpy(qnap_ts409_eth_data.mac_addr, addr, 6); 215*47e9cffdSSylver Bruneau 216*47e9cffdSSylver Bruneau return 0; 217*47e9cffdSSylver Bruneau } 218*47e9cffdSSylver Bruneau 219*47e9cffdSSylver Bruneau /* 220*47e9cffdSSylver Bruneau * The 'NAS Config' flash partition has an ext2 filesystem which 221*47e9cffdSSylver Bruneau * contains a file that has the ethernet MAC address in plain text 222*47e9cffdSSylver Bruneau * (format "xx:xx:xx:xx:xx:xx\n"). 223*47e9cffdSSylver Bruneau */ 224*47e9cffdSSylver Bruneau static void __init ts409_find_mac_addr(void) 225*47e9cffdSSylver Bruneau { 226*47e9cffdSSylver Bruneau unsigned long addr; 227*47e9cffdSSylver Bruneau 228*47e9cffdSSylver Bruneau for (addr = 0x00700000; addr < 0x00760000; addr += 1024) { 229*47e9cffdSSylver Bruneau char *nor_page; 230*47e9cffdSSylver Bruneau int ret = 0; 231*47e9cffdSSylver Bruneau 232*47e9cffdSSylver Bruneau nor_page = ioremap(QNAP_TS409_NOR_BOOT_BASE + addr, 1024); 233*47e9cffdSSylver Bruneau if (nor_page != NULL) { 234*47e9cffdSSylver Bruneau ret = check_mac_addr(nor_page); 235*47e9cffdSSylver Bruneau iounmap(nor_page); 236*47e9cffdSSylver Bruneau } 237*47e9cffdSSylver Bruneau 238*47e9cffdSSylver Bruneau if (ret == 0) 239*47e9cffdSSylver Bruneau break; 240*47e9cffdSSylver Bruneau } 241*47e9cffdSSylver Bruneau } 242*47e9cffdSSylver Bruneau 243*47e9cffdSSylver Bruneau /***************************************************************************** 244*47e9cffdSSylver Bruneau * RTC S35390A on I2C bus 245*47e9cffdSSylver Bruneau ****************************************************************************/ 246*47e9cffdSSylver Bruneau 247*47e9cffdSSylver Bruneau #define TS409_RTC_GPIO 10 248*47e9cffdSSylver Bruneau 249*47e9cffdSSylver Bruneau static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = { 250*47e9cffdSSylver Bruneau I2C_BOARD_INFO("s35390a", 0x30), 251*47e9cffdSSylver Bruneau }; 252*47e9cffdSSylver Bruneau 253*47e9cffdSSylver Bruneau /**************************************************************************** 254*47e9cffdSSylver Bruneau * GPIO Attached Keys 255*47e9cffdSSylver Bruneau * Power button is attached to the PIC microcontroller 256*47e9cffdSSylver Bruneau ****************************************************************************/ 257*47e9cffdSSylver Bruneau 258*47e9cffdSSylver Bruneau #define QNAP_TS409_GPIO_KEY_MEDIA 15 259*47e9cffdSSylver Bruneau 260*47e9cffdSSylver Bruneau static struct gpio_keys_button qnap_ts409_buttons[] = { 261*47e9cffdSSylver Bruneau { 262*47e9cffdSSylver Bruneau .code = KEY_RESTART, 263*47e9cffdSSylver Bruneau .gpio = QNAP_TS409_GPIO_KEY_MEDIA, 264*47e9cffdSSylver Bruneau .desc = "USB Copy Button", 265*47e9cffdSSylver Bruneau .active_low = 1, 266*47e9cffdSSylver Bruneau }, 267*47e9cffdSSylver Bruneau }; 268*47e9cffdSSylver Bruneau 269*47e9cffdSSylver Bruneau static struct gpio_keys_platform_data qnap_ts409_button_data = { 270*47e9cffdSSylver Bruneau .buttons = qnap_ts409_buttons, 271*47e9cffdSSylver Bruneau .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), 272*47e9cffdSSylver Bruneau }; 273*47e9cffdSSylver Bruneau 274*47e9cffdSSylver Bruneau static struct platform_device qnap_ts409_button_device = { 275*47e9cffdSSylver Bruneau .name = "gpio-keys", 276*47e9cffdSSylver Bruneau .id = -1, 277*47e9cffdSSylver Bruneau .num_resources = 0, 278*47e9cffdSSylver Bruneau .dev = { 279*47e9cffdSSylver Bruneau .platform_data = &qnap_ts409_button_data, 280*47e9cffdSSylver Bruneau }, 281*47e9cffdSSylver Bruneau }; 282*47e9cffdSSylver Bruneau 283*47e9cffdSSylver Bruneau /***************************************************************************** 284*47e9cffdSSylver Bruneau * General Setup 285*47e9cffdSSylver Bruneau ****************************************************************************/ 286*47e9cffdSSylver Bruneau static struct orion5x_mpp_mode ts409_mpp_modes[] __initdata = { 287*47e9cffdSSylver Bruneau { 0, MPP_UNUSED }, 288*47e9cffdSSylver Bruneau { 1, MPP_UNUSED }, 289*47e9cffdSSylver Bruneau { 2, MPP_UNUSED }, 290*47e9cffdSSylver Bruneau { 3, MPP_UNUSED }, 291*47e9cffdSSylver Bruneau { 4, MPP_GPIO }, /* HDD 1 status */ 292*47e9cffdSSylver Bruneau { 5, MPP_GPIO }, /* HDD 2 status */ 293*47e9cffdSSylver Bruneau { 6, MPP_GPIO }, /* HDD 3 status */ 294*47e9cffdSSylver Bruneau { 7, MPP_GPIO }, /* HDD 4 status */ 295*47e9cffdSSylver Bruneau { 8, MPP_UNUSED }, 296*47e9cffdSSylver Bruneau { 9, MPP_UNUSED }, 297*47e9cffdSSylver Bruneau { 10, MPP_GPIO }, /* RTC int */ 298*47e9cffdSSylver Bruneau { 11, MPP_UNUSED }, 299*47e9cffdSSylver Bruneau { 12, MPP_UNUSED }, 300*47e9cffdSSylver Bruneau { 13, MPP_UNUSED }, 301*47e9cffdSSylver Bruneau { 14, MPP_GPIO }, /* SW_RST */ 302*47e9cffdSSylver Bruneau { 15, MPP_GPIO }, /* USB copy button */ 303*47e9cffdSSylver Bruneau { 16, MPP_UART }, /* UART1 RXD */ 304*47e9cffdSSylver Bruneau { 17, MPP_UART }, /* UART1 TXD */ 305*47e9cffdSSylver Bruneau { 18, MPP_UNUSED }, 306*47e9cffdSSylver Bruneau { 19, MPP_UNUSED }, 307*47e9cffdSSylver Bruneau { -1 }, 308*47e9cffdSSylver Bruneau }; 309*47e9cffdSSylver Bruneau 310*47e9cffdSSylver Bruneau /* 311*47e9cffdSSylver Bruneau * QNAP TS-409 specific power off method via UART1-attached PIC 312*47e9cffdSSylver Bruneau */ 313*47e9cffdSSylver Bruneau 314*47e9cffdSSylver Bruneau #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) 315*47e9cffdSSylver Bruneau 316*47e9cffdSSylver Bruneau static void qnap_ts409_power_off(void) 317*47e9cffdSSylver Bruneau { 318*47e9cffdSSylver Bruneau /* 19200 baud divisor */ 319*47e9cffdSSylver Bruneau const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200)); 320*47e9cffdSSylver Bruneau 321*47e9cffdSSylver Bruneau pr_info("%s: triggering power-off...\n", __func__); 322*47e9cffdSSylver Bruneau 323*47e9cffdSSylver Bruneau /* hijack uart1 and reset into sane state (19200,8n1) */ 324*47e9cffdSSylver Bruneau writel(0x83, UART1_REG(LCR)); 325*47e9cffdSSylver Bruneau writel(divisor & 0xff, UART1_REG(DLL)); 326*47e9cffdSSylver Bruneau writel((divisor >> 8) & 0xff, UART1_REG(DLM)); 327*47e9cffdSSylver Bruneau writel(0x03, UART1_REG(LCR)); 328*47e9cffdSSylver Bruneau writel(0x00, UART1_REG(IER)); 329*47e9cffdSSylver Bruneau writel(0x00, UART1_REG(FCR)); 330*47e9cffdSSylver Bruneau writel(0x00, UART1_REG(MCR)); 331*47e9cffdSSylver Bruneau 332*47e9cffdSSylver Bruneau /* send the power-off command 'A' to PIC */ 333*47e9cffdSSylver Bruneau writel('A', UART1_REG(TX)); 334*47e9cffdSSylver Bruneau } 335*47e9cffdSSylver Bruneau 336*47e9cffdSSylver Bruneau static void __init qnap_ts409_init(void) 337*47e9cffdSSylver Bruneau { 338*47e9cffdSSylver Bruneau /* 339*47e9cffdSSylver Bruneau * Setup basic Orion functions. Need to be called early. 340*47e9cffdSSylver Bruneau */ 341*47e9cffdSSylver Bruneau orion5x_init(); 342*47e9cffdSSylver Bruneau 343*47e9cffdSSylver Bruneau orion5x_mpp_conf(ts409_mpp_modes); 344*47e9cffdSSylver Bruneau 345*47e9cffdSSylver Bruneau /* 346*47e9cffdSSylver Bruneau * Configure peripherals. 347*47e9cffdSSylver Bruneau */ 348*47e9cffdSSylver Bruneau orion5x_ehci0_init(); 349*47e9cffdSSylver Bruneau ts409_find_mac_addr(); 350*47e9cffdSSylver Bruneau orion5x_eth_init(&qnap_ts409_eth_data); 351*47e9cffdSSylver Bruneau orion5x_i2c_init(); 352*47e9cffdSSylver Bruneau orion5x_uart0_init(); 353*47e9cffdSSylver Bruneau 354*47e9cffdSSylver Bruneau orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE, 355*47e9cffdSSylver Bruneau QNAP_TS409_NOR_BOOT_SIZE); 356*47e9cffdSSylver Bruneau platform_device_register(&qnap_ts409_nor_flash); 357*47e9cffdSSylver Bruneau 358*47e9cffdSSylver Bruneau platform_device_register(&qnap_ts409_button_device); 359*47e9cffdSSylver Bruneau 360*47e9cffdSSylver Bruneau /* Get RTC IRQ and register the chip */ 361*47e9cffdSSylver Bruneau if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) { 362*47e9cffdSSylver Bruneau if (gpio_direction_input(TS409_RTC_GPIO) == 0) 363*47e9cffdSSylver Bruneau qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO); 364*47e9cffdSSylver Bruneau else 365*47e9cffdSSylver Bruneau gpio_free(TS409_RTC_GPIO); 366*47e9cffdSSylver Bruneau } 367*47e9cffdSSylver Bruneau if (qnap_ts409_i2c_rtc.irq == 0) 368*47e9cffdSSylver Bruneau pr_warning("qnap_ts409_init: failed to get RTC IRQ\n"); 369*47e9cffdSSylver Bruneau i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1); 370*47e9cffdSSylver Bruneau 371*47e9cffdSSylver Bruneau /* register ts409 specific power-off method */ 372*47e9cffdSSylver Bruneau pm_power_off = qnap_ts409_power_off; 373*47e9cffdSSylver Bruneau } 374*47e9cffdSSylver Bruneau 375*47e9cffdSSylver Bruneau MACHINE_START(TS409, "QNAP TS-409") 376*47e9cffdSSylver Bruneau /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */ 377*47e9cffdSSylver Bruneau .phys_io = ORION5X_REGS_PHYS_BASE, 378*47e9cffdSSylver Bruneau .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, 379*47e9cffdSSylver Bruneau .boot_params = 0x00000100, 380*47e9cffdSSylver Bruneau .init_machine = qnap_ts409_init, 381*47e9cffdSSylver Bruneau .map_io = orion5x_map_io, 382*47e9cffdSSylver Bruneau .init_irq = orion5x_init_irq, 383*47e9cffdSSylver Bruneau .timer = &orion5x_timer, 384*47e9cffdSSylver Bruneau .fixup = tag_fixup_mem32, 385*47e9cffdSSylver Bruneau MACHINE_END 386