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>
32 #include <linux/of_gpio.h>
33 #include <linux/of_mdio.h>
34 #include <linux/of_platform.h>
37 struct mdio_gpio_info
{
38 struct mdiobb_ctrl ctrl
;
42 static void mdio_dir(struct mdiobb_ctrl
*ctrl
, int dir
)
44 struct mdio_gpio_info
*bitbang
=
45 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
48 gpio_direction_output(bitbang
->mdio
, 1);
50 gpio_direction_input(bitbang
->mdio
);
53 static int mdio_get(struct mdiobb_ctrl
*ctrl
)
55 struct mdio_gpio_info
*bitbang
=
56 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
58 return gpio_get_value(bitbang
->mdio
);
61 static void mdio_set(struct mdiobb_ctrl
*ctrl
, int what
)
63 struct mdio_gpio_info
*bitbang
=
64 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
66 gpio_set_value(bitbang
->mdio
, what
);
69 static void mdc_set(struct mdiobb_ctrl
*ctrl
, int what
)
71 struct mdio_gpio_info
*bitbang
=
72 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
74 gpio_set_value(bitbang
->mdc
, what
);
77 static struct mdiobb_ops mdio_gpio_ops
= {
80 .set_mdio_dir
= mdio_dir
,
81 .set_mdio_data
= mdio_set
,
82 .get_mdio_data
= mdio_get
,
85 static struct mii_bus
* __devinit
mdio_gpio_bus_init(struct device
*dev
,
86 struct mdio_gpio_platform_data
*pdata
,
89 struct mii_bus
*new_bus
;
90 struct mdio_gpio_info
*bitbang
;
93 bitbang
= kzalloc(sizeof(*bitbang
), GFP_KERNEL
);
97 bitbang
->ctrl
.ops
= &mdio_gpio_ops
;
98 bitbang
->ctrl
.reset
= pdata
->reset
;
99 bitbang
->mdc
= pdata
->mdc
;
100 bitbang
->mdio
= pdata
->mdio
;
102 new_bus
= alloc_mdio_bitbang(&bitbang
->ctrl
);
104 goto out_free_bitbang
;
106 new_bus
->name
= "GPIO Bitbanged MDIO",
108 new_bus
->phy_mask
= pdata
->phy_mask
;
109 new_bus
->irq
= pdata
->irqs
;
110 new_bus
->parent
= dev
;
112 if (new_bus
->phy_mask
== ~0)
115 for (i
= 0; i
< PHY_MAX_ADDR
; i
++)
116 if (!new_bus
->irq
[i
])
117 new_bus
->irq
[i
] = PHY_POLL
;
119 snprintf(new_bus
->id
, MII_BUS_ID_SIZE
, "gpio-%x", bus_id
);
121 if (gpio_request(bitbang
->mdc
, "mdc"))
124 if (gpio_request(bitbang
->mdio
, "mdio"))
127 gpio_direction_output(bitbang
->mdc
, 0);
129 dev_set_drvdata(dev
, new_bus
);
134 gpio_free(bitbang
->mdc
);
136 free_mdio_bitbang(new_bus
);
143 static void mdio_gpio_bus_deinit(struct device
*dev
)
145 struct mii_bus
*bus
= dev_get_drvdata(dev
);
146 struct mdio_gpio_info
*bitbang
= bus
->priv
;
148 dev_set_drvdata(dev
, NULL
);
149 gpio_free(bitbang
->mdio
);
150 gpio_free(bitbang
->mdc
);
151 free_mdio_bitbang(bus
);
155 static void __devexit
mdio_gpio_bus_destroy(struct device
*dev
)
157 struct mii_bus
*bus
= dev_get_drvdata(dev
);
159 mdiobus_unregister(bus
);
160 mdio_gpio_bus_deinit(dev
);
163 static int __devinit
mdio_gpio_probe(struct platform_device
*pdev
)
165 struct mdio_gpio_platform_data
*pdata
= pdev
->dev
.platform_data
;
166 struct mii_bus
*new_bus
;
172 new_bus
= mdio_gpio_bus_init(&pdev
->dev
, pdata
, pdev
->id
);
176 ret
= mdiobus_register(new_bus
);
178 mdio_gpio_bus_deinit(&pdev
->dev
);
183 static int __devexit
mdio_gpio_remove(struct platform_device
*pdev
)
185 mdio_gpio_bus_destroy(&pdev
->dev
);
190 #ifdef CONFIG_OF_GPIO
192 static int __devinit
mdio_ofgpio_probe(struct platform_device
*ofdev
)
194 struct mdio_gpio_platform_data
*pdata
;
195 struct mii_bus
*new_bus
;
198 pdata
= kzalloc(sizeof(*pdata
), GFP_KERNEL
);
202 ret
= of_get_gpio(ofdev
->dev
.of_node
, 0);
207 ret
= of_get_gpio(ofdev
->dev
.of_node
, 1);
212 new_bus
= mdio_gpio_bus_init(&ofdev
->dev
, pdata
, pdata
->mdc
);
216 ret
= of_mdiobus_register(new_bus
, ofdev
->dev
.of_node
);
218 mdio_gpio_bus_deinit(&ofdev
->dev
);
227 static int __devexit
mdio_ofgpio_remove(struct platform_device
*ofdev
)
229 mdio_gpio_bus_destroy(&ofdev
->dev
);
230 kfree(ofdev
->dev
.platform_data
);
235 static struct of_device_id mdio_ofgpio_match
[] = {
237 .compatible
= "virtual,mdio-gpio",
241 MODULE_DEVICE_TABLE(of
, mdio_ofgpio_match
);
243 static struct platform_driver mdio_ofgpio_driver
= {
245 .name
= "mdio-ofgpio",
246 .owner
= THIS_MODULE
,
247 .of_match_table
= mdio_ofgpio_match
,
249 .probe
= mdio_ofgpio_probe
,
250 .remove
= __devexit_p(mdio_ofgpio_remove
),
253 static inline int __init
mdio_ofgpio_init(void)
255 return platform_driver_register(&mdio_ofgpio_driver
);
258 static inline void __exit
mdio_ofgpio_exit(void)
260 platform_driver_unregister(&mdio_ofgpio_driver
);
263 static inline int __init
mdio_ofgpio_init(void) { return 0; }
264 static inline void __exit
mdio_ofgpio_exit(void) { }
265 #endif /* CONFIG_OF_GPIO */
267 static struct platform_driver mdio_gpio_driver
= {
268 .probe
= mdio_gpio_probe
,
269 .remove
= __devexit_p(mdio_gpio_remove
),
272 .owner
= THIS_MODULE
,
276 static int __init
mdio_gpio_init(void)
280 ret
= mdio_ofgpio_init();
284 ret
= platform_driver_register(&mdio_gpio_driver
);
290 module_init(mdio_gpio_init
);
292 static void __exit
mdio_gpio_exit(void)
294 platform_driver_unregister(&mdio_gpio_driver
);
297 module_exit(mdio_gpio_exit
);
299 MODULE_ALIAS("platform:mdio-gpio");
300 MODULE_AUTHOR("Laurent Pinchart, Paulius Zaleckas");
301 MODULE_LICENSE("GPL");
302 MODULE_DESCRIPTION("Generic driver for MDIO bus emulation using GPIO");