brcm47xx: resolve GPIO conflict for WRT54GSv1
[openwrt/openwrt.git] / target / linux / brcm47xx / patches-4.4 / 209-b44-register-adm-switch.patch
1 From b36f694256f41bc71571f467646d015dda128d14 Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Sat, 9 Nov 2013 17:03:59 +0100
4 Subject: [PATCH 210/210] b44: register adm switch
5
6 ---
7 drivers/net/ethernet/broadcom/b44.c | 57 +++++++++++++++++++++++++++++++++++
8 drivers/net/ethernet/broadcom/b44.h | 3 ++
9 2 files changed, 60 insertions(+)
10
11 --- a/drivers/net/ethernet/broadcom/b44.c
12 +++ b/drivers/net/ethernet/broadcom/b44.c
13 @@ -31,6 +31,8 @@
14 #include <linux/ssb/ssb.h>
15 #include <linux/slab.h>
16 #include <linux/phy.h>
17 +#include <linux/platform_device.h>
18 +#include <linux/platform_data/adm6996-gpio.h>
19
20 #include <asm/uaccess.h>
21 #include <asm/io.h>
22 @@ -2240,6 +2242,69 @@ static void b44_adjust_link(struct net_d
23 }
24 }
25
26 +#ifdef CONFIG_BCM47XX
27 +static int b44_register_adm_switch(struct b44 *bp)
28 +{
29 + int gpio;
30 + struct platform_device *pdev;
31 + struct adm6996_gpio_platform_data adm_data = {0};
32 + struct platform_device_info info = {0};
33 +
34 + adm_data.model = ADM6996L;
35 + gpio = bcm47xx_nvram_gpio_pin("adm_eecs");
36 + if (gpio >= 0)
37 + adm_data.eecs = gpio;
38 + else
39 + adm_data.eecs = 2;
40 +
41 + gpio = bcm47xx_nvram_gpio_pin("adm_eesk");
42 + if (gpio >= 0)
43 + adm_data.eesk = gpio;
44 + else
45 + adm_data.eesk = 3;
46 +
47 + gpio = bcm47xx_nvram_gpio_pin("adm_eedi");
48 + if (gpio >= 0)
49 + adm_data.eedi = gpio;
50 + else
51 + adm_data.eedi = 4;
52 +
53 + /*
54 + * We ignore the "adm_rc" GPIO here. The driver does not use it,
55 + * and it conflicts with the Reset button GPIO on the Linksys WRT54GSv1.
56 + */
57 +
58 + info.parent = bp->sdev->dev;
59 + info.name = "adm6996_gpio";
60 + info.id = -1;
61 + info.data = &adm_data;
62 + info.size_data = sizeof(adm_data);
63 +
64 + if (!bp->adm_switch) {
65 + pdev = platform_device_register_full(&info);
66 + if (IS_ERR(pdev))
67 + return PTR_ERR(pdev);
68 +
69 + bp->adm_switch = pdev;
70 + }
71 + return 0;
72 +}
73 +static void b44_unregister_adm_switch(struct b44 *bp)
74 +{
75 + if (bp->adm_switch)
76 + platform_device_unregister(bp->adm_switch);
77 +}
78 +#else
79 +static int b44_register_adm_switch(struct b44 *bp)
80 +{
81 + return 0;
82 +}
83 +static void b44_unregister_adm_switch(struct b44 *bp)
84 +{
85 +
86 +}
87 +#endif /* CONFIG_BCM47XX */
88 +
89 static int b44_register_phy_one(struct b44 *bp)
90 {
91 struct mii_bus *mii_bus;
92 @@ -2283,6 +2348,9 @@ static int b44_register_phy_one(struct b
93 if (!bp->mii_bus->phy_map[bp->phy_addr] &&
94 (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
95
96 + if (sprom->boardflags_lo & B44_BOARDFLAG_ADM)
97 + b44_register_adm_switch(bp);
98 +
99 dev_info(sdev->dev,
100 "could not find PHY at %i, use fixed one\n",
101 bp->phy_addr);
102 @@ -2479,6 +2547,7 @@ static void b44_remove_one(struct ssb_de
103 unregister_netdev(dev);
104 if (bp->flags & B44_FLAG_EXTERNAL_PHY)
105 b44_unregister_phy_one(bp);
106 + b44_unregister_adm_switch(bp);
107 ssb_device_disable(sdev, 0);
108 ssb_bus_may_powerdown(sdev->bus);
109 netif_napi_del(&bp->napi);
110 --- a/drivers/net/ethernet/broadcom/b44.h
111 +++ b/drivers/net/ethernet/broadcom/b44.h
112 @@ -408,6 +408,9 @@ struct b44 {
113 struct mii_bus *mii_bus;
114 int old_link;
115 struct mii_if_info mii_if;
116 +
117 + /* platform device for associated switch */
118 + struct platform_device *adm_switch;
119 };
120
121 #endif /* _B44_H */