ks8851: Add GPIO and regulator support
Allow the ks8851 driver to configure regulators and GPIOs specified as platform data or in device tree. Change-Id: I806f7c22ba4b75eb26720704968cdec9cd7796c8 Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org> Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org> (cherry picked from commit c990b2faa3ce0b4f2361630a687abdedee4241a9) Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
This commit is contained in:
committed by
Stephen Boyd
parent
62774a2a5f
commit
af33ebe883
@@ -23,8 +23,13 @@
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/eeprom_93cx6.h>
|
||||
#include <linux/ks8851.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#include "ks8851.h"
|
||||
|
||||
@@ -131,6 +136,10 @@ struct ks8851_net {
|
||||
struct spi_transfer spi_xfer1;
|
||||
struct spi_transfer spi_xfer2[2];
|
||||
|
||||
struct regulator *vdd_io;
|
||||
struct regulator *vdd_phy;
|
||||
int rst_gpio;
|
||||
|
||||
struct eeprom_93cx6 eeprom;
|
||||
};
|
||||
|
||||
@@ -1415,6 +1424,66 @@ static int ks8851_resume(struct spi_device *spi)
|
||||
#define ks8851_resume NULL
|
||||
#endif
|
||||
|
||||
static int __devinit ks8851_init_hw(struct spi_device *spi,
|
||||
struct ks8851_net *ks)
|
||||
{
|
||||
struct ks8851_pdata *pdata = spi->dev.platform_data;
|
||||
struct device_node *dnode = spi->dev.of_node;
|
||||
enum of_gpio_flags flags;
|
||||
int ret;
|
||||
|
||||
ks->rst_gpio = -ENODEV;
|
||||
|
||||
if (dnode)
|
||||
ks->rst_gpio = of_get_named_gpio_flags(dnode, "rst-gpio",
|
||||
0, &flags);
|
||||
else if (pdata)
|
||||
ks->rst_gpio = pdata->rst_gpio;
|
||||
|
||||
if (gpio_is_valid(ks->rst_gpio)) {
|
||||
ret = gpio_request(ks->rst_gpio, "ks8851_rst");
|
||||
if (ret) {
|
||||
pr_err("ks8851 gpio_request failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make sure the chip is in reset state */
|
||||
gpio_direction_output(ks->rst_gpio, 0);
|
||||
}
|
||||
|
||||
ks->vdd_io = regulator_get(&spi->dev, "vdd-io");
|
||||
|
||||
if (IS_ERR(ks->vdd_io)) {
|
||||
ret = PTR_ERR(ks->vdd_io);
|
||||
goto fail_gpio;
|
||||
}
|
||||
|
||||
ks->vdd_phy = regulator_get(&spi->dev, "vdd-phy");
|
||||
|
||||
if (IS_ERR(ks->vdd_phy)) {
|
||||
regulator_put(ks->vdd_io);
|
||||
ret = PTR_ERR(ks->vdd_phy);
|
||||
goto fail_gpio;
|
||||
}
|
||||
|
||||
regulator_enable(ks->vdd_io);
|
||||
regulator_enable(ks->vdd_phy);
|
||||
|
||||
/* Wait for atleast 10ms after turning on regulator */
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
if (gpio_is_valid(ks->rst_gpio))
|
||||
gpio_direction_output(ks->rst_gpio, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_gpio:
|
||||
if (gpio_is_valid(ks->rst_gpio))
|
||||
gpio_free(ks->rst_gpio);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devinit ks8851_probe(struct spi_device *spi)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
@@ -1430,6 +1499,10 @@ static int __devinit ks8851_probe(struct spi_device *spi)
|
||||
|
||||
ks = netdev_priv(ndev);
|
||||
|
||||
ret = ks8851_init_hw(spi, ks);
|
||||
if (ret)
|
||||
goto err_init;
|
||||
|
||||
ks->netdev = ndev;
|
||||
ks->spidev = spi;
|
||||
ks->tx_space = 6144;
|
||||
@@ -1530,6 +1603,20 @@ err_netdev:
|
||||
|
||||
err_id:
|
||||
err_irq:
|
||||
if (gpio_is_valid(ks->rst_gpio))
|
||||
gpio_free(ks->rst_gpio);
|
||||
|
||||
if (!IS_ERR(ks->vdd_io)) {
|
||||
regulator_disable(ks->vdd_io);
|
||||
regulator_put(ks->vdd_io);
|
||||
}
|
||||
|
||||
if (!IS_ERR(ks->vdd_phy)) {
|
||||
regulator_disable(ks->vdd_phy);
|
||||
regulator_put(ks->vdd_phy);
|
||||
}
|
||||
|
||||
err_init:
|
||||
free_netdev(ndev);
|
||||
return ret;
|
||||
}
|
||||
@@ -1541,6 +1628,19 @@ static int __devexit ks8851_remove(struct spi_device *spi)
|
||||
if (netif_msg_drv(priv))
|
||||
dev_info(&spi->dev, "remove\n");
|
||||
|
||||
if (gpio_is_valid(priv->rst_gpio))
|
||||
gpio_free(priv->rst_gpio);
|
||||
|
||||
if (!IS_ERR(priv->vdd_io)) {
|
||||
regulator_disable(priv->vdd_io);
|
||||
regulator_put(priv->vdd_io);
|
||||
}
|
||||
|
||||
if (!IS_ERR(priv->vdd_phy)) {
|
||||
regulator_disable(priv->vdd_phy);
|
||||
regulator_put(priv->vdd_phy);
|
||||
}
|
||||
|
||||
unregister_netdev(priv->netdev);
|
||||
free_irq(spi->irq, priv);
|
||||
free_netdev(priv->netdev);
|
||||
@@ -1548,9 +1648,17 @@ static int __devexit ks8851_remove(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id ks8851_match_table[] = {
|
||||
{
|
||||
.compatible = "micrel,ks8851",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct spi_driver ks8851_driver = {
|
||||
.driver = {
|
||||
.name = "ks8851",
|
||||
.of_match_table = ks8851_match_table,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ks8851_probe,
|
||||
|
||||
Reference in New Issue
Block a user