1/* 2 * WD My Net N600 board support 3 * 4 * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation. 9 */ 10 11#include <linux/pci.h> 12#include <linux/phy.h> 13#include <linux/gpio.h> 14#include <linux/platform_device.h> 15#include <linux/ath9k_platform.h> 16#include <linux/ar8216_platform.h> 17 18#include <asm/mach-ath79/ar71xx_regs.h> 19 20#include "common.h" 21#include "dev-ap9x-pci.h" 22#include "dev-eth.h" 23#include "dev-gpio-buttons.h" 24#include "dev-leds-gpio.h" 25#include "dev-m25p80.h" 26#include "dev-spi.h" 27#include "dev-usb.h" 28#include "dev-wmac.h" 29#include "machtypes.h" 30#include "nvram.h" 31 32#define MYNET_N600_GPIO_LED_WIFI 0 33#define MYNET_N600_GPIO_LED_POWER 11 34#define MYNET_N600_GPIO_LED_INTERNET 12 35#define MYNET_N600_GPIO_LED_WPS 13 36 37#define MYNET_N600_GPIO_LED_LAN1 4 38#define MYNET_N600_GPIO_LED_LAN2 3 39#define MYNET_N600_GPIO_LED_LAN3 2 40#define MYNET_N600_GPIO_LED_LAN4 1 41 42#define MYNET_N600_GPIO_BTN_RESET 16 43#define MYNET_N600_GPIO_BTN_WPS 17 44 45#define MYNET_N600_GPIO_EXTERNAL_LNA0 14 46#define MYNET_N600_GPIO_EXTERNAL_LNA1 15 47 48#define MYNET_N600_KEYS_POLL_INTERVAL 20 /* msecs */ 49#define MYNET_N600_KEYS_DEBOUNCE_INTERVAL (3 * MYNET_N600_KEYS_POLL_INTERVAL) 50 51#define MYNET_N600_MAC0_OFFSET 0 52#define MYNET_N600_MAC1_OFFSET 6 53#define MYNET_N600_WMAC_CALDATA_OFFSET 0x1000 54#define MYNET_N600_PCIE_CALDATA_OFFSET 0x5000 55 56#define MYNET_N600_NVRAM_ADDR 0x1f058010 57#define MYNET_N600_NVRAM_SIZE 0x7ff0 58 59static struct gpio_led mynet_n600_leds_gpio[] __initdata = { 60 { 61 .name = "wd:blue:power", 62 .gpio = MYNET_N600_GPIO_LED_POWER, 63 .active_low = 0, 64 }, 65 { 66 .name = "wd:blue:wps", 67 .gpio = MYNET_N600_GPIO_LED_WPS, 68 .active_low = 0, 69 }, 70 { 71 .name = "wd:blue:wireless", 72 .gpio = MYNET_N600_GPIO_LED_WIFI, 73 .active_low = 0, 74 }, 75 { 76 .name = "wd:blue:internet", 77 .gpio = MYNET_N600_GPIO_LED_INTERNET, 78 .active_low = 0, 79 }, 80 { 81 .name = "wd:green:lan1", 82 .gpio = MYNET_N600_GPIO_LED_LAN1, 83 .active_low = 1, 84 }, 85 { 86 .name = "wd:green:lan2", 87 .gpio = MYNET_N600_GPIO_LED_LAN2, 88 .active_low = 1, 89 }, 90 { 91 .name = "wd:green:lan3", 92 .gpio = MYNET_N600_GPIO_LED_LAN3, 93 .active_low = 1, 94 }, 95 { 96 .name = "wd:green:lan4", 97 .gpio = MYNET_N600_GPIO_LED_LAN4, 98 .active_low = 1, 99 }, 100}; 101 102static struct gpio_keys_button mynet_n600_gpio_keys[] __initdata = { 103 { 104 .desc = "Reset button", 105 .type = EV_KEY, 106 .code = KEY_RESTART, 107 .debounce_interval = MYNET_N600_KEYS_DEBOUNCE_INTERVAL, 108 .gpio = MYNET_N600_GPIO_BTN_RESET, 109 .active_low = 1, 110 }, 111 { 112 .desc = "WPS button", 113 .type = EV_KEY, 114 .code = KEY_WPS_BUTTON, 115 .debounce_interval = MYNET_N600_KEYS_DEBOUNCE_INTERVAL, 116 .gpio = MYNET_N600_GPIO_BTN_WPS, 117 .active_low = 1, 118 }, 119}; 120 121static void mynet_n600_get_mac(const char *name, char *mac) 122{ 123 u8 *nvram = (u8 *) KSEG1ADDR(MYNET_N600_NVRAM_ADDR); 124 int err; 125 126 err = ath79_nvram_parse_mac_addr(nvram, MYNET_N600_NVRAM_SIZE, 127 name, mac); 128 if (err) 129 pr_err("no MAC address found for %s\n", name); 130} 131 132#define MYNET_N600_WAN_PHY_MASK BIT(0) 133 134static void __init mynet_n600_setup(void) 135{ 136 u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); 137 u8 tmpmac[ETH_ALEN]; 138 139 ath79_register_m25p80(NULL); 140 141 ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN1, 142 AR934X_GPIO_OUT_GPIO); 143 ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN2, 144 AR934X_GPIO_OUT_GPIO); 145 ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN3, 146 AR934X_GPIO_OUT_GPIO); 147 ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN4, 148 AR934X_GPIO_OUT_GPIO); 149 ath79_gpio_output_select(MYNET_N600_GPIO_LED_INTERNET, 150 AR934X_GPIO_OUT_GPIO); 151 ath79_register_leds_gpio(-1, ARRAY_SIZE(mynet_n600_leds_gpio), 152 mynet_n600_leds_gpio); 153 154 ath79_register_gpio_keys_polled(-1, MYNET_N600_KEYS_POLL_INTERVAL, 155 ARRAY_SIZE(mynet_n600_gpio_keys), 156 mynet_n600_gpio_keys); 157 158 /* 159 * Control signal for external LNAs 0 and 1 160 * Taken from GPL bootloader source: 161 * board/ar7240/db12x/alpha_gpio.c 162 */ 163 ath79_wmac_set_ext_lna_gpio(0, MYNET_N600_GPIO_EXTERNAL_LNA0); 164 ath79_wmac_set_ext_lna_gpio(1, MYNET_N600_GPIO_EXTERNAL_LNA1); 165 166 mynet_n600_get_mac("wlan24mac=", tmpmac); 167 ath79_register_wmac(art + MYNET_N600_WMAC_CALDATA_OFFSET, tmpmac); 168 169 mynet_n600_get_mac("wlan5mac=", tmpmac); 170 ap91_pci_init(art + MYNET_N600_PCIE_CALDATA_OFFSET, tmpmac); 171 172 ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE | 173 AR934X_ETH_CFG_SW_PHY_SWAP); 174 175 ath79_register_mdio(1, 0x0); 176 177 /* LAN */ 178 mynet_n600_get_mac("lanmac=", ath79_eth1_data.mac_addr); 179 180 /* GMAC1 is connected to the internal switch */ 181 ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; 182 183 ath79_register_eth(1); 184 185 /* WAN */ 186 mynet_n600_get_mac("wanmac=", ath79_eth0_data.mac_addr); 187 188 /* GMAC0 is connected to the PHY4 of the internal switch */ 189 ath79_switch_data.phy4_mii_en = 1; 190 ath79_switch_data.phy_poll_mask = MYNET_N600_WAN_PHY_MASK; 191 192 ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; 193 ath79_eth0_data.phy_mask = MYNET_N600_WAN_PHY_MASK; 194 ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; 195 196 ath79_register_eth(0); 197 198 ath79_register_usb(); 199} 200 201MIPS_MACHINE(ATH79_MACH_MYNET_N600, "MYNET-N600", "WD My Net N600", 202 mynet_n600_setup); 203