2 * OpenFirmware GPIO based MDIO bitbang driver.
4 * Copyright (c) 2008 CSE Semaphore Belgium.
5 * by Laurent Pinchart <laurentp@cse-semaphore.com>
7 * Based on earlier work by
9 * Copyright (c) 2003 Intracom S.A.
10 * by Pantelis Antoniou <panto@intracom.gr>
12 * 2005 (c) MontaVista Software, Inc.
13 * Vitaly Bordug <vbordug@ru.mvista.com>
15 * This file is licensed under the terms of the GNU General Public License
16 * version 2. This program is licensed "as is" without any warranty of any
17 * kind, whether express or implied.
20 #include <linux/module.h>
21 #include <linux/slab.h>
22 #include <linux/init.h>
23 #include <linux/interrupt.h>
24 #include <linux/mdio-bitbang.h>
25 #include <linux/of_gpio.h>
26 #include <linux/of_platform.h>
28 struct mdio_gpio_info
{
29 struct mdiobb_ctrl ctrl
;
33 static void mdio_dir(struct mdiobb_ctrl
*ctrl
, int dir
)
35 struct mdio_gpio_info
*bitbang
=
36 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
39 gpio_direction_output(bitbang
->mdio
, 1);
41 gpio_direction_input(bitbang
->mdio
);
44 static int mdio_read(struct mdiobb_ctrl
*ctrl
)
46 struct mdio_gpio_info
*bitbang
=
47 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
49 return gpio_get_value(bitbang
->mdio
);
52 static void mdio(struct mdiobb_ctrl
*ctrl
, int what
)
54 struct mdio_gpio_info
*bitbang
=
55 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
57 gpio_set_value(bitbang
->mdio
, what
);
60 static void mdc(struct mdiobb_ctrl
*ctrl
, int what
)
62 struct mdio_gpio_info
*bitbang
=
63 container_of(ctrl
, struct mdio_gpio_info
, ctrl
);
65 gpio_set_value(bitbang
->mdc
, what
);
68 static struct mdiobb_ops mdio_gpio_ops
= {
71 .set_mdio_dir
= mdio_dir
,
72 .set_mdio_data
= mdio
,
73 .get_mdio_data
= mdio_read
,
76 static int __devinit
mdio_ofgpio_bitbang_init(struct mii_bus
*bus
,
77 struct device_node
*np
)
79 struct mdio_gpio_info
*bitbang
= bus
->priv
;
81 bitbang
->mdc
= of_get_gpio(np
, 0);
82 bitbang
->mdio
= of_get_gpio(np
, 1);
84 if (bitbang
->mdc
< 0 || bitbang
->mdio
< 0)
87 snprintf(bus
->id
, MII_BUS_ID_SIZE
, "%x", bitbang
->mdc
);
91 static void __devinit
add_phy(struct mii_bus
*bus
, struct device_node
*np
)
96 data
= of_get_property(np
, "reg", &len
);
97 if (!data
|| len
!= 4)
101 bus
->phy_mask
&= ~(1 << id
);
103 irq
= of_irq_to_resource(np
, 0, NULL
);
108 static int __devinit
mdio_ofgpio_probe(struct of_device
*ofdev
,
109 const struct of_device_id
*match
)
111 struct device_node
*np
= NULL
;
112 struct mii_bus
*new_bus
;
113 struct mdio_gpio_info
*bitbang
;
117 bitbang
= kzalloc(sizeof(struct mdio_gpio_info
), GFP_KERNEL
);
121 bitbang
->ctrl
.ops
= &mdio_gpio_ops
;
123 new_bus
= alloc_mdio_bitbang(&bitbang
->ctrl
);
127 new_bus
->name
= "GPIO Bitbanged MII",
129 ret
= mdio_ofgpio_bitbang_init(new_bus
, ofdev
->node
);
133 new_bus
->phy_mask
= ~0;
134 new_bus
->irq
= kmalloc(sizeof(int) * PHY_MAX_ADDR
, GFP_KERNEL
);
138 for (i
= 0; i
< PHY_MAX_ADDR
; i
++)
139 new_bus
->irq
[i
] = -1;
141 while ((np
= of_get_next_child(ofdev
->node
, np
)))
142 if (!strcmp(np
->type
, "ethernet-phy"))
143 add_phy(new_bus
, np
);
145 new_bus
->dev
= &ofdev
->dev
;
146 dev_set_drvdata(&ofdev
->dev
, new_bus
);
148 ret
= mdiobus_register(new_bus
);
155 dev_set_drvdata(&ofdev
->dev
, NULL
);
160 free_mdio_bitbang(new_bus
);
165 static int mdio_ofgpio_remove(struct of_device
*ofdev
)
167 struct mii_bus
*bus
= dev_get_drvdata(&ofdev
->dev
);
168 struct mdio_gpio_info
*bitbang
= bus
->priv
;
170 mdiobus_unregister(bus
);
171 free_mdio_bitbang(bus
);
172 dev_set_drvdata(&ofdev
->dev
, NULL
);
180 static struct of_device_id mdio_ofgpio_match
[] = {
182 .compatible
= "virtual,mdio-gpio",
187 static struct of_platform_driver mdio_ofgpio_driver
= {
189 .match_table
= mdio_ofgpio_match
,
190 .probe
= mdio_ofgpio_probe
,
191 .remove
= mdio_ofgpio_remove
,
194 static int mdio_ofgpio_init(void)
196 return of_register_platform_driver(&mdio_ofgpio_driver
);
199 static void mdio_ofgpio_exit(void)
201 of_unregister_platform_driver(&mdio_ofgpio_driver
);
204 module_init(mdio_ofgpio_init
);
205 module_exit(mdio_ofgpio_exit
);