Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mdio-gpio: Add support for separate MDI and MDO gpio pins

This is for a system with fixed assignments of input and output pins
(various variants of Kontron COMe).

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Guenter Roeck and committed by
David S. Miller
f1d54c47 1d251481

+33 -3
+31 -3
drivers/net/phy/mdio-gpio.c
··· 32 32 33 33 struct mdio_gpio_info { 34 34 struct mdiobb_ctrl ctrl; 35 - int mdc, mdio; 36 - int mdc_active_low, mdio_active_low; 35 + int mdc, mdio, mdo; 36 + int mdc_active_low, mdio_active_low, mdo_active_low; 37 37 }; 38 38 39 39 static void *mdio_gpio_of_get_data(struct platform_device *pdev) ··· 60 60 pdata->mdio = ret; 61 61 pdata->mdio_active_low = flags & OF_GPIO_ACTIVE_LOW; 62 62 63 + ret = of_get_gpio_flags(np, 2, &flags); 64 + if (ret > 0) { 65 + pdata->mdo = ret; 66 + pdata->mdo_active_low = flags & OF_GPIO_ACTIVE_LOW; 67 + } 68 + 63 69 return pdata; 64 70 } 65 71 ··· 73 67 { 74 68 struct mdio_gpio_info *bitbang = 75 69 container_of(ctrl, struct mdio_gpio_info, ctrl); 70 + 71 + if (bitbang->mdo) { 72 + /* Separate output pin. Always set its value to high 73 + * when changing direction. If direction is input, 74 + * assume the pin serves as pull-up. If direction is 75 + * output, the default value is high. 76 + */ 77 + gpio_set_value(bitbang->mdo, 1 ^ bitbang->mdo_active_low); 78 + return; 79 + } 76 80 77 81 if (dir) 78 82 gpio_direction_output(bitbang->mdio, ··· 104 88 struct mdio_gpio_info *bitbang = 105 89 container_of(ctrl, struct mdio_gpio_info, ctrl); 106 90 107 - gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low); 91 + if (bitbang->mdo) 92 + gpio_set_value(bitbang->mdo, what ^ bitbang->mdo_active_low); 93 + else 94 + gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low); 108 95 } 109 96 110 97 static void mdc_set(struct mdiobb_ctrl *ctrl, int what) ··· 144 125 bitbang->mdc_active_low = pdata->mdc_active_low; 145 126 bitbang->mdio = pdata->mdio; 146 127 bitbang->mdio_active_low = pdata->mdio_active_low; 128 + bitbang->mdo = pdata->mdo; 129 + bitbang->mdo_active_low = pdata->mdo_active_low; 147 130 148 131 new_bus = alloc_mdio_bitbang(&bitbang->ctrl); 149 132 if (!new_bus) ··· 171 150 172 151 if (devm_gpio_request(dev, bitbang->mdio, "mdio")) 173 152 goto out_free_bus; 153 + 154 + if (bitbang->mdo) { 155 + if (devm_gpio_request(dev, bitbang->mdo, "mdo")) 156 + goto out_free_bus; 157 + gpio_direction_output(bitbang->mdo, 1); 158 + gpio_direction_input(bitbang->mdio); 159 + } 174 160 175 161 gpio_direction_output(bitbang->mdc, 0); 176 162
+2
include/linux/mdio-gpio.h
··· 17 17 /* GPIO numbers for bus pins */ 18 18 unsigned int mdc; 19 19 unsigned int mdio; 20 + unsigned int mdo; 20 21 21 22 bool mdc_active_low; 22 23 bool mdio_active_low; 24 + bool mdo_active_low; 23 25 24 26 unsigned int phy_mask; 25 27 int irqs[PHY_MAX_ADDR];