147e9cffdSSylver Bruneau /* 247e9cffdSSylver Bruneau * QNAP TS-409 Board Setup 347e9cffdSSylver Bruneau * 447e9cffdSSylver Bruneau * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> 547e9cffdSSylver Bruneau * 64a4e30afSMartin Michlmayr * Copyright (C) 2008 Sylver Bruneau <sylver.bruneau@gmail.com> 74a4e30afSMartin Michlmayr * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com> 84a4e30afSMartin Michlmayr * 947e9cffdSSylver Bruneau * This program is free software; you can redistribute it and/or 1047e9cffdSSylver Bruneau * modify it under the terms of the GNU General Public License 1147e9cffdSSylver Bruneau * as published by the Free Software Foundation; either version 1247e9cffdSSylver Bruneau * 2 of the License, or (at your option) any later version. 1347e9cffdSSylver Bruneau */ 142f8163baSRussell King #include <linux/gpio.h> 1547e9cffdSSylver Bruneau #include <linux/kernel.h> 1647e9cffdSSylver Bruneau #include <linux/init.h> 1747e9cffdSSylver Bruneau #include <linux/platform_device.h> 1847e9cffdSSylver Bruneau #include <linux/pci.h> 1947e9cffdSSylver Bruneau #include <linux/irq.h> 2047e9cffdSSylver Bruneau #include <linux/mtd/physmap.h> 2147e9cffdSSylver Bruneau #include <linux/mv643xx_eth.h> 224a4e30afSMartin Michlmayr #include <linux/leds.h> 2347e9cffdSSylver Bruneau #include <linux/gpio_keys.h> 2447e9cffdSSylver Bruneau #include <linux/input.h> 2547e9cffdSSylver Bruneau #include <linux/i2c.h> 2647e9cffdSSylver Bruneau #include <linux/serial_reg.h> 2747e9cffdSSylver Bruneau #include <asm/mach-types.h> 2847e9cffdSSylver Bruneau #include <asm/mach/arch.h> 2947e9cffdSSylver Bruneau #include <asm/mach/pci.h> 30a09e64fbSRussell King #include <mach/orion5x.h> 3147e9cffdSSylver Bruneau #include "common.h" 3247e9cffdSSylver Bruneau #include "mpp.h" 33530c854aSSylver Bruneau #include "tsx09-common.h" 3447e9cffdSSylver Bruneau 3547e9cffdSSylver Bruneau /***************************************************************************** 3647e9cffdSSylver Bruneau * QNAP TS-409 Info 3747e9cffdSSylver Bruneau ****************************************************************************/ 3847e9cffdSSylver Bruneau 3947e9cffdSSylver Bruneau /* 4047e9cffdSSylver Bruneau * QNAP TS-409 hardware : 4147e9cffdSSylver Bruneau * - Marvell 88F5281-D0 4247e9cffdSSylver Bruneau * - Marvell 88SX7042 SATA controller (PCIe) 4347e9cffdSSylver Bruneau * - Marvell 88E1118 Gigabit Ethernet PHY 4447e9cffdSSylver Bruneau * - RTC S35390A (@0x30) on I2C bus 4547e9cffdSSylver Bruneau * - 8MB NOR flash 4647e9cffdSSylver Bruneau * - 256MB of DDR-2 RAM 4747e9cffdSSylver Bruneau */ 4847e9cffdSSylver Bruneau 4947e9cffdSSylver Bruneau /* 5047e9cffdSSylver Bruneau * 8MB NOR flash Device bus boot chip select 5147e9cffdSSylver Bruneau */ 5247e9cffdSSylver Bruneau 5347e9cffdSSylver Bruneau #define QNAP_TS409_NOR_BOOT_BASE 0xff800000 5447e9cffdSSylver Bruneau #define QNAP_TS409_NOR_BOOT_SIZE SZ_8M 5547e9cffdSSylver Bruneau 5647e9cffdSSylver Bruneau /**************************************************************************** 5747e9cffdSSylver Bruneau * 8MiB NOR flash. The struct mtd_partition is not in the same order as the 5825985edcSLucas De Marchi * partitions on the device because we want to keep compatibility with 5947e9cffdSSylver Bruneau * existing QNAP firmware. 6047e9cffdSSylver Bruneau * 6147e9cffdSSylver Bruneau * Layout as used by QNAP: 6247e9cffdSSylver Bruneau * [2] 0x00000000-0x00200000 : "Kernel" 6347e9cffdSSylver Bruneau * [3] 0x00200000-0x00600000 : "RootFS1" 6447e9cffdSSylver Bruneau * [4] 0x00600000-0x00700000 : "RootFS2" 6547e9cffdSSylver Bruneau * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) 6647e9cffdSSylver Bruneau * [5] 0x00760000-0x00780000 : "U-Boot Config" 6747e9cffdSSylver Bruneau * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) 6847e9cffdSSylver Bruneau ***************************************************************************/ 6947e9cffdSSylver Bruneau static struct mtd_partition qnap_ts409_partitions[] = { 7047e9cffdSSylver Bruneau { 7147e9cffdSSylver Bruneau .name = "U-Boot", 7247e9cffdSSylver Bruneau .size = 0x00080000, 7347e9cffdSSylver Bruneau .offset = 0x00780000, 7447e9cffdSSylver Bruneau .mask_flags = MTD_WRITEABLE, 7547e9cffdSSylver Bruneau }, { 7647e9cffdSSylver Bruneau .name = "Kernel", 7747e9cffdSSylver Bruneau .size = 0x00200000, 7847e9cffdSSylver Bruneau .offset = 0, 7947e9cffdSSylver Bruneau }, { 8047e9cffdSSylver Bruneau .name = "RootFS1", 8147e9cffdSSylver Bruneau .size = 0x00400000, 8247e9cffdSSylver Bruneau .offset = 0x00200000, 8347e9cffdSSylver Bruneau }, { 8447e9cffdSSylver Bruneau .name = "RootFS2", 8547e9cffdSSylver Bruneau .size = 0x00100000, 8647e9cffdSSylver Bruneau .offset = 0x00600000, 8747e9cffdSSylver Bruneau }, { 8847e9cffdSSylver Bruneau .name = "U-Boot Config", 8947e9cffdSSylver Bruneau .size = 0x00020000, 9047e9cffdSSylver Bruneau .offset = 0x00760000, 9147e9cffdSSylver Bruneau }, { 9247e9cffdSSylver Bruneau .name = "NAS Config", 9347e9cffdSSylver Bruneau .size = 0x00060000, 9447e9cffdSSylver Bruneau .offset = 0x00700000, 9547e9cffdSSylver Bruneau .mask_flags = MTD_WRITEABLE, 9647e9cffdSSylver Bruneau }, 9747e9cffdSSylver Bruneau }; 9847e9cffdSSylver Bruneau 9947e9cffdSSylver Bruneau static struct physmap_flash_data qnap_ts409_nor_flash_data = { 10047e9cffdSSylver Bruneau .width = 1, 10147e9cffdSSylver Bruneau .parts = qnap_ts409_partitions, 10247e9cffdSSylver Bruneau .nr_parts = ARRAY_SIZE(qnap_ts409_partitions) 10347e9cffdSSylver Bruneau }; 10447e9cffdSSylver Bruneau 10547e9cffdSSylver Bruneau static struct resource qnap_ts409_nor_flash_resource = { 10647e9cffdSSylver Bruneau .flags = IORESOURCE_MEM, 10747e9cffdSSylver Bruneau .start = QNAP_TS409_NOR_BOOT_BASE, 10847e9cffdSSylver Bruneau .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1, 10947e9cffdSSylver Bruneau }; 11047e9cffdSSylver Bruneau 11147e9cffdSSylver Bruneau static struct platform_device qnap_ts409_nor_flash = { 11247e9cffdSSylver Bruneau .name = "physmap-flash", 11347e9cffdSSylver Bruneau .id = 0, 11447e9cffdSSylver Bruneau .dev = { .platform_data = &qnap_ts409_nor_flash_data, }, 11547e9cffdSSylver Bruneau .num_resources = 1, 11647e9cffdSSylver Bruneau .resource = &qnap_ts409_nor_flash_resource, 11747e9cffdSSylver Bruneau }; 11847e9cffdSSylver Bruneau 11947e9cffdSSylver Bruneau /***************************************************************************** 12047e9cffdSSylver Bruneau * PCI 12147e9cffdSSylver Bruneau ****************************************************************************/ 12247e9cffdSSylver Bruneau 123d5341942SRalf Baechle static int __init qnap_ts409_pci_map_irq(const struct pci_dev *dev, u8 slot, 124d5341942SRalf Baechle u8 pin) 12547e9cffdSSylver Bruneau { 12647e9cffdSSylver Bruneau int irq; 12747e9cffdSSylver Bruneau 12847e9cffdSSylver Bruneau /* 12947e9cffdSSylver Bruneau * Check for devices with hard-wired IRQs. 13047e9cffdSSylver Bruneau */ 13147e9cffdSSylver Bruneau irq = orion5x_pci_map_irq(dev, slot, pin); 13247e9cffdSSylver Bruneau if (irq != -1) 13347e9cffdSSylver Bruneau return irq; 13447e9cffdSSylver Bruneau 13547e9cffdSSylver Bruneau /* 13647e9cffdSSylver Bruneau * PCI isn't used on the TS-409 13747e9cffdSSylver Bruneau */ 13847e9cffdSSylver Bruneau return -1; 13947e9cffdSSylver Bruneau } 14047e9cffdSSylver Bruneau 14147e9cffdSSylver Bruneau static struct hw_pci qnap_ts409_pci __initdata = { 14247e9cffdSSylver Bruneau .nr_controllers = 2, 14347e9cffdSSylver Bruneau .swizzle = pci_std_swizzle, 14447e9cffdSSylver Bruneau .setup = orion5x_pci_sys_setup, 14547e9cffdSSylver Bruneau .scan = orion5x_pci_sys_scan_bus, 14647e9cffdSSylver Bruneau .map_irq = qnap_ts409_pci_map_irq, 14747e9cffdSSylver Bruneau }; 14847e9cffdSSylver Bruneau 14947e9cffdSSylver Bruneau static int __init qnap_ts409_pci_init(void) 15047e9cffdSSylver Bruneau { 15147e9cffdSSylver Bruneau if (machine_is_ts409()) 15247e9cffdSSylver Bruneau pci_common_init(&qnap_ts409_pci); 15347e9cffdSSylver Bruneau 15447e9cffdSSylver Bruneau return 0; 15547e9cffdSSylver Bruneau } 15647e9cffdSSylver Bruneau 15747e9cffdSSylver Bruneau subsys_initcall(qnap_ts409_pci_init); 15847e9cffdSSylver Bruneau 15947e9cffdSSylver Bruneau /***************************************************************************** 16047e9cffdSSylver Bruneau * RTC S35390A on I2C bus 16147e9cffdSSylver Bruneau ****************************************************************************/ 16247e9cffdSSylver Bruneau 16347e9cffdSSylver Bruneau #define TS409_RTC_GPIO 10 16447e9cffdSSylver Bruneau 16547e9cffdSSylver Bruneau static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = { 16647e9cffdSSylver Bruneau I2C_BOARD_INFO("s35390a", 0x30), 16747e9cffdSSylver Bruneau }; 16847e9cffdSSylver Bruneau 1694a4e30afSMartin Michlmayr /***************************************************************************** 1704a4e30afSMartin Michlmayr * LEDs attached to GPIO 1714a4e30afSMartin Michlmayr ****************************************************************************/ 1724a4e30afSMartin Michlmayr 1734a4e30afSMartin Michlmayr static struct gpio_led ts409_led_pins[] = { 1744a4e30afSMartin Michlmayr { 1754a4e30afSMartin Michlmayr .name = "ts409:red:sata1", 1764a4e30afSMartin Michlmayr .gpio = 4, 1774a4e30afSMartin Michlmayr .active_low = 1, 1784a4e30afSMartin Michlmayr }, { 1794a4e30afSMartin Michlmayr .name = "ts409:red:sata2", 1804a4e30afSMartin Michlmayr .gpio = 5, 1814a4e30afSMartin Michlmayr .active_low = 1, 1824a4e30afSMartin Michlmayr }, { 1834a4e30afSMartin Michlmayr .name = "ts409:red:sata3", 1844a4e30afSMartin Michlmayr .gpio = 6, 1854a4e30afSMartin Michlmayr .active_low = 1, 1864a4e30afSMartin Michlmayr }, { 1874a4e30afSMartin Michlmayr .name = "ts409:red:sata4", 1884a4e30afSMartin Michlmayr .gpio = 7, 1894a4e30afSMartin Michlmayr .active_low = 1, 1904a4e30afSMartin Michlmayr }, 1914a4e30afSMartin Michlmayr }; 1924a4e30afSMartin Michlmayr 1934a4e30afSMartin Michlmayr static struct gpio_led_platform_data ts409_led_data = { 1944a4e30afSMartin Michlmayr .leds = ts409_led_pins, 1954a4e30afSMartin Michlmayr .num_leds = ARRAY_SIZE(ts409_led_pins), 1964a4e30afSMartin Michlmayr }; 1974a4e30afSMartin Michlmayr 1984a4e30afSMartin Michlmayr static struct platform_device ts409_leds = { 1994a4e30afSMartin Michlmayr .name = "leds-gpio", 2004a4e30afSMartin Michlmayr .id = -1, 2014a4e30afSMartin Michlmayr .dev = { 2024a4e30afSMartin Michlmayr .platform_data = &ts409_led_data, 2034a4e30afSMartin Michlmayr }, 2044a4e30afSMartin Michlmayr }; 2054a4e30afSMartin Michlmayr 20647e9cffdSSylver Bruneau /**************************************************************************** 20747e9cffdSSylver Bruneau * GPIO Attached Keys 20847e9cffdSSylver Bruneau * Power button is attached to the PIC microcontroller 20947e9cffdSSylver Bruneau ****************************************************************************/ 21047e9cffdSSylver Bruneau 2115cebbd09SMartin Michlmayr #define QNAP_TS409_GPIO_KEY_RESET 14 21247e9cffdSSylver Bruneau #define QNAP_TS409_GPIO_KEY_MEDIA 15 21347e9cffdSSylver Bruneau 21447e9cffdSSylver Bruneau static struct gpio_keys_button qnap_ts409_buttons[] = { 21547e9cffdSSylver Bruneau { 2165cebbd09SMartin Michlmayr .code = KEY_RESTART, 2175cebbd09SMartin Michlmayr .gpio = QNAP_TS409_GPIO_KEY_RESET, 2185cebbd09SMartin Michlmayr .desc = "Reset Button", 2195cebbd09SMartin Michlmayr .active_low = 1, 2205cebbd09SMartin Michlmayr }, { 22128ca8c80SMartin Michlmayr .code = KEY_COPY, 22247e9cffdSSylver Bruneau .gpio = QNAP_TS409_GPIO_KEY_MEDIA, 22347e9cffdSSylver Bruneau .desc = "USB Copy Button", 22447e9cffdSSylver Bruneau .active_low = 1, 22547e9cffdSSylver Bruneau }, 22647e9cffdSSylver Bruneau }; 22747e9cffdSSylver Bruneau 22847e9cffdSSylver Bruneau static struct gpio_keys_platform_data qnap_ts409_button_data = { 22947e9cffdSSylver Bruneau .buttons = qnap_ts409_buttons, 23047e9cffdSSylver Bruneau .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), 23147e9cffdSSylver Bruneau }; 23247e9cffdSSylver Bruneau 23347e9cffdSSylver Bruneau static struct platform_device qnap_ts409_button_device = { 23447e9cffdSSylver Bruneau .name = "gpio-keys", 23547e9cffdSSylver Bruneau .id = -1, 23647e9cffdSSylver Bruneau .num_resources = 0, 23747e9cffdSSylver Bruneau .dev = { 23847e9cffdSSylver Bruneau .platform_data = &qnap_ts409_button_data, 23947e9cffdSSylver Bruneau }, 24047e9cffdSSylver Bruneau }; 24147e9cffdSSylver Bruneau 24247e9cffdSSylver Bruneau /***************************************************************************** 24347e9cffdSSylver Bruneau * General Setup 24447e9cffdSSylver Bruneau ****************************************************************************/ 245554cdaefSAndrew Lunn static unsigned int ts409_mpp_modes[] __initdata = { 246554cdaefSAndrew Lunn MPP0_UNUSED, 247554cdaefSAndrew Lunn MPP1_UNUSED, 248554cdaefSAndrew Lunn MPP2_UNUSED, 249554cdaefSAndrew Lunn MPP3_UNUSED, 250554cdaefSAndrew Lunn MPP4_GPIO, /* HDD 1 status */ 251554cdaefSAndrew Lunn MPP5_GPIO, /* HDD 2 status */ 252554cdaefSAndrew Lunn MPP6_GPIO, /* HDD 3 status */ 253554cdaefSAndrew Lunn MPP7_GPIO, /* HDD 4 status */ 254554cdaefSAndrew Lunn MPP8_UNUSED, 255554cdaefSAndrew Lunn MPP9_UNUSED, 256554cdaefSAndrew Lunn MPP10_GPIO, /* RTC int */ 257554cdaefSAndrew Lunn MPP11_UNUSED, 258554cdaefSAndrew Lunn MPP12_UNUSED, 259554cdaefSAndrew Lunn MPP13_UNUSED, 260554cdaefSAndrew Lunn MPP14_GPIO, /* SW_RST */ 261554cdaefSAndrew Lunn MPP15_GPIO, /* USB copy button */ 262554cdaefSAndrew Lunn MPP16_UART, /* UART1 RXD */ 263554cdaefSAndrew Lunn MPP17_UART, /* UART1 TXD */ 264554cdaefSAndrew Lunn MPP18_UNUSED, 265554cdaefSAndrew Lunn MPP19_UNUSED, 266554cdaefSAndrew Lunn 0, 26747e9cffdSSylver Bruneau }; 26847e9cffdSSylver Bruneau 26947e9cffdSSylver Bruneau static void __init qnap_ts409_init(void) 27047e9cffdSSylver Bruneau { 27147e9cffdSSylver Bruneau /* 27247e9cffdSSylver Bruneau * Setup basic Orion functions. Need to be called early. 27347e9cffdSSylver Bruneau */ 27447e9cffdSSylver Bruneau orion5x_init(); 27547e9cffdSSylver Bruneau 27647e9cffdSSylver Bruneau orion5x_mpp_conf(ts409_mpp_modes); 27747e9cffdSSylver Bruneau 27847e9cffdSSylver Bruneau /* 27947e9cffdSSylver Bruneau * Configure peripherals. 28047e9cffdSSylver Bruneau */ 28135228e84SMartin Michlmayr orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE, 28235228e84SMartin Michlmayr QNAP_TS409_NOR_BOOT_SIZE); 28335228e84SMartin Michlmayr platform_device_register(&qnap_ts409_nor_flash); 28435228e84SMartin Michlmayr 28547e9cffdSSylver Bruneau orion5x_ehci0_init(); 286530c854aSSylver Bruneau qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE + 287530c854aSSylver Bruneau qnap_ts409_partitions[5].offset, 288530c854aSSylver Bruneau qnap_ts409_partitions[5].size); 289530c854aSSylver Bruneau orion5x_eth_init(&qnap_tsx09_eth_data); 29047e9cffdSSylver Bruneau orion5x_i2c_init(); 29147e9cffdSSylver Bruneau orion5x_uart0_init(); 292e45772b2SMartin Michlmayr orion5x_uart1_init(); 29347e9cffdSSylver Bruneau 29447e9cffdSSylver Bruneau platform_device_register(&qnap_ts409_button_device); 29547e9cffdSSylver Bruneau 29647e9cffdSSylver Bruneau /* Get RTC IRQ and register the chip */ 29747e9cffdSSylver Bruneau if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) { 29847e9cffdSSylver Bruneau if (gpio_direction_input(TS409_RTC_GPIO) == 0) 29947e9cffdSSylver Bruneau qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO); 30047e9cffdSSylver Bruneau else 30147e9cffdSSylver Bruneau gpio_free(TS409_RTC_GPIO); 30247e9cffdSSylver Bruneau } 30347e9cffdSSylver Bruneau if (qnap_ts409_i2c_rtc.irq == 0) 30447e9cffdSSylver Bruneau pr_warning("qnap_ts409_init: failed to get RTC IRQ\n"); 30547e9cffdSSylver Bruneau i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1); 3064a4e30afSMartin Michlmayr platform_device_register(&ts409_leds); 30747e9cffdSSylver Bruneau 308530c854aSSylver Bruneau /* register tsx09 specific power-off method */ 309530c854aSSylver Bruneau pm_power_off = qnap_tsx09_power_off; 31047e9cffdSSylver Bruneau } 31147e9cffdSSylver Bruneau 31247e9cffdSSylver Bruneau MACHINE_START(TS409, "QNAP TS-409") 31347e9cffdSSylver Bruneau /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */ 31465aa1b1eSNicolas Pitre .atag_offset = 0x100, 31547e9cffdSSylver Bruneau .init_machine = qnap_ts409_init, 31647e9cffdSSylver Bruneau .map_io = orion5x_map_io, 3174ee1f6b5SLennert Buytenhek .init_early = orion5x_init_early, 31847e9cffdSSylver Bruneau .init_irq = orion5x_init_irq, 31947e9cffdSSylver Bruneau .timer = &orion5x_timer, 32047e9cffdSSylver Bruneau .fixup = tag_fixup_mem32, 321*764cbcc2SRussell King .restart = orion5x_restart, 32247e9cffdSSylver Bruneau MACHINE_END 323