aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/ath79
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/ath79')
-rw-r--r--arch/mips/ath79/Kconfig38
-rw-r--r--arch/mips/ath79/Makefile5
-rw-r--r--arch/mips/ath79/clock.c55
-rw-r--r--arch/mips/ath79/common.c5
-rw-r--r--arch/mips/ath79/dev-ar913x-wmac.c60
-rw-r--r--arch/mips/ath79/dev-common.c38
-rw-r--r--arch/mips/ath79/dev-usb.c197
-rw-r--r--arch/mips/ath79/dev-usb.h (renamed from arch/mips/ath79/dev-ar913x-wmac.h)10
-rw-r--r--arch/mips/ath79/dev-wmac.c109
-rw-r--r--arch/mips/ath79/dev-wmac.h17
-rw-r--r--arch/mips/ath79/early_printk.c76
-rw-r--r--arch/mips/ath79/gpio.c2
-rw-r--r--arch/mips/ath79/irq.c17
-rw-r--r--arch/mips/ath79/mach-ap121.c92
-rw-r--r--arch/mips/ath79/mach-ap81.c6
-rw-r--r--arch/mips/ath79/mach-pb44.c2
-rw-r--r--arch/mips/ath79/mach-ubnt-xm.c119
-rw-r--r--arch/mips/ath79/machtypes.h2
-rw-r--r--arch/mips/ath79/setup.c22
19 files changed, 785 insertions, 87 deletions
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 47707410582..e0fae8f4442 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -2,13 +2,26 @@ if ATH79
2 2
3menu "Atheros AR71XX/AR724X/AR913X machine selection" 3menu "Atheros AR71XX/AR724X/AR913X machine selection"
4 4
5config ATH79_MACH_AP121
6 bool "Atheros AP121 reference board"
7 select SOC_AR933X
8 select ATH79_DEV_GPIO_BUTTONS
9 select ATH79_DEV_LEDS_GPIO
10 select ATH79_DEV_SPI
11 select ATH79_DEV_USB
12 select ATH79_DEV_WMAC
13 help
14 Say 'Y' here if you want your kernel to support the
15 Atheros AP121 reference board.
16
5config ATH79_MACH_AP81 17config ATH79_MACH_AP81
6 bool "Atheros AP81 reference board" 18 bool "Atheros AP81 reference board"
7 select SOC_AR913X 19 select SOC_AR913X
8 select ATH79_DEV_AR913X_WMAC
9 select ATH79_DEV_GPIO_BUTTONS 20 select ATH79_DEV_GPIO_BUTTONS
10 select ATH79_DEV_LEDS_GPIO 21 select ATH79_DEV_LEDS_GPIO
11 select ATH79_DEV_SPI 22 select ATH79_DEV_SPI
23 select ATH79_DEV_USB
24 select ATH79_DEV_WMAC
12 help 25 help
13 Say 'Y' here if you want your kernel to support the 26 Say 'Y' here if you want your kernel to support the
14 Atheros AP81 reference board. 27 Atheros AP81 reference board.
@@ -19,10 +32,21 @@ config ATH79_MACH_PB44
19 select ATH79_DEV_GPIO_BUTTONS 32 select ATH79_DEV_GPIO_BUTTONS
20 select ATH79_DEV_LEDS_GPIO 33 select ATH79_DEV_LEDS_GPIO
21 select ATH79_DEV_SPI 34 select ATH79_DEV_SPI
35 select ATH79_DEV_USB
22 help 36 help
23 Say 'Y' here if you want your kernel to support the 37 Say 'Y' here if you want your kernel to support the
24 Atheros PB44 reference board. 38 Atheros PB44 reference board.
25 39
40config ATH79_MACH_UBNT_XM
41 bool "Ubiquiti Networks XM (rev 1.0) board"
42 select SOC_AR724X
43 select ATH79_DEV_GPIO_BUTTONS
44 select ATH79_DEV_LEDS_GPIO
45 select ATH79_DEV_SPI
46 help
47 Say 'Y' here if you want your kernel to support the
48 Ubiquiti Networks XM (rev 1.0) board.
49
26endmenu 50endmenu
27 51
28config SOC_AR71XX 52config SOC_AR71XX
@@ -33,14 +57,15 @@ config SOC_AR71XX
33config SOC_AR724X 57config SOC_AR724X
34 select USB_ARCH_HAS_EHCI 58 select USB_ARCH_HAS_EHCI
35 select USB_ARCH_HAS_OHCI 59 select USB_ARCH_HAS_OHCI
60 select HW_HAS_PCI
36 def_bool n 61 def_bool n
37 62
38config SOC_AR913X 63config SOC_AR913X
39 select USB_ARCH_HAS_EHCI 64 select USB_ARCH_HAS_EHCI
40 def_bool n 65 def_bool n
41 66
42config ATH79_DEV_AR913X_WMAC 67config SOC_AR933X
43 depends on SOC_AR913X 68 select USB_ARCH_HAS_EHCI
44 def_bool n 69 def_bool n
45 70
46config ATH79_DEV_GPIO_BUTTONS 71config ATH79_DEV_GPIO_BUTTONS
@@ -52,4 +77,11 @@ config ATH79_DEV_LEDS_GPIO
52config ATH79_DEV_SPI 77config ATH79_DEV_SPI
53 def_bool n 78 def_bool n
54 79
80config ATH79_DEV_USB
81 def_bool n
82
83config ATH79_DEV_WMAC
84 depends on (SOC_AR913X || SOC_AR933X)
85 def_bool n
86
55endif 87endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index c33d4653007..3b911e09dbe 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,13 +16,16 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
16# Devices 16# Devices
17# 17#
18obj-y += dev-common.o 18obj-y += dev-common.o
19obj-$(CONFIG_ATH79_DEV_AR913X_WMAC) += dev-ar913x-wmac.o
20obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o 19obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
21obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o 20obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
22obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o 21obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o
22obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o
23obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
23 24
24# 25#
25# Machines 26# Machines
26# 27#
28obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
27obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o 29obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
28obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o 30obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
31obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index 680bde99a26..54d0eb4db98 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -110,6 +110,59 @@ static void __init ar913x_clocks_init(void)
110 ath79_uart_clk.rate = ath79_ahb_clk.rate; 110 ath79_uart_clk.rate = ath79_ahb_clk.rate;
111} 111}
112 112
113static void __init ar933x_clocks_init(void)
114{
115 u32 clock_ctrl;
116 u32 cpu_config;
117 u32 freq;
118 u32 t;
119
120 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
121 if (t & AR933X_BOOTSTRAP_REF_CLK_40)
122 ath79_ref_clk.rate = (40 * 1000 * 1000);
123 else
124 ath79_ref_clk.rate = (25 * 1000 * 1000);
125
126 clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
127 if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
128 ath79_cpu_clk.rate = ath79_ref_clk.rate;
129 ath79_ahb_clk.rate = ath79_ref_clk.rate;
130 ath79_ddr_clk.rate = ath79_ref_clk.rate;
131 } else {
132 cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
133
134 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
135 AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
136 freq = ath79_ref_clk.rate / t;
137
138 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
139 AR933X_PLL_CPU_CONFIG_NINT_MASK;
140 freq *= t;
141
142 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
143 AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
144 if (t == 0)
145 t = 1;
146
147 freq >>= t;
148
149 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
150 AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
151 ath79_cpu_clk.rate = freq / t;
152
153 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
154 AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
155 ath79_ddr_clk.rate = freq / t;
156
157 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
158 AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
159 ath79_ahb_clk.rate = freq / t;
160 }
161
162 ath79_wdt_clk.rate = ath79_ref_clk.rate;
163 ath79_uart_clk.rate = ath79_ref_clk.rate;
164}
165
113void __init ath79_clocks_init(void) 166void __init ath79_clocks_init(void)
114{ 167{
115 if (soc_is_ar71xx()) 168 if (soc_is_ar71xx())
@@ -118,6 +171,8 @@ void __init ath79_clocks_init(void)
118 ar724x_clocks_init(); 171 ar724x_clocks_init();
119 else if (soc_is_ar913x()) 172 else if (soc_is_ar913x())
120 ar913x_clocks_init(); 173 ar913x_clocks_init();
174 else if (soc_is_ar933x())
175 ar933x_clocks_init();
121 else 176 else
122 BUG(); 177 BUG();
123 178
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
index 58f60e722a0..f0fda982b96 100644
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -30,6 +30,7 @@ u32 ath79_ddr_freq;
30EXPORT_SYMBOL_GPL(ath79_ddr_freq); 30EXPORT_SYMBOL_GPL(ath79_ddr_freq);
31 31
32enum ath79_soc_type ath79_soc; 32enum ath79_soc_type ath79_soc;
33unsigned int ath79_soc_rev;
33 34
34void __iomem *ath79_pll_base; 35void __iomem *ath79_pll_base;
35void __iomem *ath79_reset_base; 36void __iomem *ath79_reset_base;
@@ -64,6 +65,8 @@ void ath79_device_reset_set(u32 mask)
64 reg = AR724X_RESET_REG_RESET_MODULE; 65 reg = AR724X_RESET_REG_RESET_MODULE;
65 else if (soc_is_ar913x()) 66 else if (soc_is_ar913x())
66 reg = AR913X_RESET_REG_RESET_MODULE; 67 reg = AR913X_RESET_REG_RESET_MODULE;
68 else if (soc_is_ar933x())
69 reg = AR933X_RESET_REG_RESET_MODULE;
67 else 70 else
68 BUG(); 71 BUG();
69 72
@@ -86,6 +89,8 @@ void ath79_device_reset_clear(u32 mask)
86 reg = AR724X_RESET_REG_RESET_MODULE; 89 reg = AR724X_RESET_REG_RESET_MODULE;
87 else if (soc_is_ar913x()) 90 else if (soc_is_ar913x())
88 reg = AR913X_RESET_REG_RESET_MODULE; 91 reg = AR913X_RESET_REG_RESET_MODULE;
92 else if (soc_is_ar933x())
93 reg = AR933X_RESET_REG_RESET_MODULE;
89 else 94 else
90 BUG(); 95 BUG();
91 96
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c
deleted file mode 100644
index 48f425a5ba2..00000000000
--- a/arch/mips/ath79/dev-ar913x-wmac.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * Atheros AR913X SoC built-in WMAC device support
3 *
4 * Copyright (C) 2008-2010 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/init.h>
13#include <linux/delay.h>
14#include <linux/irq.h>
15#include <linux/platform_device.h>
16#include <linux/ath9k_platform.h>
17
18#include <asm/mach-ath79/ath79.h>
19#include <asm/mach-ath79/ar71xx_regs.h>
20#include "dev-ar913x-wmac.h"
21
22static struct ath9k_platform_data ar913x_wmac_data;
23
24static struct resource ar913x_wmac_resources[] = {
25 {
26 .start = AR913X_WMAC_BASE,
27 .end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1,
28 .flags = IORESOURCE_MEM,
29 }, {
30 .start = ATH79_CPU_IRQ_IP2,
31 .end = ATH79_CPU_IRQ_IP2,
32 .flags = IORESOURCE_IRQ,
33 },
34};
35
36static struct platform_device ar913x_wmac_device = {
37 .name = "ath9k",
38 .id = -1,
39 .resource = ar913x_wmac_resources,
40 .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
41 .dev = {
42 .platform_data = &ar913x_wmac_data,
43 },
44};
45
46void __init ath79_register_ar913x_wmac(u8 *cal_data)
47{
48 if (cal_data)
49 memcpy(ar913x_wmac_data.eeprom_data, cal_data,
50 sizeof(ar913x_wmac_data.eeprom_data));
51
52 /* reset the WMAC */
53 ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
54 mdelay(10);
55
56 ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
57 mdelay(10);
58
59 platform_device_register(&ar913x_wmac_device);
60}
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
index 3b82e325beb..f4956f80907 100644
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -20,6 +20,7 @@
20 20
21#include <asm/mach-ath79/ath79.h> 21#include <asm/mach-ath79/ath79.h>
22#include <asm/mach-ath79/ar71xx_regs.h> 22#include <asm/mach-ath79/ar71xx_regs.h>
23#include <asm/mach-ath79/ar933x_uart_platform.h>
23#include "common.h" 24#include "common.h"
24#include "dev-common.h" 25#include "dev-common.h"
25 26
@@ -54,6 +55,30 @@ static struct platform_device ath79_uart_device = {
54 }, 55 },
55}; 56};
56 57
58static struct resource ar933x_uart_resources[] = {
59 {
60 .start = AR933X_UART_BASE,
61 .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1,
62 .flags = IORESOURCE_MEM,
63 },
64 {
65 .start = ATH79_MISC_IRQ_UART,
66 .end = ATH79_MISC_IRQ_UART,
67 .flags = IORESOURCE_IRQ,
68 },
69};
70
71static struct ar933x_uart_platform_data ar933x_uart_data;
72static struct platform_device ar933x_uart_device = {
73 .name = "ar933x-uart",
74 .id = -1,
75 .resource = ar933x_uart_resources,
76 .num_resources = ARRAY_SIZE(ar933x_uart_resources),
77 .dev = {
78 .platform_data = &ar933x_uart_data,
79 },
80};
81
57void __init ath79_register_uart(void) 82void __init ath79_register_uart(void)
58{ 83{
59 struct clk *clk; 84 struct clk *clk;
@@ -62,8 +87,17 @@ void __init ath79_register_uart(void)
62 if (IS_ERR(clk)) 87 if (IS_ERR(clk))
63 panic("unable to get UART clock, err=%ld", PTR_ERR(clk)); 88 panic("unable to get UART clock, err=%ld", PTR_ERR(clk));
64 89
65 ath79_uart_data[0].uartclk = clk_get_rate(clk); 90 if (soc_is_ar71xx() ||
66 platform_device_register(&ath79_uart_device); 91 soc_is_ar724x() ||
92 soc_is_ar913x()) {
93 ath79_uart_data[0].uartclk = clk_get_rate(clk);
94 platform_device_register(&ath79_uart_device);
95 } else if (soc_is_ar933x()) {
96 ar933x_uart_data.uartclk = clk_get_rate(clk);
97 platform_device_register(&ar933x_uart_device);
98 } else {
99 BUG();
100 }
67} 101}
68 102
69static struct platform_device ath79_wdt_device = { 103static struct platform_device ath79_wdt_device = {
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
new file mode 100644
index 00000000000..002d6d2afe0
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.c
@@ -0,0 +1,197 @@
1/*
2 * Atheros AR7XXX/AR9XXX USB Host Controller device
3 *
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/irq.h>
18#include <linux/dma-mapping.h>
19#include <linux/platform_device.h>
20
21#include <asm/mach-ath79/ath79.h>
22#include <asm/mach-ath79/ar71xx_regs.h>
23#include "common.h"
24#include "dev-usb.h"
25
26static struct resource ath79_ohci_resources[] = {
27 [0] = {
28 /* .start and .end fields are filled dynamically */
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = ATH79_MISC_IRQ_OHCI,
33 .end = ATH79_MISC_IRQ_OHCI,
34 .flags = IORESOURCE_IRQ,
35 },
36};
37
38static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
39static struct platform_device ath79_ohci_device = {
40 .name = "ath79-ohci",
41 .id = -1,
42 .resource = ath79_ohci_resources,
43 .num_resources = ARRAY_SIZE(ath79_ohci_resources),
44 .dev = {
45 .dma_mask = &ath79_ohci_dmamask,
46 .coherent_dma_mask = DMA_BIT_MASK(32),
47 },
48};
49
50static struct resource ath79_ehci_resources[] = {
51 [0] = {
52 /* .start and .end fields are filled dynamically */
53 .flags = IORESOURCE_MEM,
54 },
55 [1] = {
56 .start = ATH79_CPU_IRQ_USB,
57 .end = ATH79_CPU_IRQ_USB,
58 .flags = IORESOURCE_IRQ,
59 },
60};
61
62static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
63static struct platform_device ath79_ehci_device = {
64 .name = "ath79-ehci",
65 .id = -1,
66 .resource = ath79_ehci_resources,
67 .num_resources = ARRAY_SIZE(ath79_ehci_resources),
68 .dev = {
69 .dma_mask = &ath79_ehci_dmamask,
70 .coherent_dma_mask = DMA_BIT_MASK(32),
71 },
72};
73
74#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
75 AR71XX_RESET_USB_PHY | \
76 AR71XX_RESET_USB_OHCI_DLL)
77
78static void __init ath79_usb_setup(void)
79{
80 void __iomem *usb_ctrl_base;
81
82 ath79_device_reset_set(AR71XX_USB_RESET_MASK);
83 mdelay(1000);
84 ath79_device_reset_clear(AR71XX_USB_RESET_MASK);
85
86 usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE);
87
88 /* Turning on the Buff and Desc swap bits */
89 __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
90
91 /* WAR for HW bug. Here it adjusts the duration between two SOFS */
92 __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
93
94 iounmap(usb_ctrl_base);
95
96 mdelay(900);
97
98 ath79_ohci_resources[0].start = AR71XX_OHCI_BASE;
99 ath79_ohci_resources[0].end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1;
100 platform_device_register(&ath79_ohci_device);
101
102 ath79_ehci_resources[0].start = AR71XX_EHCI_BASE;
103 ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1;
104 ath79_ehci_device.name = "ar71xx-ehci";
105 platform_device_register(&ath79_ehci_device);
106}
107
108static void __init ar7240_usb_setup(void)
109{
110 void __iomem *usb_ctrl_base;
111
112 ath79_device_reset_clear(AR7240_RESET_OHCI_DLL);
113 ath79_device_reset_set(AR7240_RESET_USB_HOST);
114
115 mdelay(1000);
116
117 ath79_device_reset_set(AR7240_RESET_OHCI_DLL);
118 ath79_device_reset_clear(AR7240_RESET_USB_HOST);
119
120 usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE);
121
122 /* WAR for HW bug. Here it adjusts the duration between two SOFS */
123 __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
124
125 iounmap(usb_ctrl_base);
126
127 ath79_ohci_resources[0].start = AR7240_OHCI_BASE;
128 ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1;
129 platform_device_register(&ath79_ohci_device);
130}
131
132static void __init ar724x_usb_setup(void)
133{
134 ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE);
135 mdelay(10);
136
137 ath79_device_reset_clear(AR724X_RESET_USB_HOST);
138 mdelay(10);
139
140 ath79_device_reset_clear(AR724X_RESET_USB_PHY);
141 mdelay(10);
142
143 ath79_ehci_resources[0].start = AR724X_EHCI_BASE;
144 ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1;
145 ath79_ehci_device.name = "ar724x-ehci";
146 platform_device_register(&ath79_ehci_device);
147}
148
149static void __init ar913x_usb_setup(void)
150{
151 ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE);
152 mdelay(10);
153
154 ath79_device_reset_clear(AR913X_RESET_USB_HOST);
155 mdelay(10);
156
157 ath79_device_reset_clear(AR913X_RESET_USB_PHY);
158 mdelay(10);
159
160 ath79_ehci_resources[0].start = AR913X_EHCI_BASE;
161 ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1;
162 ath79_ehci_device.name = "ar913x-ehci";
163 platform_device_register(&ath79_ehci_device);
164}
165
166static void __init ar933x_usb_setup(void)
167{
168 ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE);
169 mdelay(10);
170
171 ath79_device_reset_clear(AR933X_RESET_USB_HOST);
172 mdelay(10);
173
174 ath79_device_reset_clear(AR933X_RESET_USB_PHY);
175 mdelay(10);
176
177 ath79_ehci_resources[0].start = AR933X_EHCI_BASE;
178 ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1;
179 ath79_ehci_device.name = "ar933x-ehci";
180 platform_device_register(&ath79_ehci_device);
181}
182
183void __init ath79_register_usb(void)
184{
185 if (soc_is_ar71xx())
186 ath79_usb_setup();
187 else if (soc_is_ar7240())
188 ar7240_usb_setup();
189 else if (soc_is_ar7241() || soc_is_ar7242())
190 ar724x_usb_setup();
191 else if (soc_is_ar913x())
192 ar913x_usb_setup();
193 else if (soc_is_ar933x())
194 ar933x_usb_setup();
195 else
196 BUG();
197}
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-usb.h
index 579d562bbda..4b86a69ca08 100644
--- a/arch/mips/ath79/dev-ar913x-wmac.h
+++ b/arch/mips/ath79/dev-usb.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Atheros AR913X SoC built-in WMAC device support 2 * Atheros AR71XX/AR724X/AR913X USB Host Controller support
3 * 3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
@@ -9,9 +9,9 @@
9 * by the Free Software Foundation. 9 * by the Free Software Foundation.
10 */ 10 */
11 11
12#ifndef _ATH79_DEV_AR913X_WMAC_H 12#ifndef _ATH79_DEV_USB_H
13#define _ATH79_DEV_AR913X_WMAC_H 13#define _ATH79_DEV_USB_H
14 14
15void ath79_register_ar913x_wmac(u8 *cal_data); 15void ath79_register_usb(void);
16 16
17#endif /* _ATH79_DEV_AR913X_WMAC_H */ 17#endif /* _ATH79_DEV_USB_H */
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c
new file mode 100644
index 00000000000..24f546985b6
--- /dev/null
+++ b/arch/mips/ath79/dev-wmac.c
@@ -0,0 +1,109 @@
1/*
2 * Atheros AR913X/AR933X SoC built-in WMAC device support
3 *
4 * Copyright (C) 2008-2011 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/init.h>
13#include <linux/delay.h>
14#include <linux/irq.h>
15#include <linux/platform_device.h>
16#include <linux/ath9k_platform.h>
17
18#include <asm/mach-ath79/ath79.h>
19#include <asm/mach-ath79/ar71xx_regs.h>
20#include "dev-wmac.h"
21
22static struct ath9k_platform_data ath79_wmac_data;
23
24static struct resource ath79_wmac_resources[] = {
25 {
26 /* .start and .end fields are filled dynamically */
27 .flags = IORESOURCE_MEM,
28 }, {
29 .start = ATH79_CPU_IRQ_IP2,
30 .end = ATH79_CPU_IRQ_IP2,
31 .flags = IORESOURCE_IRQ,
32 },
33};
34
35static struct platform_device ath79_wmac_device = {
36 .name = "ath9k",
37 .id = -1,
38 .resource = ath79_wmac_resources,
39 .num_resources = ARRAY_SIZE(ath79_wmac_resources),
40 .dev = {
41 .platform_data = &ath79_wmac_data,
42 },
43};
44
45static void __init ar913x_wmac_setup(void)
46{
47 /* reset the WMAC */
48 ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
49 mdelay(10);
50
51 ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
52 mdelay(10);
53
54 ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
55 ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
56}
57
58
59static int ar933x_wmac_reset(void)
60{
61 ath79_device_reset_clear(AR933X_RESET_WMAC);
62 ath79_device_reset_set(AR933X_RESET_WMAC);
63
64 return 0;
65}
66
67static int ar933x_r1_get_wmac_revision(void)
68{
69 return ath79_soc_rev;
70}
71
72static void __init ar933x_wmac_setup(void)
73{
74 u32 t;
75
76 ar933x_wmac_reset();
77
78 ath79_wmac_device.name = "ar933x_wmac";
79
80 ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
81 ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
82
83 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
84 if (t & AR933X_BOOTSTRAP_REF_CLK_40)
85 ath79_wmac_data.is_clk_25mhz = false;
86 else
87 ath79_wmac_data.is_clk_25mhz = true;
88
89 if (ath79_soc_rev == 1)
90 ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision;
91
92 ath79_wmac_data.external_reset = ar933x_wmac_reset;
93}
94
95void __init ath79_register_wmac(u8 *cal_data)
96{
97 if (soc_is_ar913x())
98 ar913x_wmac_setup();
99 if (soc_is_ar933x())
100 ar933x_wmac_setup();
101 else
102 BUG();
103
104 if (cal_data)
105 memcpy(ath79_wmac_data.eeprom_data, cal_data,
106 sizeof(ath79_wmac_data.eeprom_data));
107
108 platform_device_register(&ath79_wmac_device);
109}
diff --git a/arch/mips/ath79/dev-wmac.h b/arch/mips/ath79/dev-wmac.h
new file mode 100644
index 00000000000..c9cd8709f09
--- /dev/null
+++ b/arch/mips/ath79/dev-wmac.h
@@ -0,0 +1,17 @@
1/*
2 * Atheros AR913X/AR933X SoC built-in WMAC device support
3 *
4 * Copyright (C) 2008-2011 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#ifndef _ATH79_DEV_WMAC_H
13#define _ATH79_DEV_WMAC_H
14
15void ath79_register_wmac(u8 *cal_data);
16
17#endif /* _ATH79_DEV_WMAC_H */
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
index 7499b0e9df2..6a51ced7a29 100644
--- a/arch/mips/ath79/early_printk.c
+++ b/arch/mips/ath79/early_printk.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Atheros AR71XX/AR724X/AR913X SoC early printk support 2 * Atheros AR7XXX/AR9XXX SoC early printk support
3 * 3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -10,27 +10,85 @@
10 */ 10 */
11 11
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/errno.h>
13#include <linux/serial_reg.h> 14#include <linux/serial_reg.h>
14#include <asm/addrspace.h> 15#include <asm/addrspace.h>
15 16
17#include <asm/mach-ath79/ath79.h>
16#include <asm/mach-ath79/ar71xx_regs.h> 18#include <asm/mach-ath79/ar71xx_regs.h>
19#include <asm/mach-ath79/ar933x_uart.h>
17 20
18static inline void prom_wait_thre(void __iomem *base) 21static void (*_prom_putchar) (unsigned char);
22
23static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
19{ 24{
20 u32 lsr; 25 u32 t;
21 26
22 do { 27 do {
23 lsr = __raw_readl(base + UART_LSR * 4); 28 t = __raw_readl(reg);
24 if (lsr & UART_LSR_THRE) 29 if ((t & mask) == val)
25 break; 30 break;
26 } while (1); 31 } while (1);
27} 32}
28 33
29void prom_putchar(unsigned char ch) 34static void prom_putchar_ar71xx(unsigned char ch)
30{ 35{
31 void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); 36 void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
32 37
33 prom_wait_thre(base); 38 prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
34 __raw_writel(ch, base + UART_TX * 4); 39 __raw_writel(ch, base + UART_TX * 4);
35 prom_wait_thre(base); 40 prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
41}
42
43static void prom_putchar_ar933x(unsigned char ch)
44{
45 void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE));
46
47 prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
48 AR933X_UART_DATA_TX_CSR);
49 __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG);
50 prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
51 AR933X_UART_DATA_TX_CSR);
52}
53
54static void prom_putchar_dummy(unsigned char ch)
55{
56 /* nothing to do */
57}
58
59static void prom_putchar_init(void)
60{
61 void __iomem *base;
62 u32 id;
63
64 base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE));
65 id = __raw_readl(base + AR71XX_RESET_REG_REV_ID);
66 id &= REV_ID_MAJOR_MASK;
67
68 switch (id) {
69 case REV_ID_MAJOR_AR71XX:
70 case REV_ID_MAJOR_AR7240:
71 case REV_ID_MAJOR_AR7241:
72 case REV_ID_MAJOR_AR7242:
73 case REV_ID_MAJOR_AR913X:
74 _prom_putchar = prom_putchar_ar71xx;
75 break;
76
77 case REV_ID_MAJOR_AR9330:
78 case REV_ID_MAJOR_AR9331:
79 _prom_putchar = prom_putchar_ar933x;
80 break;
81
82 default:
83 _prom_putchar = prom_putchar_dummy;
84 break;
85 }
86}
87
88void prom_putchar(unsigned char ch)
89{
90 if (!_prom_putchar)
91 prom_putchar_init();
92
93 _prom_putchar(ch);
36} 94}
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
index a0c426b8212..a2f8ca630ed 100644
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -153,6 +153,8 @@ void __init ath79_gpio_init(void)
153 ath79_gpio_count = AR724X_GPIO_COUNT; 153 ath79_gpio_count = AR724X_GPIO_COUNT;
154 else if (soc_is_ar913x()) 154 else if (soc_is_ar913x())
155 ath79_gpio_count = AR913X_GPIO_COUNT; 155 ath79_gpio_count = AR913X_GPIO_COUNT;
156 else if (soc_is_ar933x())
157 ath79_gpio_count = AR933X_GPIO_COUNT;
156 else 158 else
157 BUG(); 159 BUG();
158 160
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index ac610d5fe3b..1b073de4468 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -46,6 +46,15 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
46 else if (pending & MISC_INT_TIMER) 46 else if (pending & MISC_INT_TIMER)
47 generic_handle_irq(ATH79_MISC_IRQ_TIMER); 47 generic_handle_irq(ATH79_MISC_IRQ_TIMER);
48 48
49 else if (pending & MISC_INT_TIMER2)
50 generic_handle_irq(ATH79_MISC_IRQ_TIMER2);
51
52 else if (pending & MISC_INT_TIMER3)
53 generic_handle_irq(ATH79_MISC_IRQ_TIMER3);
54
55 else if (pending & MISC_INT_TIMER4)
56 generic_handle_irq(ATH79_MISC_IRQ_TIMER4);
57
49 else if (pending & MISC_INT_OHCI) 58 else if (pending & MISC_INT_OHCI)
50 generic_handle_irq(ATH79_MISC_IRQ_OHCI); 59 generic_handle_irq(ATH79_MISC_IRQ_OHCI);
51 60
@@ -58,6 +67,9 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
58 else if (pending & MISC_INT_WDOG) 67 else if (pending & MISC_INT_WDOG)
59 generic_handle_irq(ATH79_MISC_IRQ_WDOG); 68 generic_handle_irq(ATH79_MISC_IRQ_WDOG);
60 69
70 else if (pending & MISC_INT_ETHSW)
71 generic_handle_irq(ATH79_MISC_IRQ_ETHSW);
72
61 else 73 else
62 spurious_interrupt(); 74 spurious_interrupt();
63} 75}
@@ -117,7 +129,7 @@ static void __init ath79_misc_irq_init(void)
117 129
118 if (soc_is_ar71xx() || soc_is_ar913x()) 130 if (soc_is_ar71xx() || soc_is_ar913x())
119 ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; 131 ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
120 else if (soc_is_ar724x()) 132 else if (soc_is_ar724x() || soc_is_ar933x())
121 ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; 133 ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
122 else 134 else
123 BUG(); 135 BUG();
@@ -174,6 +186,9 @@ void __init arch_init_irq(void)
174 } else if (soc_is_ar913x()) { 186 } else if (soc_is_ar913x()) {
175 ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC; 187 ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
176 ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB; 188 ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
189 } else if (soc_is_ar933x()) {
190 ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC;
191 ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB;
177 } else 192 } else
178 BUG(); 193 BUG();
179 194
diff --git a/arch/mips/ath79/mach-ap121.c b/arch/mips/ath79/mach-ap121.c
new file mode 100644
index 00000000000..4c20200d7c7
--- /dev/null
+++ b/arch/mips/ath79/mach-ap121.c
@@ -0,0 +1,92 @@
1/*
2 * Atheros AP121 board support
3 *
4 * Copyright (C) 2011 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 "machtypes.h"
12#include "dev-gpio-buttons.h"
13#include "dev-leds-gpio.h"
14#include "dev-spi.h"
15#include "dev-usb.h"
16#include "dev-wmac.h"
17
18#define AP121_GPIO_LED_WLAN 0
19#define AP121_GPIO_LED_USB 1
20
21#define AP121_GPIO_BTN_JUMPSTART 11
22#define AP121_GPIO_BTN_RESET 12
23
24#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */
25#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL)
26
27#define AP121_CAL_DATA_ADDR 0x1fff1000
28
29static struct gpio_led ap121_leds_gpio[] __initdata = {
30 {
31 .name = "ap121:green:usb",
32 .gpio = AP121_GPIO_LED_USB,
33 .active_low = 0,
34 },
35 {
36 .name = "ap121:green:wlan",
37 .gpio = AP121_GPIO_LED_WLAN,
38 .active_low = 0,
39 },
40};
41
42static struct gpio_keys_button ap121_gpio_keys[] __initdata = {
43 {
44 .desc = "jumpstart button",
45 .type = EV_KEY,
46 .code = KEY_WPS_BUTTON,
47 .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
48 .gpio = AP121_GPIO_BTN_JUMPSTART,
49 .active_low = 1,
50 },
51 {
52 .desc = "reset button",
53 .type = EV_KEY,
54 .code = KEY_RESTART,
55 .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
56 .gpio = AP121_GPIO_BTN_RESET,
57 .active_low = 1,
58 }
59};
60
61static struct spi_board_info ap121_spi_info[] = {
62 {
63 .bus_num = 0,
64 .chip_select = 0,
65 .max_speed_hz = 25000000,
66 .modalias = "mx25l1606e",
67 }
68};
69
70static struct ath79_spi_platform_data ap121_spi_data = {
71 .bus_num = 0,
72 .num_chipselect = 1,
73};
74
75static void __init ap121_setup(void)
76{
77 u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR);
78
79 ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio),
80 ap121_leds_gpio);
81 ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
82 ARRAY_SIZE(ap121_gpio_keys),
83 ap121_gpio_keys);
84
85 ath79_register_spi(&ap121_spi_data, ap121_spi_info,
86 ARRAY_SIZE(ap121_spi_info));
87 ath79_register_usb();
88 ath79_register_wmac(cal_data);
89}
90
91MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board",
92 ap121_setup);
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
index eee4c121deb..abe19836331 100644
--- a/arch/mips/ath79/mach-ap81.c
+++ b/arch/mips/ath79/mach-ap81.c
@@ -10,10 +10,11 @@
10 */ 10 */
11 11
12#include "machtypes.h" 12#include "machtypes.h"
13#include "dev-ar913x-wmac.h" 13#include "dev-wmac.h"
14#include "dev-gpio-buttons.h" 14#include "dev-gpio-buttons.h"
15#include "dev-leds-gpio.h" 15#include "dev-leds-gpio.h"
16#include "dev-spi.h" 16#include "dev-spi.h"
17#include "dev-usb.h"
17 18
18#define AP81_GPIO_LED_STATUS 1 19#define AP81_GPIO_LED_STATUS 1
19#define AP81_GPIO_LED_AOSS 3 20#define AP81_GPIO_LED_AOSS 3
@@ -91,7 +92,8 @@ static void __init ap81_setup(void)
91 ap81_gpio_keys); 92 ap81_gpio_keys);
92 ath79_register_spi(&ap81_spi_data, ap81_spi_info, 93 ath79_register_spi(&ap81_spi_data, ap81_spi_info,
93 ARRAY_SIZE(ap81_spi_info)); 94 ARRAY_SIZE(ap81_spi_info));
94 ath79_register_ar913x_wmac(cal_data); 95 ath79_register_wmac(cal_data);
96 ath79_register_usb();
95} 97}
96 98
97MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board", 99MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ec7b7a135d5..fe9701a3229 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -18,6 +18,7 @@
18#include "dev-gpio-buttons.h" 18#include "dev-gpio-buttons.h"
19#include "dev-leds-gpio.h" 19#include "dev-leds-gpio.h"
20#include "dev-spi.h" 20#include "dev-spi.h"
21#include "dev-usb.h"
21 22
22#define PB44_GPIO_I2C_SCL 0 23#define PB44_GPIO_I2C_SCL 0
23#define PB44_GPIO_I2C_SDA 1 24#define PB44_GPIO_I2C_SDA 1
@@ -112,6 +113,7 @@ static void __init pb44_init(void)
112 pb44_gpio_keys); 113 pb44_gpio_keys);
113 ath79_register_spi(&pb44_spi_data, pb44_spi_info, 114 ath79_register_spi(&pb44_spi_data, pb44_spi_info,
114 ARRAY_SIZE(pb44_spi_info)); 115 ARRAY_SIZE(pb44_spi_info));
116 ath79_register_usb();
115} 117}
116 118
117MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", 119MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
new file mode 100644
index 00000000000..3c311a53934
--- /dev/null
+++ b/arch/mips/ath79/mach-ubnt-xm.c
@@ -0,0 +1,119 @@
1/*
2 * Ubiquiti Networks XM (rev 1.0) board support
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 *
6 * Derived from: mach-pb44.c
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/pci.h>
15
16#ifdef CONFIG_PCI
17#include <linux/ath9k_platform.h>
18#include <asm/mach-ath79/pci-ath724x.h>
19#endif /* CONFIG_PCI */
20
21#include "machtypes.h"
22#include "dev-gpio-buttons.h"
23#include "dev-leds-gpio.h"
24#include "dev-spi.h"
25
26#define UBNT_XM_GPIO_LED_L1 0
27#define UBNT_XM_GPIO_LED_L2 1
28#define UBNT_XM_GPIO_LED_L3 11
29#define UBNT_XM_GPIO_LED_L4 7
30
31#define UBNT_XM_GPIO_BTN_RESET 12
32
33#define UBNT_XM_KEYS_POLL_INTERVAL 20
34#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL)
35
36#define UBNT_XM_PCI_IRQ 48
37#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000)
38
39static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
40 {
41 .name = "ubnt-xm:red:link1",
42 .gpio = UBNT_XM_GPIO_LED_L1,
43 .active_low = 0,
44 }, {
45 .name = "ubnt-xm:orange:link2",
46 .gpio = UBNT_XM_GPIO_LED_L2,
47 .active_low = 0,
48 }, {
49 .name = "ubnt-xm:green:link3",
50 .gpio = UBNT_XM_GPIO_LED_L3,
51 .active_low = 0,
52 }, {
53 .name = "ubnt-xm:green:link4",
54 .gpio = UBNT_XM_GPIO_LED_L4,
55 .active_low = 0,
56 },
57};
58
59static struct gpio_keys_button ubnt_xm_gpio_keys[] __initdata = {
60 {
61 .desc = "reset",
62 .type = EV_KEY,
63 .code = KEY_RESTART,
64 .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL,
65 .gpio = UBNT_XM_GPIO_BTN_RESET,
66 .active_low = 1,
67 }
68};
69
70static struct spi_board_info ubnt_xm_spi_info[] = {
71 {
72 .bus_num = 0,
73 .chip_select = 0,
74 .max_speed_hz = 25000000,
75 .modalias = "mx25l6405d",
76 }
77};
78
79static struct ath79_spi_platform_data ubnt_xm_spi_data = {
80 .bus_num = 0,
81 .num_chipselect = 1,
82};
83
84#ifdef CONFIG_PCI
85static struct ath9k_platform_data ubnt_xm_eeprom_data;
86
87static struct ath724x_pci_data ubnt_xm_pci_data[] = {
88 {
89 .irq = UBNT_XM_PCI_IRQ,
90 .pdata = &ubnt_xm_eeprom_data,
91 },
92};
93#endif /* CONFIG_PCI */
94
95static void __init ubnt_xm_init(void)
96{
97 ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio),
98 ubnt_xm_leds_gpio);
99
100 ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
101 ARRAY_SIZE(ubnt_xm_gpio_keys),
102 ubnt_xm_gpio_keys);
103
104 ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
105 ARRAY_SIZE(ubnt_xm_spi_info));
106
107#ifdef CONFIG_PCI
108 memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
109 sizeof(ubnt_xm_eeprom_data.eeprom_data));
110
111 ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
112#endif /* CONFIG_PCI */
113
114}
115
116MIPS_MACHINE(ATH79_MACH_UBNT_XM,
117 "UBNT-XM",
118 "Ubiquiti Networks XM (rev 1.0) board",
119 ubnt_xm_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index 3940fe470b2..9a1f3826626 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,8 +16,10 @@
16 16
17enum ath79_mach_type { 17enum ath79_mach_type {
18 ATH79_MACH_GENERIC = 0, 18 ATH79_MACH_GENERIC = 0,
19 ATH79_MACH_AP121, /* Atheros AP121 reference board */
19 ATH79_MACH_AP81, /* Atheros AP81 reference board */ 20 ATH79_MACH_AP81, /* Atheros AP81 reference board */
20 ATH79_MACH_PB44, /* Atheros PB44 reference board */ 21 ATH79_MACH_PB44, /* Atheros PB44 reference board */
22 ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */
21}; 23};
22 24
23#endif /* _ATH79_MACHTYPE_H */ 25#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 159b42f106b..80a7d4023d7 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -101,19 +101,31 @@ static void __init ath79_detect_sys_type(void)
101 case REV_ID_MAJOR_AR7240: 101 case REV_ID_MAJOR_AR7240:
102 ath79_soc = ATH79_SOC_AR7240; 102 ath79_soc = ATH79_SOC_AR7240;
103 chip = "7240"; 103 chip = "7240";
104 rev = (id & AR724X_REV_ID_REVISION_MASK); 104 rev = id & AR724X_REV_ID_REVISION_MASK;
105 break; 105 break;
106 106
107 case REV_ID_MAJOR_AR7241: 107 case REV_ID_MAJOR_AR7241:
108 ath79_soc = ATH79_SOC_AR7241; 108 ath79_soc = ATH79_SOC_AR7241;
109 chip = "7241"; 109 chip = "7241";
110 rev = (id & AR724X_REV_ID_REVISION_MASK); 110 rev = id & AR724X_REV_ID_REVISION_MASK;
111 break; 111 break;
112 112
113 case REV_ID_MAJOR_AR7242: 113 case REV_ID_MAJOR_AR7242:
114 ath79_soc = ATH79_SOC_AR7242; 114 ath79_soc = ATH79_SOC_AR7242;
115 chip = "7242"; 115 chip = "7242";
116 rev = (id & AR724X_REV_ID_REVISION_MASK); 116 rev = id & AR724X_REV_ID_REVISION_MASK;
117 break;
118
119 case REV_ID_MAJOR_AR9330:
120 ath79_soc = ATH79_SOC_AR9330;
121 chip = "9330";
122 rev = id & AR933X_REV_ID_REVISION_MASK;
123 break;
124
125 case REV_ID_MAJOR_AR9331:
126 ath79_soc = ATH79_SOC_AR9331;
127 chip = "9331";
128 rev = id & AR933X_REV_ID_REVISION_MASK;
117 break; 129 break;
118 130
119 case REV_ID_MAJOR_AR913X: 131 case REV_ID_MAJOR_AR913X:
@@ -134,9 +146,11 @@ static void __init ath79_detect_sys_type(void)
134 break; 146 break;
135 147
136 default: 148 default:
137 panic("ath79: unknown SoC, id:0x%08x\n", id); 149 panic("ath79: unknown SoC, id:0x%08x", id);
138 } 150 }
139 151
152 ath79_soc_rev = rev;
153
140 sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); 154 sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
141 pr_info("SoC: %s\n", ath79_sys_type); 155 pr_info("SoC: %s\n", ath79_sys_type);
142} 156}