Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d251481 authored by Guenter Roeck's avatar Guenter Roeck Committed by David S. Miller
Browse files

net: mdio-gpio: Add support for active low gpio pins



Some systems using mdio-gpio may use active-low gpio pins
(eg with inverters or FETs connected to all or some of the
gpio pins).

Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 78cdb079
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -33,28 +33,32 @@
struct mdio_gpio_info {
	struct mdiobb_ctrl ctrl;
	int mdc, mdio;
	int mdc_active_low, mdio_active_low;
};

static void *mdio_gpio_of_get_data(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct mdio_gpio_platform_data *pdata;
	enum of_gpio_flags flags;
	int ret;

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return NULL;

	ret = of_get_gpio(np, 0);
	ret = of_get_gpio_flags(np, 0, &flags);
	if (ret < 0)
		return NULL;

	pdata->mdc = ret;
	pdata->mdc_active_low = flags & OF_GPIO_ACTIVE_LOW;

	ret = of_get_gpio(np, 1);
	ret = of_get_gpio_flags(np, 1, &flags);
	if (ret < 0)
		return NULL;
	pdata->mdio = ret;
	pdata->mdio_active_low = flags & OF_GPIO_ACTIVE_LOW;

	return pdata;
}
@@ -65,7 +69,8 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
		container_of(ctrl, struct mdio_gpio_info, ctrl);

	if (dir)
		gpio_direction_output(bitbang->mdio, 1);
		gpio_direction_output(bitbang->mdio,
				      1 ^ bitbang->mdio_active_low);
	else
		gpio_direction_input(bitbang->mdio);
}
@@ -75,7 +80,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl)
	struct mdio_gpio_info *bitbang =
		container_of(ctrl, struct mdio_gpio_info, ctrl);

	return gpio_get_value(bitbang->mdio);
	return gpio_get_value(bitbang->mdio) ^ bitbang->mdio_active_low;
}

static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
@@ -83,7 +88,7 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
	struct mdio_gpio_info *bitbang =
		container_of(ctrl, struct mdio_gpio_info, ctrl);

	gpio_set_value(bitbang->mdio, what);
	gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low);
}

static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
@@ -91,7 +96,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
	struct mdio_gpio_info *bitbang =
		container_of(ctrl, struct mdio_gpio_info, ctrl);

	gpio_set_value(bitbang->mdc, what);
	gpio_set_value(bitbang->mdc, what ^ bitbang->mdc_active_low);
}

static struct mdiobb_ops mdio_gpio_ops = {
@@ -117,7 +122,9 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
	bitbang->ctrl.ops = &mdio_gpio_ops;
	bitbang->ctrl.reset = pdata->reset;
	bitbang->mdc = pdata->mdc;
	bitbang->mdc_active_low = pdata->mdc_active_low;
	bitbang->mdio = pdata->mdio;
	bitbang->mdio_active_low = pdata->mdio_active_low;

	new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
	if (!new_bus)
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ struct mdio_gpio_platform_data {
	unsigned int mdc;
	unsigned int mdio;

	bool mdc_active_low;
	bool mdio_active_low;

	unsigned int phy_mask;
	int irqs[PHY_MAX_ADDR];
	/* reset callback */