2 * GPIO based MDIO bitbang driver.
3 * Supports OpenFirmware.
5 * Copyright (c) 2008 CSE Semaphore Belgium.
6 * by Laurent Pinchart <laurentp@cse-semaphore.com>
8 * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
10 * Based on earlier work by
12 * Copyright (c) 2003 Intracom S.A.
13 * by Pantelis Antoniou <panto@intracom.gr>
15 * 2005 (c) MontaVista Software, Inc.
16 * Vitaly Bordug <vbordug@ru.mvista.com>
18 * This file is licensed under the terms of the GNU General Public License
19 * version 2. This program is licensed "as is" without any warranty of any
20 * kind, whether express or implied.
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/gpio.h>
29 #include <linux/mdio-gpio.h>
31 #include <linux/of_gpio.h>
32 #include <linux/of_mdio.h>
34 struct mdio_gpio_info
{
35 struct mdiobb_ctrl ctrl
;
39 static void *mdio_gpio_of_get_data(struct platform_device
*pdev
)
41 struct device_node
*np
= pdev
->dev
.of_node
;
42 struct mdio_gpio_platform_data
*pdata
;
45 pdata
= devm_kzalloc(&pdev
->dev
, sizeof(*pdata
), GFP_KERNEL
);
49 ret
= of_get_gpio(np
, 0);
55 ret
= of_get_gpio(np
, 1);
63 static void mdio_dir(struct mdiobb_ctrl
*ctrl
, int dir
)
65 struct mdio_gpio_info
*bitbang
=
66 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
69 gpio_direction_output(bitbang
->mdio
, 1);
71 gpio_direction_input(bitbang
->mdio
);
74 static int mdio_get(struct mdiobb_ctrl
*ctrl
)
76 struct mdio_gpio_info
*bitbang
=
77 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
79 return gpio_get_value(bitbang
->mdio
);
82 static void mdio_set(struct mdiobb_ctrl
*ctrl
, int what
)
84 struct mdio_gpio_info
*bitbang
=
85 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
87 gpio_set_value(bitbang
->mdio
, what
);
90 static void mdc_set(struct mdiobb_ctrl
*ctrl
, int what
)
92 struct mdio_gpio_info
*bitbang
=
93 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
95 gpio_set_value(bitbang
->mdc
, what
);
98 static struct mdiobb_ops mdio_gpio_ops
= {
101 .set_mdio_dir
= mdio_dir
,
102 .set_mdio_data
= mdio_set
,
103 .get_mdio_data
= mdio_get
,
106 static struct mii_bus
*mdio_gpio_bus_init(struct device
*dev
,
107 struct mdio_gpio_platform_data
*pdata
,
110 struct mii_bus
*new_bus
;
111 struct mdio_gpio_info
*bitbang
;
114 bitbang
= kzalloc(sizeof(*bitbang
), GFP_KERNEL
);
118 bitbang
->ctrl
.ops
= &mdio_gpio_ops
;
119 bitbang
->ctrl
.reset
= pdata
->reset
;
120 bitbang
->mdc
= pdata
->mdc
;
121 bitbang
->mdio
= pdata
->mdio
;
123 new_bus
= alloc_mdio_bitbang(&bitbang
->ctrl
);
125 goto out_free_bitbang
;
127 new_bus
->name
= "GPIO Bitbanged MDIO",
129 new_bus
->phy_mask
= pdata
->phy_mask
;
130 new_bus
->irq
= pdata
->irqs
;
131 new_bus
->parent
= dev
;
133 if (new_bus
->phy_mask
== ~0)
136 for (i
= 0; i
< PHY_MAX_ADDR
; i
++)
137 if (!new_bus
->irq
[i
])
138 new_bus
->irq
[i
] = PHY_POLL
;
140 snprintf(new_bus
->id
, MII_BUS_ID_SIZE
, "gpio-%x", bus_id
);
142 if (gpio_request(bitbang
->mdc
, "mdc"))
145 if (gpio_request(bitbang
->mdio
, "mdio"))
148 gpio_direction_output(bitbang
->mdc
, 0);
150 dev_set_drvdata(dev
, new_bus
);
155 gpio_free(bitbang
->mdc
);
157 free_mdio_bitbang(new_bus
);
164 static void mdio_gpio_bus_deinit(struct device
*dev
)
166 struct mii_bus
*bus
= dev_get_drvdata(dev
);
167 struct mdio_gpio_info
*bitbang
= bus
->priv
;
169 dev_set_drvdata(dev
, NULL
);
170 gpio_free(bitbang
->mdio
);
171 gpio_free(bitbang
->mdc
);
172 free_mdio_bitbang(bus
);
176 static void mdio_gpio_bus_destroy(struct device
*dev
)
178 struct mii_bus
*bus
= dev_get_drvdata(dev
);
180 mdiobus_unregister(bus
);
181 mdio_gpio_bus_deinit(dev
);
184 static int mdio_gpio_probe(struct platform_device
*pdev
)
186 struct mdio_gpio_platform_data
*pdata
;
187 struct mii_bus
*new_bus
;
190 if (pdev
->dev
.of_node
) {
191 pdata
= mdio_gpio_of_get_data(pdev
);
192 bus_id
= of_alias_get_id(pdev
->dev
.of_node
, "mdio-gpio");
194 pdata
= dev_get_platdata(&pdev
->dev
);
201 new_bus
= mdio_gpio_bus_init(&pdev
->dev
, pdata
, bus_id
);
205 if (pdev
->dev
.of_node
)
206 ret
= of_mdiobus_register(new_bus
, pdev
->dev
.of_node
);
208 ret
= mdiobus_register(new_bus
);
211 mdio_gpio_bus_deinit(&pdev
->dev
);
216 static int mdio_gpio_remove(struct platform_device
*pdev
)
218 mdio_gpio_bus_destroy(&pdev
->dev
);
223 static struct of_device_id mdio_gpio_of_match
[] = {
224 { .compatible
= "virtual,mdio-gpio", },
228 static struct platform_driver mdio_gpio_driver
= {
229 .probe
= mdio_gpio_probe
,
230 .remove
= mdio_gpio_remove
,
233 .owner
= THIS_MODULE
,
234 .of_match_table
= mdio_gpio_of_match
,
238 module_platform_driver(mdio_gpio_driver
);
240 MODULE_ALIAS("platform:mdio-gpio");
241 MODULE_AUTHOR("Laurent Pinchart, Paulius Zaleckas");
242 MODULE_LICENSE("GPL");
243 MODULE_DESCRIPTION("Generic driver for MDIO bus emulation using GPIO");