1/* 2 * Atheros AP83 board support 3 * 4 * Copyright (C) 2008-2012 Gabor Juhos <juhosg@openwrt.org> 5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 as published 9 * by the Free Software Foundation. 10 */ 11 12#include <linux/delay.h> 13#include <linux/platform_device.h> 14#include <linux/mtd/mtd.h> 15#include <linux/mtd/partitions.h> 16#include <linux/mtd/physmap.h> 17#include <linux/spi/spi.h> 18#include <linux/spi/spi_gpio.h> 19#include <linux/spi/vsc7385.h> 20 21#include <asm/mach-ath79/ar71xx_regs.h> 22#include <asm/mach-ath79/ath79.h> 23 24#include "dev-eth.h" 25#include "dev-gpio-buttons.h" 26#include "dev-leds-gpio.h" 27#include "dev-usb.h" 28#include "dev-wmac.h" 29#include "machtypes.h" 30 31#define AP83_GPIO_LED_WLAN 6 32#define AP83_GPIO_LED_POWER 14 33#define AP83_GPIO_LED_JUMPSTART 15 34#define AP83_GPIO_BTN_JUMPSTART 12 35#define AP83_GPIO_BTN_RESET 21 36 37#define AP83_050_GPIO_VSC7385_CS 1 38#define AP83_050_GPIO_VSC7385_MISO 3 39#define AP83_050_GPIO_VSC7385_MOSI 16 40#define AP83_050_GPIO_VSC7385_SCK 17 41 42#define AP83_KEYS_POLL_INTERVAL 20 /* msecs */ 43#define AP83_KEYS_DEBOUNCE_INTERVAL (3 * AP83_KEYS_POLL_INTERVAL) 44 45static struct mtd_partition ap83_flash_partitions[] = { 46 { 47 .name = "u-boot", 48 .offset = 0, 49 .size = 0x040000, 50 .mask_flags = MTD_WRITEABLE, 51 }, { 52 .name = "u-boot-env", 53 .offset = 0x040000, 54 .size = 0x020000, 55 .mask_flags = MTD_WRITEABLE, 56 }, { 57 .name = "kernel", 58 .offset = 0x060000, 59 .size = 0x140000, 60 }, { 61 .name = "rootfs", 62 .offset = 0x1a0000, 63 .size = 0x650000, 64 }, { 65 .name = "art", 66 .offset = 0x7f0000, 67 .size = 0x010000, 68 .mask_flags = MTD_WRITEABLE, 69 }, { 70 .name = "firmware", 71 .offset = 0x060000, 72 .size = 0x790000, 73 } 74}; 75 76static struct physmap_flash_data ap83_flash_data = { 77 .width = 2, 78 .parts = ap83_flash_partitions, 79 .nr_parts = ARRAY_SIZE(ap83_flash_partitions), 80}; 81 82static struct resource ap83_flash_resources[] = { 83 [0] = { 84 .start = AR71XX_SPI_BASE, 85 .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, 86 .flags = IORESOURCE_MEM, 87 }, 88}; 89 90static struct platform_device ap83_flash_device = { 91 .name = "ar91xx-flash", 92 .id = -1, 93 .resource = ap83_flash_resources, 94 .num_resources = ARRAY_SIZE(ap83_flash_resources), 95 .dev = { 96 .platform_data = &ap83_flash_data, 97 } 98}; 99 100static struct gpio_led ap83_leds_gpio[] __initdata = { 101 { 102 .name = "ap83:green:jumpstart", 103 .gpio = AP83_GPIO_LED_JUMPSTART, 104 .active_low = 0, 105 }, { 106 .name = "ap83:green:power", 107 .gpio = AP83_GPIO_LED_POWER, 108 .active_low = 0, 109 }, { 110 .name = "ap83:green:wlan", 111 .gpio = AP83_GPIO_LED_WLAN, 112 .active_low = 0, 113 }, 114}; 115 116static struct gpio_keys_button ap83_gpio_keys[] __initdata = { 117 { 118 .desc = "soft_reset", 119 .type = EV_KEY, 120 .code = KEY_RESTART, 121 .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, 122 .gpio = AP83_GPIO_BTN_RESET, 123 .active_low = 1, 124 }, { 125 .desc = "jumpstart", 126 .type = EV_KEY, 127 .code = KEY_WPS_BUTTON, 128 .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, 129 .gpio = AP83_GPIO_BTN_JUMPSTART, 130 .active_low = 1, 131 } 132}; 133 134static struct resource ap83_040_spi_resources[] = { 135 [0] = { 136 .start = AR71XX_SPI_BASE, 137 .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, 138 .flags = IORESOURCE_MEM, 139 }, 140}; 141 142static struct platform_device ap83_040_spi_device = { 143 .name = "ap83-spi", 144 .id = 0, 145 .resource = ap83_040_spi_resources, 146 .num_resources = ARRAY_SIZE(ap83_040_spi_resources), 147}; 148 149static struct spi_gpio_platform_data ap83_050_spi_data = { 150 .miso = AP83_050_GPIO_VSC7385_MISO, 151 .mosi = AP83_050_GPIO_VSC7385_MOSI, 152 .sck = AP83_050_GPIO_VSC7385_SCK, 153 .num_chipselect = 1, 154}; 155 156static struct platform_device ap83_050_spi_device = { 157 .name = "spi_gpio", 158 .id = 0, 159 .dev = { 160 .platform_data = &ap83_050_spi_data, 161 } 162}; 163 164static void ap83_vsc7385_reset(void) 165{ 166 ath79_device_reset_set(AR71XX_RESET_GE1_PHY); 167 udelay(10); 168 ath79_device_reset_clear(AR71XX_RESET_GE1_PHY); 169 mdelay(50); 170} 171 172static struct vsc7385_platform_data ap83_vsc7385_data = { 173 .reset = ap83_vsc7385_reset, 174 .ucode_name = "vsc7385_ucode_ap83.bin", 175 .mac_cfg = { 176 .tx_ipg = 6, 177 .bit2 = 0, 178 .clk_sel = 3, 179 }, 180}; 181 182static struct spi_board_info ap83_spi_info[] = { 183 { 184 .bus_num = 0, 185 .chip_select = 0, 186 .max_speed_hz = 25000000, 187 .modalias = "spi-vsc7385", 188 .platform_data = &ap83_vsc7385_data, 189 .controller_data = (void *) AP83_050_GPIO_VSC7385_CS, 190 } 191}; 192 193static void __init ap83_generic_setup(void) 194{ 195 u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); 196 197 ath79_register_mdio(0, 0xfffffffe); 198 199 ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); 200 ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; 201 ath79_eth0_data.phy_mask = 0x1; 202 203 ath79_register_eth(0); 204 205 ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); 206 ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; 207 ath79_eth1_data.speed = SPEED_1000; 208 ath79_eth1_data.duplex = DUPLEX_FULL; 209 210 ath79_eth1_pll_data.pll_1000 = 0x1f000000; 211 212 ath79_register_eth(1); 213 214 ath79_register_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio), 215 ap83_leds_gpio); 216 217 ath79_register_gpio_keys_polled(-1, AP83_KEYS_POLL_INTERVAL, 218 ARRAY_SIZE(ap83_gpio_keys), 219 ap83_gpio_keys); 220 221 ath79_register_usb(); 222 223 ath79_register_wmac(eeprom, NULL); 224 225 platform_device_register(&ap83_flash_device); 226 227 spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info)); 228} 229 230static void ap83_040_flash_lock(struct platform_device *pdev) 231{ 232 ath79_flash_acquire(); 233} 234 235static void ap83_040_flash_unlock(struct platform_device *pdev) 236{ 237 ath79_flash_release(); 238} 239 240static void __init ap83_040_setup(void) 241{ 242 ap83_flash_data.lock = ap83_040_flash_lock; 243 ap83_flash_data.unlock = ap83_040_flash_unlock; 244 ap83_generic_setup(); 245 platform_device_register(&ap83_040_spi_device); 246} 247 248static void __init ap83_050_setup(void) 249{ 250 ap83_generic_setup(); 251 platform_device_register(&ap83_050_spi_device); 252} 253 254static void __init ap83_setup(void) 255{ 256 u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244); 257 unsigned int board_version; 258 259 board_version = (unsigned int)(board_id[0] - '0'); 260 board_version += ((unsigned int)(board_id[1] - '0')) * 10; 261 262 switch (board_version) { 263 case 40: 264 ap83_040_setup(); 265 break; 266 case 50: 267 ap83_050_setup(); 268 break; 269 default: 270 printk(KERN_WARNING "AP83-%03u board is not yet supported\n", 271 board_version); 272 } 273} 274 275MIPS_MACHINE(ATH79_MACH_AP83, "AP83", "Atheros AP83", ap83_setup); 276