aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-4.14/209-b44-register-adm-switch.patch
blob: cdeb1f96e927e7c886cce12135855447d433491a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
From b36f694256f41bc71571f467646d015dda128d14 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 9 Nov 2013 17:03:59 +0100
Subject: [PATCH 210/210] b44: register adm switch

---
 drivers/net/ethernet/broadcom/b44.c |   57 +++++++++++++++++++++++++++++++++++
 drivers/net/ethernet/broadcom/b44.h |    3 ++
 2 files changed, 60 insertions(+)

--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -31,6 +31,8 @@
 #include <linux/ssb/ssb.h>
 #include <linux/slab.h>
 #include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/adm6996-gpio.h>
 
 #include <linux/uaccess.h>
 #include <asm/io.h>
@@ -2251,6 +2253,69 @@ static void b44_adjust_link(struct net_d
 	}
 }
 
+#ifdef CONFIG_BCM47XX
+static int b44_register_adm_switch(struct b44 *bp)
+{
+	int gpio;
+	struct platform_device *pdev;
+	struct adm6996_gpio_platform_data adm_data = {0};
+	struct platform_device_info info = {0};
+
+	adm_data.model = ADM6996L;
+	gpio = bcm47xx_nvram_gpio_pin("adm_eecs");
+	if (gpio >= 0)
+		adm_data.eecs = gpio;
+	else
+		adm_data.eecs = 2;
+
+	gpio = bcm47xx_nvram_gpio_pin("adm_eesk");
+	if (gpio >= 0)
+		adm_data.eesk = gpio;
+	else
+		adm_data.eesk = 3;
+
+	gpio = bcm47xx_nvram_gpio_pin("adm_eedi");
+	if (gpio >= 0)
+		adm_data.eedi = gpio;
+	else
+		adm_data.eedi = 4;
+
+	/*
+	 * We ignore the "adm_rc" GPIO here. The driver does not use it,
+	 * and it conflicts with the Reset button GPIO on the Linksys WRT54GSv1.
+	 */
+
+	info.parent = bp->sdev->dev;
+	info.name = "adm6996_gpio";
+	info.id = -1;
+	info.data = &adm_data;
+	info.size_data = sizeof(adm_data);
+
+	if (!bp->adm_switch) {
+		pdev = platform_device_register_full(&info);
+		if (IS_ERR(pdev))
+			return PTR_ERR(pdev);
+
+		bp->adm_switch = pdev;
+	}
+	return 0;
+}
+static void b44_unregister_adm_switch(struct b44 *bp)
+{
+	if (bp->adm_switch)
+		platform_device_unregister(bp->adm_switch);
+}
+#else
+static int b44_register_adm_switch(struct b44 *bp)
+{
+	return 0;
+}
+static void b44_unregister_adm_switch(struct b44 *bp)
+{
+
+}
+#endif /* CONFIG_BCM47XX */
+
 static int b44_register_phy_one(struct b44 *bp)
 {
 	struct mii_bus *mii_bus;
@@ -2286,6 +2351,9 @@ static int b44_register_phy_one(struct b
 	if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
 	    (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
 
+		if (sprom->boardflags_lo & B44_BOARDFLAG_ADM)
+			b44_register_adm_switch(bp);
+
 		dev_info(sdev->dev,
 			 "could not find PHY at %i, use fixed one\n",
 			 bp->phy_addr);
@@ -2480,6 +2548,7 @@ static void b44_remove_one(struct ssb_de
 	unregister_netdev(dev);
 	if (bp->flags & B44_FLAG_EXTERNAL_PHY)
 		b44_unregister_phy_one(bp);
+	b44_unregister_adm_switch(bp);
 	ssb_device_disable(sdev, 0);
 	ssb_bus_may_powerdown(sdev->bus);
 	netif_napi_del(&bp->napi);
--- a/drivers/net/ethernet/broadcom/b44.h
+++ b/drivers/net/ethernet/broadcom/b44.h
@@ -408,6 +408,9 @@ struct b44 {
 	struct mii_bus		*mii_bus;
 	int			old_link;
 	struct mii_if_info	mii_if;
+
+	/* platform device for associated switch */
+	struct platform_device *adm_switch;
 };
 
 #endif /* _B44_H */