1 /* 2 * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> 3 * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 */ 10 #include <linux/gpio.h> 11 #include <linux/gpio/machine.h> 12 #include <linux/kernel.h> 13 #include <linux/init.h> 14 #include <linux/platform_device.h> 15 #include <linux/irq.h> 16 #include <linux/mtd/physmap.h> 17 #include <linux/mv643xx_eth.h> 18 #include <linux/leds.h> 19 #include <linux/gpio_keys.h> 20 #include <linux/input.h> 21 #include <linux/i2c.h> 22 #include <linux/ata_platform.h> 23 #include <asm/mach-types.h> 24 #include <asm/mach/arch.h> 25 #include "common.h" 26 #include "mpp.h" 27 #include "orion5x.h" 28 29 #define MV2120_NOR_BOOT_BASE 0xf4000000 30 #define MV2120_NOR_BOOT_SIZE SZ_512K 31 32 #define MV2120_GPIO_RTC_IRQ 3 33 #define MV2120_GPIO_KEY_RESET 17 34 #define MV2120_GPIO_KEY_POWER 18 35 #define MV2120_GPIO_POWER_OFF 19 36 37 38 /***************************************************************************** 39 * Ethernet 40 ****************************************************************************/ 41 static struct mv643xx_eth_platform_data mv2120_eth_data = { 42 .phy_addr = MV643XX_ETH_PHY_ADDR(8), 43 }; 44 45 static struct mv_sata_platform_data mv2120_sata_data = { 46 .n_ports = 2, 47 }; 48 49 static struct mtd_partition mv2120_partitions[] = { 50 { 51 .name = "firmware", 52 .size = 0x00080000, 53 .offset = 0, 54 }, 55 }; 56 57 static struct physmap_flash_data mv2120_nor_flash_data = { 58 .width = 1, 59 .parts = mv2120_partitions, 60 .nr_parts = ARRAY_SIZE(mv2120_partitions) 61 }; 62 63 static struct resource mv2120_nor_flash_resource = { 64 .flags = IORESOURCE_MEM, 65 .start = MV2120_NOR_BOOT_BASE, 66 .end = MV2120_NOR_BOOT_BASE + MV2120_NOR_BOOT_SIZE - 1, 67 }; 68 69 static struct platform_device mv2120_nor_flash = { 70 .name = "physmap-flash", 71 .id = 0, 72 .dev = { 73 .platform_data = &mv2120_nor_flash_data, 74 }, 75 .resource = &mv2120_nor_flash_resource, 76 .num_resources = 1, 77 }; 78 79 static struct gpio_keys_button mv2120_buttons[] = { 80 { 81 .code = KEY_RESTART, 82 .gpio = MV2120_GPIO_KEY_RESET, 83 .desc = "reset", 84 .active_low = 1, 85 }, { 86 .code = KEY_POWER, 87 .gpio = MV2120_GPIO_KEY_POWER, 88 .desc = "power", 89 .active_low = 1, 90 }, 91 }; 92 93 static struct gpio_keys_platform_data mv2120_button_data = { 94 .buttons = mv2120_buttons, 95 .nbuttons = ARRAY_SIZE(mv2120_buttons), 96 }; 97 98 static struct platform_device mv2120_button_device = { 99 .name = "gpio-keys", 100 .id = -1, 101 .num_resources = 0, 102 .dev = { 103 .platform_data = &mv2120_button_data, 104 }, 105 }; 106 107 108 /**************************************************************************** 109 * General Setup 110 ****************************************************************************/ 111 static unsigned int mv2120_mpp_modes[] __initdata = { 112 MPP0_GPIO, /* Sys status LED */ 113 MPP1_GPIO, /* Sys error LED */ 114 MPP2_GPIO, /* OverTemp interrupt */ 115 MPP3_GPIO, /* RTC interrupt */ 116 MPP4_GPIO, /* V_LED 5V */ 117 MPP5_GPIO, /* V_LED 3.3V */ 118 MPP6_UNUSED, 119 MPP7_UNUSED, 120 MPP8_GPIO, /* SATA 0 fail LED */ 121 MPP9_GPIO, /* SATA 1 fail LED */ 122 MPP10_UNUSED, 123 MPP11_UNUSED, 124 MPP12_SATA_LED, /* SATA 0 presence */ 125 MPP13_SATA_LED, /* SATA 1 presence */ 126 MPP14_SATA_LED, /* SATA 0 active */ 127 MPP15_SATA_LED, /* SATA 1 active */ 128 MPP16_UNUSED, 129 MPP17_GPIO, /* Reset button */ 130 MPP18_GPIO, /* Power button */ 131 MPP19_GPIO, /* Power off */ 132 0, 133 }; 134 135 static struct i2c_board_info __initdata mv2120_i2c_rtc = { 136 I2C_BOARD_INFO("pcf8563", 0x51), 137 .irq = 0, 138 }; 139 140 static struct gpio_led mv2120_led_pins[] = { 141 { 142 .name = "mv2120:blue:health", 143 }, 144 { 145 .name = "mv2120:red:health", 146 }, 147 { 148 .name = "mv2120:led:bright", 149 .default_trigger = "default-on", 150 }, 151 { 152 .name = "mv2120:led:dimmed", 153 }, 154 { 155 .name = "mv2120:red:sata0", 156 }, 157 { 158 .name = "mv2120:red:sata1", 159 }, 160 161 }; 162 163 static struct gpiod_lookup_table mv2120_leds_gpio_table = { 164 .dev_id = "leds-gpio", 165 .table = { 166 GPIO_LOOKUP_IDX("orion_gpio0", 0, NULL, 167 0, GPIO_ACTIVE_HIGH), 168 GPIO_LOOKUP_IDX("orion_gpio0", 1, NULL, 169 1, GPIO_ACTIVE_HIGH), 170 GPIO_LOOKUP_IDX("orion_gpio0", 4, NULL, 171 2, GPIO_ACTIVE_HIGH), 172 GPIO_LOOKUP_IDX("orion_gpio0", 5, NULL, 173 3, GPIO_ACTIVE_HIGH), 174 GPIO_LOOKUP_IDX("orion_gpio0", 8, NULL, 175 4, GPIO_ACTIVE_LOW), 176 GPIO_LOOKUP_IDX("orion_gpio0", 9, NULL, 177 5, GPIO_ACTIVE_LOW), 178 { }, 179 }, 180 }; 181 182 static struct gpio_led_platform_data mv2120_led_data = { 183 .leds = mv2120_led_pins, 184 .num_leds = ARRAY_SIZE(mv2120_led_pins), 185 }; 186 187 static struct platform_device mv2120_leds = { 188 .name = "leds-gpio", 189 .id = -1, 190 .dev = { 191 .platform_data = &mv2120_led_data, 192 } 193 }; 194 195 static void mv2120_power_off(void) 196 { 197 pr_info("%s: triggering power-off...\n", __func__); 198 gpio_set_value(MV2120_GPIO_POWER_OFF, 0); 199 } 200 201 static void __init mv2120_init(void) 202 { 203 /* Setup basic Orion functions. Need to be called early. */ 204 orion5x_init(); 205 206 orion5x_mpp_conf(mv2120_mpp_modes); 207 208 /* 209 * Configure peripherals. 210 */ 211 orion5x_ehci0_init(); 212 orion5x_ehci1_init(); 213 orion5x_eth_init(&mv2120_eth_data); 214 orion5x_i2c_init(); 215 orion5x_sata_init(&mv2120_sata_data); 216 orion5x_uart0_init(); 217 orion5x_xor_init(); 218 219 mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET, 220 ORION_MBUS_DEVBUS_BOOT_ATTR, 221 MV2120_NOR_BOOT_BASE, 222 MV2120_NOR_BOOT_SIZE); 223 platform_device_register(&mv2120_nor_flash); 224 225 platform_device_register(&mv2120_button_device); 226 227 if (gpio_request(MV2120_GPIO_RTC_IRQ, "rtc") == 0) { 228 if (gpio_direction_input(MV2120_GPIO_RTC_IRQ) == 0) 229 mv2120_i2c_rtc.irq = gpio_to_irq(MV2120_GPIO_RTC_IRQ); 230 else 231 gpio_free(MV2120_GPIO_RTC_IRQ); 232 } 233 i2c_register_board_info(0, &mv2120_i2c_rtc, 1); 234 gpiod_add_lookup_table(&mv2120_leds_gpio_table); 235 platform_device_register(&mv2120_leds); 236 237 /* register mv2120 specific power-off method */ 238 if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 || 239 gpio_direction_output(MV2120_GPIO_POWER_OFF, 1) != 0) 240 pr_err("mv2120: failed to setup power-off GPIO\n"); 241 pm_power_off = mv2120_power_off; 242 } 243 244 /* Warning: HP uses a wrong mach-type (=526) in their bootloader */ 245 MACHINE_START(MV2120, "HP Media Vault mv2120") 246 /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ 247 .atag_offset = 0x100, 248 .nr_irqs = ORION5X_NR_IRQS, 249 .init_machine = mv2120_init, 250 .map_io = orion5x_map_io, 251 .init_early = orion5x_init_early, 252 .init_irq = orion5x_init_irq, 253 .init_time = orion5x_timer_init, 254 .fixup = tag_fixup_mem32, 255 .restart = orion5x_restart, 256 MACHINE_END 257