Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73fdeb82 authored by Stephen Boyd's avatar Stephen Boyd Committed by David S. Miller
Browse files

net: ks8851: Add optional vdd_io regulator and reset gpio



Allow the ks8851 driver to enable an optional 1.8V vdd_io
regulator and assert the reset pin to the phy if a reset gpio is
present in device tree.

Cc: Nishanth Menon <nm@ti.com>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c78dbad8
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#include <linux/regulator/consumer.h>

#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>

#include "ks8851.h"

@@ -85,6 +87,8 @@ union ks8851_tx_hdr {
 * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom
 * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM.
 * @vdd_reg:	Optional regulator supplying the chip
 * @vdd_io: Optional digital power supply for IO
 * @gpio: Optional reset_n gpio
 *
 * The @lock ensures that the chip is protected when certain operations are
 * in progress. When the read or write packet transfer is in progress, most
@@ -133,6 +137,8 @@ struct ks8851_net {

	struct eeprom_93cx6	eeprom;
	struct regulator	*vdd_reg;
	struct regulator	*vdd_io;
	int			gpio;
};

static int msg_enable;
@@ -1404,6 +1410,7 @@ static int ks8851_probe(struct spi_device *spi)
	struct ks8851_net *ks;
	int ret;
	unsigned cider;
	int gpio;

	ndev = alloc_etherdev(sizeof(struct ks8851_net));
	if (!ndev)
@@ -1417,6 +1424,37 @@ static int ks8851_probe(struct spi_device *spi)
	ks->spidev = spi;
	ks->tx_space = 6144;

	gpio = of_get_named_gpio_flags(spi->dev.of_node, "reset-gpios",
				       0, NULL);
	if (gpio == -EPROBE_DEFER) {
		ret = gpio;
		goto err_gpio;
	}

	ks->gpio = gpio;
	if (gpio_is_valid(gpio)) {
		ret = devm_gpio_request_one(&spi->dev, gpio,
					    GPIOF_OUT_INIT_LOW, "ks8851_rst_n");
		if (ret) {
			dev_err(&spi->dev, "reset gpio request failed\n");
			goto err_gpio;
		}
	}

	ks->vdd_io = devm_regulator_get_optional(&spi->dev, "vdd-io");
	if (IS_ERR(ks->vdd_io)) {
		ret = PTR_ERR(ks->vdd_io);
		if (ret == -EPROBE_DEFER)
			goto err_reg_io;
	} else {
		ret = regulator_enable(ks->vdd_io);
		if (ret) {
			dev_err(&spi->dev, "regulator vdd_io enable fail: %d\n",
				ret);
			goto err_reg_io;
		}
	}

	ks->vdd_reg = devm_regulator_get_optional(&spi->dev, "vdd");
	if (IS_ERR(ks->vdd_reg)) {
		ret = PTR_ERR(ks->vdd_reg);
@@ -1425,12 +1463,16 @@ static int ks8851_probe(struct spi_device *spi)
	} else {
		ret = regulator_enable(ks->vdd_reg);
		if (ret) {
			dev_err(&spi->dev, "regulator enable fail: %d\n",
			dev_err(&spi->dev, "regulator vdd enable fail: %d\n",
				ret);
			goto err_reg;
		}
	}

	if (gpio_is_valid(gpio)) {
		usleep_range(10000, 11000);
		gpio_set_value(gpio, 1);
	}

	mutex_init(&ks->lock);
	spin_lock_init(&ks->statelock);
@@ -1527,10 +1569,16 @@ err_netdev:
	free_irq(ndev->irq, ks);

err_irq:
	if (gpio_is_valid(gpio))
		gpio_set_value(gpio, 0);
err_id:
	if (!IS_ERR(ks->vdd_reg))
		regulator_disable(ks->vdd_reg);
err_reg:
	if (!IS_ERR(ks->vdd_io))
		regulator_disable(ks->vdd_io);
err_reg_io:
err_gpio:
	free_netdev(ndev);
	return ret;
}
@@ -1544,8 +1592,12 @@ static int ks8851_remove(struct spi_device *spi)

	unregister_netdev(priv->netdev);
	free_irq(spi->irq, priv);
	if (gpio_is_valid(priv->gpio))
		gpio_set_value(priv->gpio, 0);
	if (!IS_ERR(priv->vdd_reg))
		regulator_disable(priv->vdd_reg);
	if (!IS_ERR(priv->vdd_io))
		regulator_disable(priv->vdd_io);
	free_netdev(priv->netdev);

	return 0;