linux/arch/arm/mach-orion5x/ts409-setup.c
<<
>>
Prefs
   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