1/* 2 * arch/arm/mach-orion5x/d2net-setup.c 3 * 4 * LaCie d2Network and Big Disk Network NAS setup 5 * 6 * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com> 7 * 8 * This file is licensed under the terms of the GNU General Public 9 * License version 2. This program is licensed "as is" without any 10 * warranty of any kind, whether express or implied. 11 */ 12 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/platform_device.h> 16#include <linux/pci.h> 17#include <linux/irq.h> 18#include <linux/mtd/physmap.h> 19#include <linux/mv643xx_eth.h> 20#include <linux/leds.h> 21#include <linux/gpio_keys.h> 22#include <linux/input.h> 23#include <linux/i2c.h> 24#include <linux/ata_platform.h> 25#include <linux/gpio.h> 26#include <asm/mach-types.h> 27#include <asm/mach/arch.h> 28#include <asm/mach/pci.h> 29#include <mach/orion5x.h> 30#include "common.h" 31#include "mpp.h" 32 33/***************************************************************************** 34 * LaCie d2 Network Info 35 ****************************************************************************/ 36 37/* 38 * 512KB NOR flash Device bus boot chip select 39 */ 40 41#define D2NET_NOR_BOOT_BASE 0xfff80000 42#define D2NET_NOR_BOOT_SIZE SZ_512K 43 44/***************************************************************************** 45 * 512KB NOR Flash on Boot Device 46 ****************************************************************************/ 47 48/* 49 * TODO: Check write support on flash MX29LV400CBTC-70G 50 */ 51 52static struct mtd_partition d2net_partitions[] = { 53 { 54 .name = "Full512kb", 55 .size = MTDPART_SIZ_FULL, 56 .offset = 0, 57 .mask_flags = MTD_WRITEABLE, 58 }, 59}; 60 61static struct physmap_flash_data d2net_nor_flash_data = { 62 .width = 1, 63 .parts = d2net_partitions, 64 .nr_parts = ARRAY_SIZE(d2net_partitions), 65}; 66 67static struct resource d2net_nor_flash_resource = { 68 .flags = IORESOURCE_MEM, 69 .start = D2NET_NOR_BOOT_BASE, 70 .end = D2NET_NOR_BOOT_BASE 71 + D2NET_NOR_BOOT_SIZE - 1, 72}; 73 74static struct platform_device d2net_nor_flash = { 75 .name = "physmap-flash", 76 .id = 0, 77 .dev = { 78 .platform_data = &d2net_nor_flash_data, 79 }, 80 .num_resources = 1, 81 .resource = &d2net_nor_flash_resource, 82}; 83 84/***************************************************************************** 85 * Ethernet 86 ****************************************************************************/ 87 88static struct mv643xx_eth_platform_data d2net_eth_data = { 89 .phy_addr = MV643XX_ETH_PHY_ADDR(8), 90}; 91 92/***************************************************************************** 93 * I2C devices 94 ****************************************************************************/ 95 96/* 97 * i2c addr | chip | description 98 * 0x32 | Ricoh 5C372b | RTC 99 * 0x3e | GMT G762 | PWM fan controller 100 * 0x50 | HT24LC08 | eeprom (1kB) 101 * 102 * TODO: Add G762 support to the g760a driver. 103 */ 104static struct i2c_board_info __initdata d2net_i2c_devices[] = { 105 { 106 I2C_BOARD_INFO("rs5c372b", 0x32), 107 }, { 108 I2C_BOARD_INFO("24c08", 0x50), 109 }, 110}; 111 112/***************************************************************************** 113 * SATA 114 ****************************************************************************/ 115 116static struct mv_sata_platform_data d2net_sata_data = { 117 .n_ports = 2, 118}; 119 120#define D2NET_GPIO_SATA0_POWER 3 121#define D2NET_GPIO_SATA1_POWER 12 122 123static void __init d2net_sata_power_init(void) 124{ 125 int err; 126 127 err = gpio_request(D2NET_GPIO_SATA0_POWER, "SATA0 power"); 128 if (err == 0) { 129 err = gpio_direction_output(D2NET_GPIO_SATA0_POWER, 1); 130 if (err) 131 gpio_free(D2NET_GPIO_SATA0_POWER); 132 } 133 if (err) 134 pr_err("d2net: failed to configure SATA0 power GPIO\n"); 135 136 err = gpio_request(D2NET_GPIO_SATA1_POWER, "SATA1 power"); 137 if (err == 0) { 138 err = gpio_direction_output(D2NET_GPIO_SATA1_POWER, 1); 139 if (err) 140 gpio_free(D2NET_GPIO_SATA1_POWER); 141 } 142 if (err) 143 pr_err("d2net: failed to configure SATA1 power GPIO\n"); 144} 145 146/***************************************************************************** 147 * GPIO LED's 148 ****************************************************************************/ 149 150/* 151 * The blue front LED is wired to the CPLD and can blink in relation with the 152 * SATA activity. 153 * 154 * The following array detail the different LED registers and the combination 155 * of their possible values: 156 * 157 * led_off | blink_ctrl | SATA active | LED state 158 * | | | 159 * 1 | x | x | off 160 * 0 | 0 | 0 | off 161 * 0 | 1 | 0 | blink (rate 300ms) 162 * 0 | x | 1 | on 163 * 164 * Notes: The blue and the red front LED's can't be on at the same time. 165 * Red LED have priority. 166 */ 167 168#define D2NET_GPIO_RED_LED 6 169#define D2NET_GPIO_BLUE_LED_BLINK_CTRL 16 170#define D2NET_GPIO_BLUE_LED_OFF 23 171 172static struct gpio_led d2net_leds[] = { 173 { 174 .name = "d2net:blue:sata", 175 .default_trigger = "default-on", 176 .gpio = D2NET_GPIO_BLUE_LED_OFF, 177 .active_low = 1, 178 }, 179 { 180 .name = "d2net:red:fail", 181 .gpio = D2NET_GPIO_RED_LED, 182 }, 183}; 184 185static struct gpio_led_platform_data d2net_led_data = { 186 .num_leds = ARRAY_SIZE(d2net_leds), 187 .leds = d2net_leds, 188}; 189 190static struct platform_device d2net_gpio_leds = { 191 .name = "leds-gpio", 192 .id = -1, 193 .dev = { 194 .platform_data = &d2net_led_data, 195 }, 196}; 197 198static void __init d2net_gpio_leds_init(void) 199{ 200 int err; 201 202 /* Configure GPIO over MPP max number. */ 203 orion_gpio_set_valid(D2NET_GPIO_BLUE_LED_OFF, 1); 204 205 /* Configure register blink_ctrl to allow SATA activity LED blinking. */ 206 err = gpio_request(D2NET_GPIO_BLUE_LED_BLINK_CTRL, "blue LED blink"); 207 if (err == 0) { 208 err = gpio_direction_output(D2NET_GPIO_BLUE_LED_BLINK_CTRL, 1); 209 if (err) 210 gpio_free(D2NET_GPIO_BLUE_LED_BLINK_CTRL); 211 } 212 if (err) 213 pr_err("d2net: failed to configure blue LED blink GPIO\n"); 214 215 platform_device_register(&d2net_gpio_leds); 216} 217 218/**************************************************************************** 219 * GPIO keys 220 ****************************************************************************/ 221 222#define D2NET_GPIO_PUSH_BUTTON 18 223#define D2NET_GPIO_POWER_SWITCH_ON 8 224#define D2NET_GPIO_POWER_SWITCH_OFF 9 225 226#define D2NET_SWITCH_POWER_ON 0x1 227#define D2NET_SWITCH_POWER_OFF 0x2 228 229static struct gpio_keys_button d2net_buttons[] = { 230 { 231 .type = EV_SW, 232 .code = D2NET_SWITCH_POWER_OFF, 233 .gpio = D2NET_GPIO_POWER_SWITCH_OFF, 234 .desc = "Power rocker switch (auto|off)", 235 .active_low = 0, 236 }, 237 { 238 .type = EV_SW, 239 .code = D2NET_SWITCH_POWER_ON, 240 .gpio = D2NET_GPIO_POWER_SWITCH_ON, 241 .desc = "Power rocker switch (on|auto)", 242 .active_low = 0, 243 }, 244 { 245 .type = EV_KEY, 246 .code = KEY_POWER, 247 .gpio = D2NET_GPIO_PUSH_BUTTON, 248 .desc = "Front Push Button", 249 .active_low = 0, 250 }, 251}; 252 253static struct gpio_keys_platform_data d2net_button_data = { 254 .buttons = d2net_buttons, 255 .nbuttons = ARRAY_SIZE(d2net_buttons), 256}; 257 258static struct platform_device d2net_gpio_buttons = { 259 .name = "gpio-keys", 260 .id = -1, 261 .dev = { 262 .platform_data = &d2net_button_data, 263 }, 264}; 265 266/***************************************************************************** 267 * General Setup 268 ****************************************************************************/ 269 270static struct orion5x_mpp_mode d2net_mpp_modes[] __initdata = { 271 { 0, MPP_GPIO }, /* Board ID (bit 0) */ 272 { 1, MPP_GPIO }, /* Board ID (bit 1) */ 273 { 2, MPP_GPIO }, /* Board ID (bit 2) */ 274 { 3, MPP_GPIO }, /* SATA 0 power */ 275 { 4, MPP_UNUSED }, 276 { 5, MPP_GPIO }, /* Fan fail detection */ 277 { 6, MPP_GPIO }, /* Red front LED */ 278 { 7, MPP_UNUSED }, 279 { 8, MPP_GPIO }, /* Rear power switch (on|auto) */ 280 { 9, MPP_GPIO }, /* Rear power switch (auto|off) */ 281 { 10, MPP_UNUSED }, 282 { 11, MPP_UNUSED }, 283 { 12, MPP_GPIO }, /* SATA 1 power */ 284 { 13, MPP_UNUSED }, 285 { 14, MPP_SATA_LED }, /* SATA 0 active */ 286 { 15, MPP_SATA_LED }, /* SATA 1 active */ 287 { 16, MPP_GPIO }, /* Blue front LED blink control */ 288 { 17, MPP_UNUSED }, 289 { 18, MPP_GPIO }, /* Front button (0 = Released, 1 = Pushed ) */ 290 { 19, MPP_UNUSED }, 291 { -1 } 292 /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */ 293 /* 23: Blue front LED off */ 294 /* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */ 295}; 296 297#define D2NET_GPIO_INHIBIT_POWER_OFF 24 298 299static void __init d2net_init(void) 300{ 301 /* 302 * Setup basic Orion functions. Need to be called early. 303 */ 304 orion5x_init(); 305 306 orion5x_mpp_conf(d2net_mpp_modes); 307 308 /* 309 * Configure peripherals. 310 */ 311 orion5x_ehci0_init(); 312 orion5x_eth_init(&d2net_eth_data); 313 orion5x_i2c_init(); 314 orion5x_uart0_init(); 315 316 d2net_sata_power_init(); 317 orion5x_sata_init(&d2net_sata_data); 318 319 orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE, 320 D2NET_NOR_BOOT_SIZE); 321 platform_device_register(&d2net_nor_flash); 322 323 platform_device_register(&d2net_gpio_buttons); 324 325 d2net_gpio_leds_init(); 326 327 pr_notice("d2net: Flash write are not yet supported.\n"); 328 329 i2c_register_board_info(0, d2net_i2c_devices, 330 ARRAY_SIZE(d2net_i2c_devices)); 331 332 orion_gpio_set_valid(D2NET_GPIO_INHIBIT_POWER_OFF, 1); 333} 334 335/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */ 336 337#ifdef CONFIG_MACH_D2NET 338MACHINE_START(D2NET, "LaCie d2 Network") 339 .phys_io = ORION5X_REGS_PHYS_BASE, 340 .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, 341 .boot_params = 0x00000100, 342 .init_machine = d2net_init, 343 .map_io = orion5x_map_io, 344 .init_irq = orion5x_init_irq, 345 .timer = &orion5x_timer, 346 .fixup = tag_fixup_mem32, 347MACHINE_END 348#endif 349 350#ifdef CONFIG_MACH_BIGDISK 351MACHINE_START(BIGDISK, "LaCie Big Disk Network") 352 .phys_io = ORION5X_REGS_PHYS_BASE, 353 .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, 354 .boot_params = 0x00000100, 355 .init_machine = d2net_init, 356 .map_io = orion5x_map_io, 357 .init_irq = orion5x_init_irq, 358 .timer = &orion5x_timer, 359 .fixup = tag_fixup_mem32, 360MACHINE_END 361#endif 362