dm9000: Add regulator and reset support to dm9000
[cascardo/linux.git] / drivers / net / ethernet / davicom / dm9000.c
index f3ba840..c0a7813 100644 (file)
@@ -36,6 +36,9 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -1426,11 +1429,48 @@ dm9000_probe(struct platform_device *pdev)
        struct dm9000_plat_data *pdata = dev_get_platdata(&pdev->dev);
        struct board_info *db;  /* Point a board information structure */
        struct net_device *ndev;
+       struct device *dev = &pdev->dev;
        const unsigned char *mac_src;
        int ret = 0;
        int iosize;
        int i;
        u32 id_val;
+       int reset_gpios;
+       enum of_gpio_flags flags;
+       struct regulator *power;
+
+       power = devm_regulator_get(dev, "vcc");
+       if (IS_ERR(power)) {
+               if (PTR_ERR(power) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               dev_dbg(dev, "no regulator provided\n");
+       } else {
+               ret = regulator_enable(power);
+               if (ret != 0) {
+                       dev_err(dev,
+                               "Failed to enable power regulator: %d\n", ret);
+                       return ret;
+               }
+               dev_dbg(dev, "regulator enabled\n");
+       }
+
+       reset_gpios = of_get_named_gpio_flags(dev->of_node, "reset-gpios", 0,
+                                             &flags);
+       if (gpio_is_valid(reset_gpios)) {
+               ret = devm_gpio_request_one(dev, reset_gpios, flags,
+                                           "dm9000_reset");
+               if (ret) {
+                       dev_err(dev, "failed to request reset gpio %d: %d\n",
+                               reset_gpios, ret);
+                       return -ENODEV;
+               }
+
+               /* According to manual PWRST# Low Period Min 1ms */
+               msleep(2);
+               gpio_set_value(reset_gpios, 1);
+               /* Needs 3ms to read eeprom when PWRST is deasserted */
+               msleep(4);
+       }
 
        if (!pdata) {
                pdata = dm9000_parse_dt(&pdev->dev);
@@ -1749,7 +1789,6 @@ MODULE_DEVICE_TABLE(of, dm9000_of_matches);
 static struct platform_driver dm9000_driver = {
        .driver = {
                .name    = "dm9000",
-               .owner   = THIS_MODULE,
                .pm      = &dm9000_drv_pm_ops,
                .of_match_table = of_match_ptr(dm9000_of_matches),
        },