1 /* 2 * QNAP TS-409 Board Setup 3 * 4 * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> 5 * 6 * Copyright (C) 2008 Sylver Bruneau <sylver.bruneau@gmail.com> 7 * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com> 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 12 * 2 of the License, or (at your option) any later version. 13 */ 14 #include <linux/gpio.h> 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/platform_device.h> 18 #include <linux/pci.h> 19 #include <linux/irq.h> 20 #include <linux/mtd/physmap.h> 21 #include <linux/mv643xx_eth.h> 22 #include <linux/leds.h> 23 #include <linux/gpio_keys.h> 24 #include <linux/input.h> 25 #include <linux/i2c.h> 26 #include <linux/serial_reg.h> 27 #include <asm/mach-types.h> 28 #include <asm/mach/arch.h> 29 #include <asm/mach/pci.h> 30 #include <mach/orion5x.h> 31 #include "common.h" 32 #include "mpp.h" 33 #include "tsx09-common.h" 34 35 /***************************************************************************** 36 * QNAP TS-409 Info 37 ****************************************************************************/ 38 39 /* 40 * QNAP TS-409 hardware : 41 * - Marvell 88F5281-D0 42 * - Marvell 88SX7042 SATA controller (PCIe) 43 * - Marvell 88E1118 Gigabit Ethernet PHY 44 * - RTC S35390A (@0x30) on I2C bus 45 * - 8MB NOR flash 46 * - 256MB of DDR-2 RAM 47 */ 48 49 /* 50 * 8MB NOR flash Device bus boot chip select 51 */ 52 53 #define QNAP_TS409_NOR_BOOT_BASE 0xff800000 54 #define QNAP_TS409_NOR_BOOT_SIZE SZ_8M 55 56 /**************************************************************************** 57 * 8MiB NOR flash. The struct mtd_partition is not in the same order as the 58 * partitions on the device because we want to keep compatibility with 59 * existing QNAP firmware. 60 * 61 * Layout as used by QNAP: 62 * [2] 0x00000000-0x00200000 : "Kernel" 63 * [3] 0x00200000-0x00600000 : "RootFS1" 64 * [4] 0x00600000-0x00700000 : "RootFS2" 65 * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) 66 * [5] 0x00760000-0x00780000 : "U-Boot Config" 67 * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) 68 ***************************************************************************/ 69 static struct mtd_partition qnap_ts409_partitions[] = { 70 { 71 .name = "U-Boot", 72 .size = 0x00080000, 73 .offset = 0x00780000, 74 .mask_flags = MTD_WRITEABLE, 75 }, { 76 .name = "Kernel", 77 .size = 0x00200000, 78 .offset = 0, 79 }, { 80 .name = "RootFS1", 81 .size = 0x00400000, 82 .offset = 0x00200000, 83 }, { 84 .name = "RootFS2", 85 .size = 0x00100000, 86 .offset = 0x00600000, 87 }, { 88 .name = "U-Boot Config", 89 .size = 0x00020000, 90 .offset = 0x00760000, 91 }, { 92 .name = "NAS Config", 93 .size = 0x00060000, 94 .offset = 0x00700000, 95 .mask_flags = MTD_WRITEABLE, 96 }, 97 }; 98 99 static struct physmap_flash_data qnap_ts409_nor_flash_data = { 100 .width = 1, 101 .parts = qnap_ts409_partitions, 102 .nr_parts = ARRAY_SIZE(qnap_ts409_partitions) 103 }; 104 105 static struct resource qnap_ts409_nor_flash_resource = { 106 .flags = IORESOURCE_MEM, 107 .start = QNAP_TS409_NOR_BOOT_BASE, 108 .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1, 109 }; 110 111 static struct platform_device qnap_ts409_nor_flash = { 112 .name = "physmap-flash", 113 .id = 0, 114 .dev = { .platform_data = &qnap_ts409_nor_flash_data, }, 115 .num_resources = 1, 116 .resource = &qnap_ts409_nor_flash_resource, 117 }; 118 119 /***************************************************************************** 120 * PCI 121 ****************************************************************************/ 122 123 static int __init qnap_ts409_pci_map_irq(const struct pci_dev *dev, u8 slot, 124 u8 pin) 125 { 126 int irq; 127 128 /* 129 * Check for devices with hard-wired IRQs. 130 */ 131 irq = orion5x_pci_map_irq(dev, slot, pin); 132 if (irq != -1) 133 return irq; 134 135 /* 136 * PCI isn't used on the TS-409 137 */ 138 return -1; 139 } 140 141 static struct hw_pci qnap_ts409_pci __initdata = { 142 .nr_controllers = 2, 143 .setup = orion5x_pci_sys_setup, 144 .scan = orion5x_pci_sys_scan_bus, 145 .map_irq = qnap_ts409_pci_map_irq, 146 }; 147 148 static int __init qnap_ts409_pci_init(void) 149 { 150 if (machine_is_ts409()) 151 pci_common_init(&qnap_ts409_pci); 152 153 return 0; 154 } 155 156 subsys_initcall(qnap_ts409_pci_init); 157 158 /***************************************************************************** 159 * RTC S35390A on I2C bus 160 ****************************************************************************/ 161 162 #define TS409_RTC_GPIO 10 163 164 static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = { 165 I2C_BOARD_INFO("s35390a", 0x30), 166 }; 167 168 /***************************************************************************** 169 * LEDs attached to GPIO 170 ****************************************************************************/ 171 172 static struct gpio_led ts409_led_pins[] = { 173 { 174 .name = "ts409:red:sata1", 175 .gpio = 4, 176 .active_low = 1, 177 }, { 178 .name = "ts409:red:sata2", 179 .gpio = 5, 180 .active_low = 1, 181 }, { 182 .name = "ts409:red:sata3", 183 .gpio = 6, 184 .active_low = 1, 185 }, { 186 .name = "ts409:red:sata4", 187 .gpio = 7, 188 .active_low = 1, 189 }, 190 }; 191 192 static struct gpio_led_platform_data ts409_led_data = { 193 .leds = ts409_led_pins, 194 .num_leds = ARRAY_SIZE(ts409_led_pins), 195 }; 196 197 static struct platform_device ts409_leds = { 198 .name = "leds-gpio", 199 .id = -1, 200 .dev = { 201 .platform_data = &ts409_led_data, 202 }, 203 }; 204 205 /**************************************************************************** 206 * GPIO Attached Keys 207 * Power button is attached to the PIC microcontroller 208 ****************************************************************************/ 209 210 #define QNAP_TS409_GPIO_KEY_RESET 14 211 #define QNAP_TS409_GPIO_KEY_MEDIA 15 212 213 static struct gpio_keys_button qnap_ts409_buttons[] = { 214 { 215 .code = KEY_RESTART, 216 .gpio = QNAP_TS409_GPIO_KEY_RESET, 217 .desc = "Reset Button", 218 .active_low = 1, 219 }, { 220 .code = KEY_COPY, 221 .gpio = QNAP_TS409_GPIO_KEY_MEDIA, 222 .desc = "USB Copy Button", 223 .active_low = 1, 224 }, 225 }; 226 227 static struct gpio_keys_platform_data qnap_ts409_button_data = { 228 .buttons = qnap_ts409_buttons, 229 .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), 230 }; 231 232 static struct platform_device qnap_ts409_button_device = { 233 .name = "gpio-keys", 234 .id = -1, 235 .num_resources = 0, 236 .dev = { 237 .platform_data = &qnap_ts409_button_data, 238 }, 239 }; 240 241 /***************************************************************************** 242 * General Setup 243 ****************************************************************************/ 244 static unsigned int ts409_mpp_modes[] __initdata = { 245 MPP0_UNUSED, 246 MPP1_UNUSED, 247 MPP2_UNUSED, 248 MPP3_UNUSED, 249 MPP4_GPIO, /* HDD 1 status */ 250 MPP5_GPIO, /* HDD 2 status */ 251 MPP6_GPIO, /* HDD 3 status */ 252 MPP7_GPIO, /* HDD 4 status */ 253 MPP8_UNUSED, 254 MPP9_UNUSED, 255 MPP10_GPIO, /* RTC int */ 256 MPP11_UNUSED, 257 MPP12_UNUSED, 258 MPP13_UNUSED, 259 MPP14_GPIO, /* SW_RST */ 260 MPP15_GPIO, /* USB copy button */ 261 MPP16_UART, /* UART1 RXD */ 262 MPP17_UART, /* UART1 TXD */ 263 MPP18_UNUSED, 264 MPP19_UNUSED, 265 0, 266 }; 267 268 static void __init qnap_ts409_init(void) 269 { 270 /* 271 * Setup basic Orion functions. Need to be called early. 272 */ 273 orion5x_init(); 274 275 orion5x_mpp_conf(ts409_mpp_modes); 276 277 /* 278 * Configure peripherals. 279 */ 280 mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET, 281 ORION_MBUS_DEVBUS_BOOT_ATTR, 282 QNAP_TS409_NOR_BOOT_BASE, 283 QNAP_TS409_NOR_BOOT_SIZE); 284 platform_device_register(&qnap_ts409_nor_flash); 285 286 orion5x_ehci0_init(); 287 qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE + 288 qnap_ts409_partitions[5].offset, 289 qnap_ts409_partitions[5].size); 290 orion5x_eth_init(&qnap_tsx09_eth_data); 291 orion5x_i2c_init(); 292 orion5x_uart0_init(); 293 orion5x_uart1_init(); 294 295 platform_device_register(&qnap_ts409_button_device); 296 297 /* Get RTC IRQ and register the chip */ 298 if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) { 299 if (gpio_direction_input(TS409_RTC_GPIO) == 0) 300 qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO); 301 else 302 gpio_free(TS409_RTC_GPIO); 303 } 304 if (qnap_ts409_i2c_rtc.irq == 0) 305 pr_warning("qnap_ts409_init: failed to get RTC IRQ\n"); 306 i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1); 307 platform_device_register(&ts409_leds); 308 309 /* register tsx09 specific power-off method */ 310 pm_power_off = qnap_tsx09_power_off; 311 } 312 313 MACHINE_START(TS409, "QNAP TS-409") 314 /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */ 315 .atag_offset = 0x100, 316 .init_machine = qnap_ts409_init, 317 .map_io = orion5x_map_io, 318 .init_early = orion5x_init_early, 319 .init_irq = orion5x_init_irq, 320 .init_time = orion5x_timer_init, 321 .fixup = tag_fixup_mem32, 322 .restart = orion5x_restart, 323 MACHINE_END 324