1 /* 2 * QNAP TS-109/TS-209 Board Setup 3 * 4 * Maintainer: Byron Bradley <byron.bbradley@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 #include <linux/gpio.h> 12 #include <linux/kernel.h> 13 #include <linux/init.h> 14 #include <linux/platform_device.h> 15 #include <linux/pci.h> 16 #include <linux/irq.h> 17 #include <linux/mtd/physmap.h> 18 #include <linux/mtd/nand.h> 19 #include <linux/mv643xx_eth.h> 20 #include <linux/gpio_keys.h> 21 #include <linux/input.h> 22 #include <linux/i2c.h> 23 #include <linux/serial_reg.h> 24 #include <linux/ata_platform.h> 25 #include <asm/mach-types.h> 26 #include <asm/mach/arch.h> 27 #include <asm/mach/pci.h> 28 #include <mach/orion5x.h> 29 #include "common.h" 30 #include "mpp.h" 31 #include "tsx09-common.h" 32 33 #define QNAP_TS209_NOR_BOOT_BASE 0xf4000000 34 #define QNAP_TS209_NOR_BOOT_SIZE SZ_8M 35 36 /**************************************************************************** 37 * 8MiB NOR flash. The struct mtd_partition is not in the same order as the 38 * partitions on the device because we want to keep compatibility with 39 * existing QNAP firmware. 40 * 41 * Layout as used by QNAP: 42 * [2] 0x00000000-0x00200000 : "Kernel" 43 * [3] 0x00200000-0x00600000 : "RootFS1" 44 * [4] 0x00600000-0x00700000 : "RootFS2" 45 * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) 46 * [5] 0x00760000-0x00780000 : "U-Boot Config" 47 * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) 48 ***************************************************************************/ 49 static struct mtd_partition qnap_ts209_partitions[] = { 50 { 51 .name = "U-Boot", 52 .size = 0x00080000, 53 .offset = 0x00780000, 54 .mask_flags = MTD_WRITEABLE, 55 }, { 56 .name = "Kernel", 57 .size = 0x00200000, 58 .offset = 0, 59 }, { 60 .name = "RootFS1", 61 .size = 0x00400000, 62 .offset = 0x00200000, 63 }, { 64 .name = "RootFS2", 65 .size = 0x00100000, 66 .offset = 0x00600000, 67 }, { 68 .name = "U-Boot Config", 69 .size = 0x00020000, 70 .offset = 0x00760000, 71 }, { 72 .name = "NAS Config", 73 .size = 0x00060000, 74 .offset = 0x00700000, 75 .mask_flags = MTD_WRITEABLE, 76 }, 77 }; 78 79 static struct physmap_flash_data qnap_ts209_nor_flash_data = { 80 .width = 1, 81 .parts = qnap_ts209_partitions, 82 .nr_parts = ARRAY_SIZE(qnap_ts209_partitions) 83 }; 84 85 static struct resource qnap_ts209_nor_flash_resource = { 86 .flags = IORESOURCE_MEM, 87 .start = QNAP_TS209_NOR_BOOT_BASE, 88 .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1, 89 }; 90 91 static struct platform_device qnap_ts209_nor_flash = { 92 .name = "physmap-flash", 93 .id = 0, 94 .dev = { 95 .platform_data = &qnap_ts209_nor_flash_data, 96 }, 97 .resource = &qnap_ts209_nor_flash_resource, 98 .num_resources = 1, 99 }; 100 101 /***************************************************************************** 102 * PCI 103 ****************************************************************************/ 104 105 #define QNAP_TS209_PCI_SLOT0_OFFS 7 106 #define QNAP_TS209_PCI_SLOT0_IRQ_PIN 6 107 #define QNAP_TS209_PCI_SLOT1_IRQ_PIN 7 108 109 void __init qnap_ts209_pci_preinit(void) 110 { 111 int pin; 112 113 /* 114 * Configure PCI GPIO IRQ pins 115 */ 116 pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN; 117 if (gpio_request(pin, "PCI Int1") == 0) { 118 if (gpio_direction_input(pin) == 0) { 119 irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); 120 } else { 121 printk(KERN_ERR "qnap_ts209_pci_preinit failed to " 122 "set_irq_type pin %d\n", pin); 123 gpio_free(pin); 124 } 125 } else { 126 printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request " 127 "%d\n", pin); 128 } 129 130 pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN; 131 if (gpio_request(pin, "PCI Int2") == 0) { 132 if (gpio_direction_input(pin) == 0) { 133 irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); 134 } else { 135 printk(KERN_ERR "qnap_ts209_pci_preinit failed " 136 "to set_irq_type pin %d\n", pin); 137 gpio_free(pin); 138 } 139 } else { 140 printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request " 141 "%d\n", pin); 142 } 143 } 144 145 static int __init qnap_ts209_pci_map_irq(const struct pci_dev *dev, u8 slot, 146 u8 pin) 147 { 148 int irq; 149 150 /* 151 * Check for devices with hard-wired IRQs. 152 */ 153 irq = orion5x_pci_map_irq(dev, slot, pin); 154 if (irq != -1) 155 return irq; 156 157 /* 158 * PCI IRQs are connected via GPIOs. 159 */ 160 switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) { 161 case 0: 162 return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN); 163 case 1: 164 return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN); 165 default: 166 return -1; 167 } 168 } 169 170 static struct hw_pci qnap_ts209_pci __initdata = { 171 .nr_controllers = 2, 172 .preinit = qnap_ts209_pci_preinit, 173 .setup = orion5x_pci_sys_setup, 174 .scan = orion5x_pci_sys_scan_bus, 175 .map_irq = qnap_ts209_pci_map_irq, 176 }; 177 178 static int __init qnap_ts209_pci_init(void) 179 { 180 if (machine_is_ts209()) 181 pci_common_init(&qnap_ts209_pci); 182 183 return 0; 184 } 185 186 subsys_initcall(qnap_ts209_pci_init); 187 188 /***************************************************************************** 189 * RTC S35390A on I2C bus 190 ****************************************************************************/ 191 192 #define TS209_RTC_GPIO 3 193 194 static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = { 195 I2C_BOARD_INFO("s35390a", 0x30), 196 .irq = 0, 197 }; 198 199 /**************************************************************************** 200 * GPIO Attached Keys 201 * Power button is attached to the PIC microcontroller 202 ****************************************************************************/ 203 204 #define QNAP_TS209_GPIO_KEY_MEDIA 1 205 #define QNAP_TS209_GPIO_KEY_RESET 2 206 207 static struct gpio_keys_button qnap_ts209_buttons[] = { 208 { 209 .code = KEY_COPY, 210 .gpio = QNAP_TS209_GPIO_KEY_MEDIA, 211 .desc = "USB Copy Button", 212 .active_low = 1, 213 }, { 214 .code = KEY_RESTART, 215 .gpio = QNAP_TS209_GPIO_KEY_RESET, 216 .desc = "Reset Button", 217 .active_low = 1, 218 }, 219 }; 220 221 static struct gpio_keys_platform_data qnap_ts209_button_data = { 222 .buttons = qnap_ts209_buttons, 223 .nbuttons = ARRAY_SIZE(qnap_ts209_buttons), 224 }; 225 226 static struct platform_device qnap_ts209_button_device = { 227 .name = "gpio-keys", 228 .id = -1, 229 .num_resources = 0, 230 .dev = { 231 .platform_data = &qnap_ts209_button_data, 232 }, 233 }; 234 235 /***************************************************************************** 236 * SATA 237 ****************************************************************************/ 238 static struct mv_sata_platform_data qnap_ts209_sata_data = { 239 .n_ports = 2, 240 }; 241 242 /***************************************************************************** 243 244 * General Setup 245 ****************************************************************************/ 246 static unsigned int ts209_mpp_modes[] __initdata = { 247 MPP0_UNUSED, 248 MPP1_GPIO, /* USB copy button */ 249 MPP2_GPIO, /* Load defaults button */ 250 MPP3_GPIO, /* GPIO RTC */ 251 MPP4_UNUSED, 252 MPP5_UNUSED, 253 MPP6_GPIO, /* PCI Int A */ 254 MPP7_GPIO, /* PCI Int B */ 255 MPP8_UNUSED, 256 MPP9_UNUSED, 257 MPP10_UNUSED, 258 MPP11_UNUSED, 259 MPP12_SATA_LED, /* SATA 0 presence */ 260 MPP13_SATA_LED, /* SATA 1 presence */ 261 MPP14_SATA_LED, /* SATA 0 active */ 262 MPP15_SATA_LED, /* SATA 1 active */ 263 MPP16_UART, /* UART1 RXD */ 264 MPP17_UART, /* UART1 TXD */ 265 MPP18_GPIO, /* SW_RST */ 266 MPP19_UNUSED, 267 0, 268 }; 269 270 static void __init qnap_ts209_init(void) 271 { 272 /* 273 * Setup basic Orion functions. Need to be called early. 274 */ 275 orion5x_init(); 276 277 orion5x_mpp_conf(ts209_mpp_modes); 278 279 /* 280 * MPP[20] PCI clock 0 281 * MPP[21] PCI clock 1 282 * MPP[22] USB 0 over current 283 * MPP[23-25] Reserved 284 */ 285 286 /* 287 * Configure peripherals. 288 */ 289 orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE, 290 QNAP_TS209_NOR_BOOT_SIZE); 291 platform_device_register(&qnap_ts209_nor_flash); 292 293 orion5x_ehci0_init(); 294 orion5x_ehci1_init(); 295 qnap_tsx09_find_mac_addr(QNAP_TS209_NOR_BOOT_BASE + 296 qnap_ts209_partitions[5].offset, 297 qnap_ts209_partitions[5].size); 298 orion5x_eth_init(&qnap_tsx09_eth_data); 299 orion5x_i2c_init(); 300 orion5x_sata_init(&qnap_ts209_sata_data); 301 orion5x_uart0_init(); 302 orion5x_uart1_init(); 303 orion5x_xor_init(); 304 305 platform_device_register(&qnap_ts209_button_device); 306 307 /* Get RTC IRQ and register the chip */ 308 if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) { 309 if (gpio_direction_input(TS209_RTC_GPIO) == 0) 310 qnap_ts209_i2c_rtc.irq = gpio_to_irq(TS209_RTC_GPIO); 311 else 312 gpio_free(TS209_RTC_GPIO); 313 } 314 if (qnap_ts209_i2c_rtc.irq == 0) 315 pr_warning("qnap_ts209_init: failed to get RTC IRQ\n"); 316 i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); 317 318 /* register tsx09 specific power-off method */ 319 pm_power_off = qnap_tsx09_power_off; 320 } 321 322 MACHINE_START(TS209, "QNAP TS-109/TS-209") 323 /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ 324 .atag_offset = 0x100, 325 .init_machine = qnap_ts209_init, 326 .map_io = orion5x_map_io, 327 .init_early = orion5x_init_early, 328 .init_irq = orion5x_init_irq, 329 .timer = &orion5x_timer, 330 .fixup = tag_fixup_mem32, 331 .restart = orion5x_restart, 332 MACHINE_END 333