Lines Matching +full:gpio +full:- +full:ctrl
1 // SPDX-License-Identifier: GPL-2.0
3 * GPIO based MDIO bitbang driver.
7 * by Laurent Pinchart <laurentp@cse-semaphore.com>
20 #include <linux/gpio/consumer.h>
22 #include <linux/mdio-bitbang.h>
23 #include <linux/mdio-gpio.h>
26 #include <linux/platform_data/mdio-gpio.h>
31 struct mdiobb_ctrl ctrl; member
38 bitbang->mdc = devm_gpiod_get_index(dev, NULL, MDIO_GPIO_MDC, in mdio_gpio_get_data()
40 if (IS_ERR(bitbang->mdc)) in mdio_gpio_get_data()
41 return PTR_ERR(bitbang->mdc); in mdio_gpio_get_data()
43 bitbang->mdio = devm_gpiod_get_index(dev, NULL, MDIO_GPIO_MDIO, in mdio_gpio_get_data()
45 if (IS_ERR(bitbang->mdio)) in mdio_gpio_get_data()
46 return PTR_ERR(bitbang->mdio); in mdio_gpio_get_data()
48 bitbang->mdo = devm_gpiod_get_index_optional(dev, NULL, MDIO_GPIO_MDO, in mdio_gpio_get_data()
50 return PTR_ERR_OR_ZERO(bitbang->mdo); in mdio_gpio_get_data()
53 static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) in mdio_dir() argument
56 container_of(ctrl, struct mdio_gpio_info, ctrl); in mdio_dir()
58 if (bitbang->mdo) { in mdio_dir()
61 * assume the pin serves as pull-up. If direction is in mdio_dir()
64 gpiod_set_value_cansleep(bitbang->mdo, 1); in mdio_dir()
69 gpiod_direction_output(bitbang->mdio, 1); in mdio_dir()
71 gpiod_direction_input(bitbang->mdio); in mdio_dir()
74 static int mdio_get(struct mdiobb_ctrl *ctrl) in mdio_get() argument
77 container_of(ctrl, struct mdio_gpio_info, ctrl); in mdio_get()
79 return gpiod_get_value_cansleep(bitbang->mdio); in mdio_get()
82 static void mdio_set(struct mdiobb_ctrl *ctrl, int what) in mdio_set() argument
85 container_of(ctrl, struct mdio_gpio_info, ctrl); in mdio_set()
87 if (bitbang->mdo) in mdio_set()
88 gpiod_set_value_cansleep(bitbang->mdo, what); in mdio_set()
90 gpiod_set_value_cansleep(bitbang->mdio, what); in mdio_set()
93 static void mdc_set(struct mdiobb_ctrl *ctrl, int what) in mdc_set() argument
96 container_of(ctrl, struct mdio_gpio_info, ctrl); in mdc_set()
98 gpiod_set_value_cansleep(bitbang->mdc, what); in mdc_set()
116 bitbang->ctrl.ops = &mdio_gpio_ops; in mdio_gpio_bus_init()
118 new_bus = alloc_mdio_bitbang(&bitbang->ctrl); in mdio_gpio_bus_init()
122 new_bus->name = "GPIO Bitbanged MDIO"; in mdio_gpio_bus_init()
123 new_bus->parent = dev; in mdio_gpio_bus_init()
125 if (bus_id != -1) in mdio_gpio_bus_init()
126 snprintf(new_bus->id, sizeof(new_bus->id), "gpio-%x", bus_id); in mdio_gpio_bus_init()
128 strscpy(new_bus->id, "gpio", sizeof(new_bus->id)); in mdio_gpio_bus_init()
131 new_bus->phy_mask = pdata->phy_mask; in mdio_gpio_bus_init()
132 new_bus->phy_ignore_ta_mask = pdata->phy_ignore_ta_mask; in mdio_gpio_bus_init()
135 if (device_is_compatible(dev, "microchip,mdio-smi0")) { in mdio_gpio_bus_init()
136 bitbang->ctrl.op_c22_read = 0; in mdio_gpio_bus_init()
137 bitbang->ctrl.op_c22_write = 0; in mdio_gpio_bus_init()
138 bitbang->ctrl.override_op_c22 = 1; in mdio_gpio_bus_init()
167 bitbang = devm_kzalloc(&pdev->dev, sizeof(*bitbang), GFP_KERNEL); in mdio_gpio_probe()
169 return -ENOMEM; in mdio_gpio_probe()
171 ret = mdio_gpio_get_data(&pdev->dev, bitbang); in mdio_gpio_probe()
175 if (pdev->dev.of_node) { in mdio_gpio_probe()
176 bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); in mdio_gpio_probe()
178 dev_warn(&pdev->dev, "failed to get alias id\n"); in mdio_gpio_probe()
182 bus_id = pdev->id; in mdio_gpio_probe()
185 new_bus = mdio_gpio_bus_init(&pdev->dev, bitbang, bus_id); in mdio_gpio_probe()
187 return -ENODEV; in mdio_gpio_probe()
189 ret = of_mdiobus_register(new_bus, pdev->dev.of_node); in mdio_gpio_probe()
191 mdio_gpio_bus_deinit(&pdev->dev); in mdio_gpio_probe()
198 mdio_gpio_bus_destroy(&pdev->dev); in mdio_gpio_remove()
202 { .compatible = "virtual,mdio-gpio", },
203 { .compatible = "microchip,mdio-smi0" },
212 .name = "mdio-gpio",
219 MODULE_ALIAS("platform:mdio-gpio");
222 MODULE_DESCRIPTION("Generic driver for MDIO bus emulation using GPIO");