libertas: convert SNMP_MIB to a direct command
[linux/fpc-iii.git] / drivers / net / phy / mdio-ofgpio.c
blob7edfc0c348355a3b33e513a92c195cce09898e2e
1 /*
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;
30 int mdc, mdio;
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);
38 if (dir)
39 gpio_direction_output(bitbang->mdio, 1);
40 else
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 = {
69 .owner = THIS_MODULE,
70 .set_mdc = mdc,
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)
85 return -ENODEV;
87 snprintf(bus->id, MII_BUS_ID_SIZE, "%x", bitbang->mdc);
88 return 0;
91 static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
93 const u32 *data;
94 int len, id, irq;
96 data = of_get_property(np, "reg", &len);
97 if (!data || len != 4)
98 return;
100 id = *data;
101 bus->phy_mask &= ~(1 << id);
103 irq = of_irq_to_resource(np, 0, NULL);
104 if (irq != NO_IRQ)
105 bus->irq[id] = irq;
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;
114 int ret = -ENOMEM;
115 int i;
117 bitbang = kzalloc(sizeof(struct mdio_gpio_info), GFP_KERNEL);
118 if (!bitbang)
119 goto out;
121 bitbang->ctrl.ops = &mdio_gpio_ops;
123 new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
124 if (!new_bus)
125 goto out_free_priv;
127 new_bus->name = "GPIO Bitbanged MII",
129 ret = mdio_ofgpio_bitbang_init(new_bus, ofdev->node);
130 if (ret)
131 goto out_free_bus;
133 new_bus->phy_mask = ~0;
134 new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
135 if (!new_bus->irq)
136 goto out_free_bus;
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);
149 if (ret)
150 goto out_free_irqs;
152 return 0;
154 out_free_irqs:
155 dev_set_drvdata(&ofdev->dev, NULL);
156 kfree(new_bus->irq);
157 out_free_bus:
158 kfree(new_bus);
159 out_free_priv:
160 free_mdio_bitbang(new_bus);
161 out:
162 return ret;
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);
173 kfree(bus->irq);
174 kfree(bitbang);
175 kfree(bus);
177 return 0;
180 static struct of_device_id mdio_ofgpio_match[] = {
182 .compatible = "virtual,mdio-gpio",
187 static struct of_platform_driver mdio_ofgpio_driver = {
188 .name = "mdio-gpio",
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);