1/*
2 * TP-LINK Archer C5/C7/TL-WDR4900 v2 board support
3 *
4 * Copyright (c) 2013 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (c) 2014 ��������� <tenninjas@tenninjas.ca>
6 * Copyright (c) 2014 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * Based on the Qualcomm Atheros AP135/AP136 reference board support code
9 *   Copyright (c) 2012 Qualcomm Atheros
10 *
11 * Permission to use, copy, modify, and/or distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 */
24
25#include <linux/pci.h>
26#include <linux/phy.h>
27#include <linux/gpio.h>
28#include <linux/platform_device.h>
29#include <linux/ath9k_platform.h>
30#include <linux/ar8216_platform.h>
31
32#include <asm/mach-ath79/ar71xx_regs.h>
33
34#include "common.h"
35#include "dev-ap9x-pci.h"
36#include "dev-eth.h"
37#include "dev-gpio-buttons.h"
38#include "dev-leds-gpio.h"
39#include "dev-m25p80.h"
40#include "dev-spi.h"
41#include "dev-usb.h"
42#include "dev-wmac.h"
43#include "machtypes.h"
44#include "pci.h"
45
46#define ARCHER_C7_GPIO_LED_WLAN2G	12
47#define ARCHER_C7_GPIO_LED_SYSTEM	14
48#define ARCHER_C7_GPIO_LED_QSS		15
49#define ARCHER_C7_GPIO_LED_WLAN5G	17
50#define ARCHER_C7_GPIO_LED_USB1		18
51#define ARCHER_C7_GPIO_LED_USB2		19
52
53#define ARCHER_C7_GPIO_BTN_RFKILL	13
54#define ARCHER_C7_V2_GPIO_BTN_RFKILL	23
55#define ARCHER_C7_GPIO_BTN_RESET	16
56
57#define ARCHER_C7_GPIO_USB1_POWER	22
58#define ARCHER_C7_GPIO_USB2_POWER	21
59
60#define ARCHER_C7_KEYS_POLL_INTERVAL	20	/* msecs */
61#define ARCHER_C7_KEYS_DEBOUNCE_INTERVAL (3 * ARCHER_C7_KEYS_POLL_INTERVAL)
62
63#define ARCHER_C7_WMAC_CALDATA_OFFSET	0x1000
64#define ARCHER_C7_PCIE_CALDATA_OFFSET	0x5000
65
66static const char *archer_c7_part_probes[] = {
67	"tp-link",
68	NULL,
69};
70
71static struct flash_platform_data archer_c7_flash_data = {
72	.part_probes	= archer_c7_part_probes,
73};
74
75static struct gpio_led archer_c7_leds_gpio[] __initdata = {
76	{
77		.name		= "tp-link:blue:qss",
78		.gpio		= ARCHER_C7_GPIO_LED_QSS,
79		.active_low	= 1,
80	},
81	{
82		.name		= "tp-link:blue:system",
83		.gpio		= ARCHER_C7_GPIO_LED_SYSTEM,
84		.active_low	= 1,
85	},
86	{
87		.name		= "tp-link:blue:wlan2g",
88		.gpio		= ARCHER_C7_GPIO_LED_WLAN2G,
89		.active_low	= 1,
90	},
91	{
92		.name		= "tp-link:blue:wlan5g",
93		.gpio		= ARCHER_C7_GPIO_LED_WLAN5G,
94		.active_low	= 1,
95	},
96	{
97		.name		= "tp-link:green:usb1",
98		.gpio		= ARCHER_C7_GPIO_LED_USB1,
99		.active_low	= 1,
100	},
101	{
102		.name		= "tp-link:green:usb2",
103		.gpio		= ARCHER_C7_GPIO_LED_USB2,
104		.active_low	= 1,
105	},
106};
107
108static struct gpio_keys_button archer_c7_gpio_keys[] __initdata = {
109	{
110		.desc		= "Reset button",
111		.type		= EV_KEY,
112		.code		= KEY_WPS_BUTTON,
113		.debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL,
114		.gpio		= ARCHER_C7_GPIO_BTN_RESET,
115		.active_low	= 1,
116	},
117	{
118		.desc		= "RFKILL switch",
119		.type		= EV_SW,
120		.code		= KEY_RFKILL,
121		.debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL,
122		.gpio		= ARCHER_C7_GPIO_BTN_RFKILL,
123	},
124};
125
126static struct gpio_keys_button archer_c7_v2_gpio_keys[] __initdata = {
127	{
128		.desc		= "Reset button",
129		.type		= EV_KEY,
130		.code		= KEY_WPS_BUTTON,
131		.debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL,
132		.gpio		= ARCHER_C7_GPIO_BTN_RESET,
133		.active_low	= 1,
134	},
135	{
136		.desc		= "RFKILL switch",
137		.type		= EV_SW,
138		.code		= KEY_RFKILL,
139		.debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL,
140		.gpio		= ARCHER_C7_V2_GPIO_BTN_RFKILL,
141	},
142};
143
144static const struct ar8327_led_info archer_c7_leds_ar8327[] __initconst = {
145	AR8327_LED_INFO(PHY0_0, HW, "tp-link:blue:wan"),
146	AR8327_LED_INFO(PHY1_0, HW, "tp-link:blue:lan1"),
147	AR8327_LED_INFO(PHY2_0, HW, "tp-link:blue:lan2"),
148	AR8327_LED_INFO(PHY3_0, HW, "tp-link:blue:lan3"),
149	AR8327_LED_INFO(PHY4_0, HW, "tp-link:blue:lan4"),
150};
151
152/* GMAC0 of the AR8327 switch is connected to the QCA9558 SoC via SGMII */
153static struct ar8327_pad_cfg archer_c7_ar8327_pad0_cfg = {
154	.mode = AR8327_PAD_MAC_SGMII,
155	.sgmii_delay_en = true,
156};
157
158/* GMAC6 of the AR8327 switch is connected to the QCA9558 SoC via RGMII */
159static struct ar8327_pad_cfg archer_c7_ar8327_pad6_cfg = {
160	.mode = AR8327_PAD_MAC_RGMII,
161	.txclk_delay_en = true,
162	.rxclk_delay_en = true,
163	.txclk_delay_sel = AR8327_CLK_DELAY_SEL1,
164	.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2,
165};
166
167static struct ar8327_led_cfg archer_c7_ar8327_led_cfg = {
168	.led_ctrl0 = 0xc737c737,
169	.led_ctrl1 = 0x00000000,
170	.led_ctrl2 = 0x00000000,
171	.led_ctrl3 = 0x0030c300,
172	.open_drain = false,
173};
174
175static struct ar8327_platform_data archer_c7_ar8327_data = {
176	.pad0_cfg = &archer_c7_ar8327_pad0_cfg,
177	.pad6_cfg = &archer_c7_ar8327_pad6_cfg,
178	.port0_cfg = {
179		.force_link = 1,
180		.speed = AR8327_PORT_SPEED_1000,
181		.duplex = 1,
182		.txpause = 1,
183		.rxpause = 1,
184	},
185	.port6_cfg = {
186		.force_link = 1,
187		.speed = AR8327_PORT_SPEED_1000,
188		.duplex = 1,
189		.txpause = 1,
190		.rxpause = 1,
191	},
192	.led_cfg = &archer_c7_ar8327_led_cfg,
193	.num_leds = ARRAY_SIZE(archer_c7_leds_ar8327),
194	.leds = archer_c7_leds_ar8327,
195};
196
197static struct mdio_board_info archer_c7_mdio0_info[] = {
198	{
199		.bus_id = "ag71xx-mdio.0",
200		.phy_addr = 0,
201		.platform_data = &archer_c7_ar8327_data,
202	},
203};
204
205static void __init common_setup(bool pcie_slot)
206{
207	u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
208	u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
209	u8 tmpmac[ETH_ALEN];
210
211	ath79_register_m25p80(&archer_c7_flash_data);
212	ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c7_leds_gpio),
213				 archer_c7_leds_gpio);
214
215	ath79_init_mac(tmpmac, mac, -1);
216	ath79_register_wmac(art + ARCHER_C7_WMAC_CALDATA_OFFSET, tmpmac);
217
218	if (pcie_slot) {
219		ath79_register_pci();
220	} else {
221		ath79_init_mac(tmpmac, mac, -1);
222		ap9x_pci_setup_wmac_led_pin(0, 0);
223		ap91_pci_init(art + ARCHER_C7_PCIE_CALDATA_OFFSET, tmpmac);
224	}
225
226	mdiobus_register_board_info(archer_c7_mdio0_info,
227				    ARRAY_SIZE(archer_c7_mdio0_info));
228	ath79_register_mdio(0, 0x0);
229
230	ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN);
231
232	/* GMAC0 is connected to the RMGII interface */
233	ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
234	ath79_eth0_data.phy_mask = BIT(0);
235	ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
236	ath79_eth0_pll_data.pll_1000 = 0x56000000;
237
238	ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1);
239	ath79_register_eth(0);
240
241	/* GMAC1 is connected to the SGMII interface */
242	ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII;
243	ath79_eth1_data.speed = SPEED_1000;
244	ath79_eth1_data.duplex = DUPLEX_FULL;
245	ath79_eth1_pll_data.pll_1000 = 0x03000101;
246
247	ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0);
248	ath79_register_eth(1);
249
250	gpio_request_one(ARCHER_C7_GPIO_USB1_POWER,
251			 GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED,
252			 "USB1 power");
253	gpio_request_one(ARCHER_C7_GPIO_USB2_POWER,
254			 GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED,
255			 "USB2 power");
256	ath79_register_usb();
257}
258
259static void __init archer_c5_setup(void)
260{
261	ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL,
262					ARRAY_SIZE(archer_c7_gpio_keys),
263					archer_c7_gpio_keys);
264	common_setup(true);
265}
266
267MIPS_MACHINE(ATH79_MACH_ARCHER_C5, "ARCHER-C5", "TP-LINK Archer C5",
268	     archer_c5_setup);
269
270static void __init archer_c7_setup(void)
271{
272	ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL,
273					ARRAY_SIZE(archer_c7_gpio_keys),
274					archer_c7_gpio_keys);
275	common_setup(true);
276}
277
278MIPS_MACHINE(ATH79_MACH_ARCHER_C7, "ARCHER-C7", "TP-LINK Archer C7",
279	     archer_c7_setup);
280
281static void __init archer_c7_v2_setup(void)
282{
283	ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL,
284					ARRAY_SIZE(archer_c7_v2_gpio_keys),
285					archer_c7_v2_gpio_keys);
286	common_setup(true);
287}
288
289MIPS_MACHINE(ATH79_MACH_ARCHER_C7_V2, "ARCHER-C7-V2", "TP-LINK Archer C7",
290	     archer_c7_v2_setup);
291
292static void __init tl_wdr4900_v2_setup(void)
293{
294	ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL,
295					ARRAY_SIZE(archer_c7_gpio_keys),
296					archer_c7_gpio_keys);
297	common_setup(false);
298}
299
300MIPS_MACHINE(ATH79_MACH_TL_WDR4900_V2, "TL-WDR4900-v2", "TP-LINK TL-WDR4900 v2",
301	     tl_wdr4900_v2_setup)
302
303