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 ***************************************************************************/ 69static 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 99static 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 105static 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 111static 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 123static 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 141static 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 148static 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 156subsys_initcall(qnap_ts409_pci_init); 157 158/***************************************************************************** 159 * RTC S35390A on I2C bus 160 ****************************************************************************/ 161 162#define TS409_RTC_GPIO 10 163 164static 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 172static 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 192static struct gpio_led_platform_data ts409_led_data = { 193 .leds = ts409_led_pins, 194 .num_leds = ARRAY_SIZE(ts409_led_pins), 195}; 196 197static 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 213static 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 227static struct gpio_keys_platform_data qnap_ts409_button_data = { 228 .buttons = qnap_ts409_buttons, 229 .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), 230}; 231 232static 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 ****************************************************************************/ 244static 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 268static 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_warn("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 313MACHINE_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, 323MACHINE_END 324