linux/arch/arm/mach-kirkwood/netxbig_v2-setup.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-kirkwood/netxbig_v2-setup.c
   3 *
   4 * LaCie 2Big and 5Big Network v2 board setup
   5 *
   6 * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 */
  22
  23#include <linux/kernel.h>
  24#include <linux/init.h>
  25#include <linux/platform_device.h>
  26#include <linux/ata_platform.h>
  27#include <linux/mv643xx_eth.h>
  28#include <linux/input.h>
  29#include <linux/gpio.h>
  30#include <linux/gpio_keys.h>
  31#include <linux/leds.h>
  32#include <asm/mach-types.h>
  33#include <asm/mach/arch.h>
  34#include <mach/kirkwood.h>
  35#include <mach/leds-netxbig.h>
  36#include "common.h"
  37#include "mpp.h"
  38#include "lacie_v2-common.h"
  39
  40/*****************************************************************************
  41 * Ethernet
  42 ****************************************************************************/
  43
  44static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = {
  45        .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
  46};
  47
  48static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = {
  49        .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
  50};
  51
  52/*****************************************************************************
  53 * SATA
  54 ****************************************************************************/
  55
  56static struct mv_sata_platform_data netxbig_v2_sata_data = {
  57        .n_ports        = 2,
  58};
  59
  60/*****************************************************************************
  61 * GPIO keys
  62 ****************************************************************************/
  63
  64#define NETXBIG_V2_GPIO_SWITCH_POWER_ON         13
  65#define NETXBIG_V2_GPIO_SWITCH_POWER_OFF        15
  66#define NETXBIG_V2_GPIO_FUNC_BUTTON             34
  67
  68#define NETXBIG_V2_SWITCH_POWER_ON              0x1
  69#define NETXBIG_V2_SWITCH_POWER_OFF             0x2
  70
  71static struct gpio_keys_button netxbig_v2_buttons[] = {
  72        [0] = {
  73                .type           = EV_SW,
  74                .code           = NETXBIG_V2_SWITCH_POWER_ON,
  75                .gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_ON,
  76                .desc           = "Back power switch (on|auto)",
  77                .active_low     = 1,
  78        },
  79        [1] = {
  80                .type           = EV_SW,
  81                .code           = NETXBIG_V2_SWITCH_POWER_OFF,
  82                .gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_OFF,
  83                .desc           = "Back power switch (auto|off)",
  84                .active_low     = 1,
  85        },
  86        [2] = {
  87                .code           = KEY_OPTION,
  88                .gpio           = NETXBIG_V2_GPIO_FUNC_BUTTON,
  89                .desc           = "Function button",
  90                .active_low     = 1,
  91        },
  92};
  93
  94static struct gpio_keys_platform_data netxbig_v2_button_data = {
  95        .buttons        = netxbig_v2_buttons,
  96        .nbuttons       = ARRAY_SIZE(netxbig_v2_buttons),
  97};
  98
  99static struct platform_device netxbig_v2_gpio_buttons = {
 100        .name           = "gpio-keys",
 101        .id             = -1,
 102        .dev            = {
 103                .platform_data  = &netxbig_v2_button_data,
 104        },
 105};
 106
 107/*****************************************************************************
 108 * GPIO extension LEDs
 109 ****************************************************************************/
 110
 111/*
 112 * The LEDs are controlled by a CPLD and can be configured through a GPIO
 113 * extension bus:
 114 *
 115 * - address register : bit [0-2] -> GPIO [47-49]
 116 * - data register    : bit [0-2] -> GPIO [44-46]
 117 * - enable register  : GPIO 29
 118 */
 119
 120static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
 121static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
 122
 123static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
 124        .addr           = netxbig_v2_gpio_ext_addr,
 125        .num_addr       = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
 126        .data           = netxbig_v2_gpio_ext_data,
 127        .num_data       = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
 128        .enable         = 29,
 129};
 130
 131/*
 132 * Address register selection:
 133 *
 134 * addr | register
 135 * ----------------------------
 136 *   0  | front LED
 137 *   1  | front LED brightness
 138 *   2  | SATA LED brightness
 139 *   3  | SATA0 LED
 140 *   4  | SATA1 LED
 141 *   5  | SATA2 LED
 142 *   6  | SATA3 LED
 143 *   7  | SATA4 LED
 144 *
 145 * Data register configuration:
 146 *
 147 * data | LED brightness
 148 * -------------------------------------------------
 149 *   0  | min (off)
 150 *   -  | -
 151 *   7  | max
 152 *
 153 * data | front LED mode
 154 * -------------------------------------------------
 155 *   0  | fix off
 156 *   1  | fix blue on
 157 *   2  | fix red on
 158 *   3  | blink blue on=1 sec and blue off=1 sec
 159 *   4  | blink red on=1 sec and red off=1 sec
 160 *   5  | blink blue on=2.5 sec and red on=0.5 sec
 161 *   6  | blink blue on=1 sec and red on=1 sec
 162 *   7  | blink blue on=0.5 sec and blue off=2.5 sec
 163 *
 164 * data | SATA LED mode
 165 * -------------------------------------------------
 166 *   0  | fix off
 167 *   1  | SATA activity blink
 168 *   2  | fix red on
 169 *   3  | blink blue on=1 sec and blue off=1 sec
 170 *   4  | blink red on=1 sec and red off=1 sec
 171 *   5  | blink blue on=2.5 sec and red on=0.5 sec
 172 *   6  | blink blue on=1 sec and red on=1 sec
 173 *   7  | fix blue on
 174 */
 175
 176static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
 177        [NETXBIG_LED_OFF]       = 0,
 178        [NETXBIG_LED_ON]        = 2,
 179        [NETXBIG_LED_SATA]      = NETXBIG_LED_INVALID_MODE,
 180        [NETXBIG_LED_TIMER1]    = 4,
 181        [NETXBIG_LED_TIMER2]    = NETXBIG_LED_INVALID_MODE,
 182};
 183
 184static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
 185        [NETXBIG_LED_OFF]       = 0,
 186        [NETXBIG_LED_ON]        = 1,
 187        [NETXBIG_LED_SATA]      = NETXBIG_LED_INVALID_MODE,
 188        [NETXBIG_LED_TIMER1]    = 3,
 189        [NETXBIG_LED_TIMER2]    = 7,
 190};
 191
 192static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
 193        [NETXBIG_LED_OFF]       = 0,
 194        [NETXBIG_LED_ON]        = 7,
 195        [NETXBIG_LED_SATA]      = 1,
 196        [NETXBIG_LED_TIMER1]    = 3,
 197        [NETXBIG_LED_TIMER2]    = NETXBIG_LED_INVALID_MODE,
 198};
 199
 200static struct netxbig_led_timer netxbig_v2_led_timer[] = {
 201        [0] = {
 202                .delay_on       = 500,
 203                .delay_off      = 500,
 204                .mode           = NETXBIG_LED_TIMER1,
 205        },
 206        [1] = {
 207                .delay_on       = 500,
 208                .delay_off      = 1000,
 209                .mode           = NETXBIG_LED_TIMER2,
 210        },
 211};
 212
 213#define NETXBIG_LED(_name, maddr, mval, baddr)                  \
 214        { .name         = _name,                                \
 215          .mode_addr    = maddr,                                \
 216          .mode_val     = mval,                                 \
 217          .bright_addr  = baddr }
 218
 219static struct netxbig_led net2big_v2_leds_ctrl[] = {
 220        NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled,  1),
 221        NETXBIG_LED("net2big-v2:red:power",  0, netxbig_v2_red_mled,       1),
 222        NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
 223        NETXBIG_LED("net2big-v2:red:sata0",  3, netxbig_v2_red_mled,       2),
 224        NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
 225        NETXBIG_LED("net2big-v2:red:sata1",  4, netxbig_v2_red_mled,       2),
 226};
 227
 228static struct netxbig_led_platform_data net2big_v2_leds_data = {
 229        .gpio_ext       = &netxbig_v2_gpio_ext,
 230        .timer          = netxbig_v2_led_timer,
 231        .num_timer      = ARRAY_SIZE(netxbig_v2_led_timer),
 232        .leds           = net2big_v2_leds_ctrl,
 233        .num_leds       = ARRAY_SIZE(net2big_v2_leds_ctrl),
 234};
 235
 236static struct netxbig_led net5big_v2_leds_ctrl[] = {
 237        NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled,  1),
 238        NETXBIG_LED("net5big-v2:red:power",  0, netxbig_v2_red_mled,       1),
 239        NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
 240        NETXBIG_LED("net5big-v2:red:sata0",  3, netxbig_v2_red_mled,       2),
 241        NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
 242        NETXBIG_LED("net5big-v2:red:sata1",  4, netxbig_v2_red_mled,       2),
 243        NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
 244        NETXBIG_LED("net5big-v2:red:sata2",  5, netxbig_v2_red_mled,       2),
 245        NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
 246        NETXBIG_LED("net5big-v2:red:sata3",  6, netxbig_v2_red_mled,       2),
 247        NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
 248        NETXBIG_LED("net5big-v2:red:sata5",  7, netxbig_v2_red_mled,       2),
 249};
 250
 251static struct netxbig_led_platform_data net5big_v2_leds_data = {
 252        .gpio_ext       = &netxbig_v2_gpio_ext,
 253        .timer          = netxbig_v2_led_timer,
 254        .num_timer      = ARRAY_SIZE(netxbig_v2_led_timer),
 255        .leds           = net5big_v2_leds_ctrl,
 256        .num_leds       = ARRAY_SIZE(net5big_v2_leds_ctrl),
 257};
 258
 259static struct platform_device netxbig_v2_leds = {
 260        .name           = "leds-netxbig",
 261        .id             = -1,
 262        .dev            = {
 263                .platform_data  = &net2big_v2_leds_data,
 264        },
 265};
 266
 267/*****************************************************************************
 268 * General Setup
 269 ****************************************************************************/
 270
 271static unsigned int net2big_v2_mpp_config[] __initdata = {
 272        MPP0_SPI_SCn,
 273        MPP1_SPI_MOSI,
 274        MPP2_SPI_SCK,
 275        MPP3_SPI_MISO,
 276        MPP6_SYSRST_OUTn,
 277        MPP7_GPO,               /* Request power-off */
 278        MPP8_TW0_SDA,
 279        MPP9_TW0_SCK,
 280        MPP10_UART0_TXD,
 281        MPP11_UART0_RXD,
 282        MPP13_GPIO,             /* Rear power switch (on|auto) */
 283        MPP14_GPIO,             /* USB fuse alarm */
 284        MPP15_GPIO,             /* Rear power switch (auto|off) */
 285        MPP16_GPIO,             /* SATA HDD1 power */
 286        MPP17_GPIO,             /* SATA HDD2 power */
 287        MPP20_SATA1_ACTn,
 288        MPP21_SATA0_ACTn,
 289        MPP24_GPIO,             /* USB mode select */
 290        MPP26_GPIO,             /* USB device vbus */
 291        MPP28_GPIO,             /* USB enable host vbus */
 292        MPP29_GPIO,             /* GPIO extension ALE */
 293        MPP34_GPIO,             /* Rear Push button */
 294        MPP35_GPIO,             /* Inhibit switch power-off */
 295        MPP36_GPIO,             /* SATA HDD1 presence */
 296        MPP37_GPIO,             /* SATA HDD2 presence */
 297        MPP40_GPIO,             /* eSATA presence */
 298        MPP44_GPIO,             /* GPIO extension (data 0) */
 299        MPP45_GPIO,             /* GPIO extension (data 1) */
 300        MPP46_GPIO,             /* GPIO extension (data 2) */
 301        MPP47_GPIO,             /* GPIO extension (addr 0) */
 302        MPP48_GPIO,             /* GPIO extension (addr 1) */
 303        MPP49_GPIO,             /* GPIO extension (addr 2) */
 304        0
 305};
 306
 307static unsigned int net5big_v2_mpp_config[] __initdata = {
 308        MPP0_SPI_SCn,
 309        MPP1_SPI_MOSI,
 310        MPP2_SPI_SCK,
 311        MPP3_SPI_MISO,
 312        MPP6_SYSRST_OUTn,
 313        MPP7_GPO,               /* Request power-off */
 314        MPP8_TW0_SDA,
 315        MPP9_TW0_SCK,
 316        MPP10_UART0_TXD,
 317        MPP11_UART0_RXD,
 318        MPP13_GPIO,             /* Rear power switch (on|auto) */
 319        MPP14_GPIO,             /* USB fuse alarm */
 320        MPP15_GPIO,             /* Rear power switch (auto|off) */
 321        MPP16_GPIO,             /* SATA HDD1 power */
 322        MPP17_GPIO,             /* SATA HDD2 power */
 323        MPP20_GE1_TXD0,
 324        MPP21_GE1_TXD1,
 325        MPP22_GE1_TXD2,
 326        MPP23_GE1_TXD3,
 327        MPP24_GE1_RXD0,
 328        MPP25_GE1_RXD1,
 329        MPP26_GE1_RXD2,
 330        MPP27_GE1_RXD3,
 331        MPP28_GPIO,             /* USB enable host vbus */
 332        MPP29_GPIO,             /* GPIO extension ALE */
 333        MPP30_GE1_RXCTL,
 334        MPP31_GE1_RXCLK,
 335        MPP32_GE1_TCLKOUT,
 336        MPP33_GE1_TXCTL,
 337        MPP34_GPIO,             /* Rear Push button */
 338        MPP35_GPIO,             /* Inhibit switch power-off */
 339        MPP36_GPIO,             /* SATA HDD1 presence */
 340        MPP37_GPIO,             /* SATA HDD2 presence */
 341        MPP38_GPIO,             /* SATA HDD3 presence */
 342        MPP39_GPIO,             /* SATA HDD4 presence */
 343        MPP40_GPIO,             /* SATA HDD5 presence */
 344        MPP41_GPIO,             /* SATA HDD3 power */
 345        MPP42_GPIO,             /* SATA HDD4 power */
 346        MPP43_GPIO,             /* SATA HDD5 power */
 347        MPP44_GPIO,             /* GPIO extension (data 0) */
 348        MPP45_GPIO,             /* GPIO extension (data 1) */
 349        MPP46_GPIO,             /* GPIO extension (data 2) */
 350        MPP47_GPIO,             /* GPIO extension (addr 0) */
 351        MPP48_GPIO,             /* GPIO extension (addr 1) */
 352        MPP49_GPIO,             /* GPIO extension (addr 2) */
 353        0
 354};
 355
 356#define NETXBIG_V2_GPIO_POWER_OFF               7
 357
 358static void netxbig_v2_power_off(void)
 359{
 360        gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1);
 361}
 362
 363static void __init netxbig_v2_init(void)
 364{
 365        /*
 366         * Basic setup. Needs to be called early.
 367         */
 368        kirkwood_init();
 369        if (machine_is_net2big_v2())
 370                kirkwood_mpp_conf(net2big_v2_mpp_config);
 371        else
 372                kirkwood_mpp_conf(net5big_v2_mpp_config);
 373
 374        if (machine_is_net2big_v2())
 375                lacie_v2_hdd_power_init(2);
 376        else
 377                lacie_v2_hdd_power_init(5);
 378
 379        kirkwood_ehci_init();
 380        kirkwood_ge00_init(&netxbig_v2_ge00_data);
 381        if (machine_is_net5big_v2())
 382                kirkwood_ge01_init(&netxbig_v2_ge01_data);
 383        kirkwood_sata_init(&netxbig_v2_sata_data);
 384        kirkwood_uart0_init();
 385        lacie_v2_register_flash();
 386        lacie_v2_register_i2c_devices();
 387
 388        if (machine_is_net5big_v2())
 389                netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
 390        platform_device_register(&netxbig_v2_leds);
 391        platform_device_register(&netxbig_v2_gpio_buttons);
 392
 393        if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
 394            gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0)
 395                pm_power_off = netxbig_v2_power_off;
 396        else
 397                pr_err("netxbig_v2: failed to configure power-off GPIO\n");
 398}
 399
 400#ifdef CONFIG_MACH_NET2BIG_V2
 401MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
 402        .boot_params    = 0x00000100,
 403        .init_machine   = netxbig_v2_init,
 404        .map_io         = kirkwood_map_io,
 405        .init_irq       = kirkwood_init_irq,
 406        .timer          = &kirkwood_timer,
 407MACHINE_END
 408#endif
 409
 410#ifdef CONFIG_MACH_NET5BIG_V2
 411MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
 412        .boot_params    = 0x00000100,
 413        .init_machine   = netxbig_v2_init,
 414        .map_io         = kirkwood_map_io,
 415        .init_irq       = kirkwood_init_irq,
 416        .timer          = &kirkwood_timer,
 417MACHINE_END
 418#endif
 419