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 .swizzle = pci_std_swizzle, 144 .setup = orion5x_pci_sys_setup, 145 .scan = orion5x_pci_sys_scan_bus, 146 .map_irq = qnap_ts409_pci_map_irq, 147 }; 148 149 static int __init qnap_ts409_pci_init(void) 150 { 151 if (machine_is_ts409()) 152 pci_common_init(&qnap_ts409_pci); 153 154 return 0; 155 } 156 157 subsys_initcall(qnap_ts409_pci_init); 158 159 /***************************************************************************** 160 * RTC S35390A on I2C bus 161 ****************************************************************************/ 162 163 #define TS409_RTC_GPIO 10 164 165 static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = { 166 I2C_BOARD_INFO("s35390a", 0x30), 167 }; 168 169 /***************************************************************************** 170 * LEDs attached to GPIO 171 ****************************************************************************/ 172 173 static struct gpio_led ts409_led_pins[] = { 174 { 175 .name = "ts409:red:sata1", 176 .gpio = 4, 177 .active_low = 1, 178 }, { 179 .name = "ts409:red:sata2", 180 .gpio = 5, 181 .active_low = 1, 182 }, { 183 .name = "ts409:red:sata3", 184 .gpio = 6, 185 .active_low = 1, 186 }, { 187 .name = "ts409:red:sata4", 188 .gpio = 7, 189 .active_low = 1, 190 }, 191 }; 192 193 static struct gpio_led_platform_data ts409_led_data = { 194 .leds = ts409_led_pins, 195 .num_leds = ARRAY_SIZE(ts409_led_pins), 196 }; 197 198 static struct platform_device ts409_leds = { 199 .name = "leds-gpio", 200 .id = -1, 201 .dev = { 202 .platform_data = &ts409_led_data, 203 }, 204 }; 205 206 /**************************************************************************** 207 * GPIO Attached Keys 208 * Power button is attached to the PIC microcontroller 209 ****************************************************************************/ 210 211 #define QNAP_TS409_GPIO_KEY_RESET 14 212 #define QNAP_TS409_GPIO_KEY_MEDIA 15 213 214 static struct gpio_keys_button qnap_ts409_buttons[] = { 215 { 216 .code = KEY_RESTART, 217 .gpio = QNAP_TS409_GPIO_KEY_RESET, 218 .desc = "Reset Button", 219 .active_low = 1, 220 }, { 221 .code = KEY_COPY, 222 .gpio = QNAP_TS409_GPIO_KEY_MEDIA, 223 .desc = "USB Copy Button", 224 .active_low = 1, 225 }, 226 }; 227 228 static struct gpio_keys_platform_data qnap_ts409_button_data = { 229 .buttons = qnap_ts409_buttons, 230 .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), 231 }; 232 233 static struct platform_device qnap_ts409_button_device = { 234 .name = "gpio-keys", 235 .id = -1, 236 .num_resources = 0, 237 .dev = { 238 .platform_data = &qnap_ts409_button_data, 239 }, 240 }; 241 242 /***************************************************************************** 243 * General Setup 244 ****************************************************************************/ 245 static unsigned int ts409_mpp_modes[] __initdata = { 246 MPP0_UNUSED, 247 MPP1_UNUSED, 248 MPP2_UNUSED, 249 MPP3_UNUSED, 250 MPP4_GPIO, /* HDD 1 status */ 251 MPP5_GPIO, /* HDD 2 status */ 252 MPP6_GPIO, /* HDD 3 status */ 253 MPP7_GPIO, /* HDD 4 status */ 254 MPP8_UNUSED, 255 MPP9_UNUSED, 256 MPP10_GPIO, /* RTC int */ 257 MPP11_UNUSED, 258 MPP12_UNUSED, 259 MPP13_UNUSED, 260 MPP14_GPIO, /* SW_RST */ 261 MPP15_GPIO, /* USB copy button */ 262 MPP16_UART, /* UART1 RXD */ 263 MPP17_UART, /* UART1 TXD */ 264 MPP18_UNUSED, 265 MPP19_UNUSED, 266 0, 267 }; 268 269 static void __init qnap_ts409_init(void) 270 { 271 /* 272 * Setup basic Orion functions. Need to be called early. 273 */ 274 orion5x_init(); 275 276 orion5x_mpp_conf(ts409_mpp_modes); 277 278 /* 279 * Configure peripherals. 280 */ 281 orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE, 282 QNAP_TS409_NOR_BOOT_SIZE); 283 platform_device_register(&qnap_ts409_nor_flash); 284 285 orion5x_ehci0_init(); 286 qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE + 287 qnap_ts409_partitions[5].offset, 288 qnap_ts409_partitions[5].size); 289 orion5x_eth_init(&qnap_tsx09_eth_data); 290 orion5x_i2c_init(); 291 orion5x_uart0_init(); 292 orion5x_uart1_init(); 293 294 platform_device_register(&qnap_ts409_button_device); 295 296 /* Get RTC IRQ and register the chip */ 297 if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) { 298 if (gpio_direction_input(TS409_RTC_GPIO) == 0) 299 qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO); 300 else 301 gpio_free(TS409_RTC_GPIO); 302 } 303 if (qnap_ts409_i2c_rtc.irq == 0) 304 pr_warning("qnap_ts409_init: failed to get RTC IRQ\n"); 305 i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1); 306 platform_device_register(&ts409_leds); 307 308 /* register tsx09 specific power-off method */ 309 pm_power_off = qnap_tsx09_power_off; 310 } 311 312 MACHINE_START(TS409, "QNAP TS-409") 313 /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */ 314 .atag_offset = 0x100, 315 .init_machine = qnap_ts409_init, 316 .map_io = orion5x_map_io, 317 .init_early = orion5x_init_early, 318 .init_irq = orion5x_init_irq, 319 .timer = &orion5x_timer, 320 .fixup = tag_fixup_mem32, 321 .restart = orion5x_restart, 322 MACHINE_END 323