1/* 2 * Atheros DB120 reference board with TB388 extension support 3 * 4 * Copyright (c) 2012 The Linux Foundation. All rights reserved. 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 * All rights reserved. 10 */ 11 12#include <linux/pci.h> 13#include <linux/phy.h> 14#include <linux/platform_device.h> 15#include <linux/ath9k_platform.h> 16#include <linux/ar8216_platform.h> 17#include <linux/delay.h> 18#include <linux/gpio.h> 19 20#include <asm/mach-ath79/ar71xx_regs.h> 21#include <asm/mach-ath79/ath79.h> 22 23#include "common.h" 24#include "dev-ap9x-pci.h" 25#include "dev-audio.h" 26#include "dev-eth.h" 27#include "dev-gpio-buttons.h" 28#include "dev-leds-gpio.h" 29#include "dev-m25p80.h" 30#include "dev-spi.h" 31#include "dev-usb.h" 32#include "dev-wmac.h" 33#include "machtypes.h" 34 35#define DB120_GPIO_I2S_MCLK 4 36#define DB120_GPIO_I2S_SD 11 37#define DB120_GPIO_I2S_WS 12 38#define DB120_GPIO_I2S_CLK 13 39#define DB120_GPIO_I2S_MIC_SD 14 40#define DB120_GPIO_SPDIF_OUT 15 41 42#define DB120_GPIO_BTN_WPS 16 43 44#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ 45#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) 46 47#define DB120_MAC0_OFFSET 0 48#define DB120_MAC1_OFFSET 6 49#define DB120_WMAC_CALDATA_OFFSET 0x1000 50#define DB120_PCIE_CALDATA_OFFSET 0x5000 51 52static struct gpio_keys_button db120_tb388_gpio_keys[] __initdata = { 53 { 54 .desc = "WPS button", 55 .type = EV_KEY, 56 .code = KEY_WPS_BUTTON, 57 .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL, 58 .gpio = DB120_GPIO_BTN_WPS, 59 .active_low = 1, 60 }, 61}; 62 63static struct ar8327_pad_cfg db120_tb388_ar8327_pad0_cfg = { 64 .mode = AR8327_PAD_MAC_RGMII, 65 .txclk_delay_en = true, 66 .rxclk_delay_en = true, 67 .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, 68 .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, 69}; 70 71static struct ar8327_platform_data db120_tb388_ar8327_data = { 72 .pad0_cfg = &db120_tb388_ar8327_pad0_cfg, 73 .cpuport_cfg = { 74 .force_link = 1, 75 .speed = AR8327_PORT_SPEED_1000, 76 .duplex = 1, 77 .txpause = 1, 78 .rxpause = 1, 79 } 80}; 81 82static struct mdio_board_info db120_tb388_mdio0_info[] = { 83 { 84 .bus_id = "ag71xx-mdio.0", 85 .phy_addr = 0, 86 .platform_data = &db120_tb388_ar8327_data, 87 }, 88}; 89 90static struct platform_device db120_tb388_spdif_codec = { 91 .name = "ath79-internal-codec", 92 .id = -1, 93}; 94 95static void __init db120_tb388_gmac_setup(void) 96{ 97 void __iomem *base; 98 u32 t; 99 100 base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); 101 102 t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); 103 t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | 104 AR934X_ETH_CFG_GMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE); 105 t |= AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE; 106 107 __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); 108 109 iounmap(base); 110} 111 112static void __init db120_tb388_audio_setup(void) 113{ 114 u32 t; 115 116 /* Reset I2S internal controller */ 117 t = ath79_reset_rr(AR71XX_RESET_REG_RESET_MODULE); 118 ath79_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | AR934X_RESET_I2S ); 119 udelay(1); 120 121 /* GPIO configuration 122 GPIOs 4,11,12,13 are configured as I2S signal - Output 123 GPIO 15 is SPDIF - Output 124 GPIO 14 is MIC - Input 125 Please note that the value in direction_output doesn't really matter 126 here as GPIOs are configured to relay internal data signal 127 */ 128 gpio_request(DB120_GPIO_I2S_CLK, "I2S CLK"); 129 ath79_gpio_output_select(DB120_GPIO_I2S_CLK, AR934X_GPIO_OUT_MUX_I2S_CLK); 130 gpio_direction_output(DB120_GPIO_I2S_CLK, 0); 131 132 gpio_request(DB120_GPIO_I2S_WS, "I2S WS"); 133 ath79_gpio_output_select(DB120_GPIO_I2S_WS, AR934X_GPIO_OUT_MUX_I2S_WS); 134 gpio_direction_output(DB120_GPIO_I2S_WS, 0); 135 136 gpio_request(DB120_GPIO_I2S_SD, "I2S SD"); 137 ath79_gpio_output_select(DB120_GPIO_I2S_SD, AR934X_GPIO_OUT_MUX_I2S_SD); 138 gpio_direction_output(DB120_GPIO_I2S_SD, 0); 139 140 gpio_request(DB120_GPIO_I2S_MCLK, "I2S MCLK"); 141 ath79_gpio_output_select(DB120_GPIO_I2S_MCLK, AR934X_GPIO_OUT_MUX_I2S_MCK); 142 gpio_direction_output(DB120_GPIO_I2S_MCLK, 0); 143 144 gpio_request(DB120_GPIO_SPDIF_OUT, "SPDIF OUT"); 145 ath79_gpio_output_select(DB120_GPIO_SPDIF_OUT, AR934X_GPIO_OUT_MUX_SPDIF_OUT); 146 gpio_direction_output(DB120_GPIO_SPDIF_OUT, 0); 147 148 gpio_request(DB120_GPIO_I2S_MIC_SD, "I2S MIC_SD"); 149 ath79_gpio_input_select(DB120_GPIO_I2S_MIC_SD, AR934X_GPIO_IN_MUX_I2S_MIC_SD); 150 gpio_direction_input(DB120_GPIO_I2S_MIC_SD); 151 152 /* Init stereo block registers in default configuration */ 153 ath79_audio_setup(); 154} 155 156static void __init db120_tb388_setup(void) 157{ 158 u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); 159 160 ath79_register_m25p80(NULL); 161 162 ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, 163 ARRAY_SIZE(db120_tb388_gpio_keys), 164 db120_tb388_gpio_keys); 165 ath79_register_usb(); 166 ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET, NULL); 167 ap91_pci_init(art + DB120_PCIE_CALDATA_OFFSET, NULL); 168 169 db120_tb388_gmac_setup(); 170 171 ath79_register_mdio(1, 0x0); 172 ath79_register_mdio(0, 0x0); 173 174 ath79_init_mac(ath79_eth0_data.mac_addr, art + DB120_MAC0_OFFSET, 0); 175 176 mdiobus_register_board_info(db120_tb388_mdio0_info, 177 ARRAY_SIZE(db120_tb388_mdio0_info)); 178 179 /* GMAC0 is connected to an AR8327 switch */ 180 ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; 181 ath79_eth0_data.phy_mask = BIT(0); 182 ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; 183 ath79_eth0_pll_data.pll_1000 = 0x06000000; 184 ath79_register_eth(0); 185 186 /* GMAC1 is connected to the internal switch */ 187 ath79_init_mac(ath79_eth1_data.mac_addr, art + DB120_MAC1_OFFSET, 0); 188 ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; 189 ath79_eth1_data.speed = SPEED_1000; 190 ath79_eth1_data.duplex = DUPLEX_FULL; 191 192 ath79_register_eth(1); 193 194 /* Audio initialization: PCM/I2S and CODEC */ 195 db120_tb388_audio_setup(); 196 platform_device_register(&db120_tb388_spdif_codec); 197 ath79_audio_device_register(); 198} 199 200MIPS_MACHINE(ATH79_MACH_DB120_TB388, "DB120TB388", 201 "Atheros DB120 reference board with TB388 extension", 202 db120_tb388_setup); 203