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