Browse Source

Merge branch 'ks8851'

Stephen Boyd says:

====================
ks8851 DT/regulator/gpio updates

This set of patches properly documents the micrel ks8851 spi ethernet
controller, converts to devm_regulator_get_optional() to make error
paths slightly simpler, and finally adds supports for another
optional regulator and a reset gpio. This allows me to use the ks8851
on my MSM8960 CDP board.

Changes since v1:
 * Dropped vendor prefix patch as that should go through DT tree
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 11 years ago
parent
commit
6c705d1362

+ 12 - 3
Documentation/devicetree/bindings/net/micrel-ks8851.txt

@@ -1,9 +1,18 @@
-Micrel KS8851 Ethernet mac
+Micrel KS8851 Ethernet mac (MLL)
 
 
 Required properties:
 Required properties:
-- compatible = "micrel,ks8851-ml" of parallel interface
+- compatible = "micrel,ks8851-mll" of parallel interface
 - reg : 2 physical address and size of registers for data and command
 - reg : 2 physical address and size of registers for data and command
 - interrupts : interrupt connection
 - interrupts : interrupt connection
 
 
+Micrel KS8851 Ethernet mac (SPI)
+
+Required properties:
+- compatible = "micrel,ks8851" or the deprecated "ks8851"
+- reg : chip select number
+- interrupts : interrupt connection
+
 Optional properties:
 Optional properties:
-- vdd-supply:	supply for Ethernet mac
+- vdd-supply: analog 3.3V supply for Ethernet mac
+- vdd-io-supply: digital 1.8V IO supply for Ethernet mac
+- reset-gpios: reset_n input pin

+ 62 - 9
drivers/net/ethernet/micrel/ks8851.c

@@ -26,6 +26,8 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
 
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 
 #include "ks8851.h"
 #include "ks8851.h"
 
 
@@ -85,6 +87,8 @@ union ks8851_tx_hdr {
  * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom
  * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom
  * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM.
  * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM.
  * @vdd_reg:	Optional regulator supplying the chip
  * @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
  * 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
  * 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 eeprom_93cx6	eeprom;
 	struct regulator	*vdd_reg;
 	struct regulator	*vdd_reg;
+	struct regulator	*vdd_io;
+	int			gpio;
 };
 };
 
 
 static int msg_enable;
 static int msg_enable;
@@ -1404,6 +1410,7 @@ static int ks8851_probe(struct spi_device *spi)
 	struct ks8851_net *ks;
 	struct ks8851_net *ks;
 	int ret;
 	int ret;
 	unsigned cider;
 	unsigned cider;
+	int gpio;
 
 
 	ndev = alloc_etherdev(sizeof(struct ks8851_net));
 	ndev = alloc_etherdev(sizeof(struct ks8851_net));
 	if (!ndev)
 	if (!ndev)
@@ -1417,7 +1424,38 @@ static int ks8851_probe(struct spi_device *spi)
 	ks->spidev = spi;
 	ks->spidev = spi;
 	ks->tx_space = 6144;
 	ks->tx_space = 6144;
 
 
-	ks->vdd_reg = regulator_get_optional(&spi->dev, "vdd");
+	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)) {
 	if (IS_ERR(ks->vdd_reg)) {
 		ret = PTR_ERR(ks->vdd_reg);
 		ret = PTR_ERR(ks->vdd_reg);
 		if (ret == -EPROBE_DEFER)
 		if (ret == -EPROBE_DEFER)
@@ -1425,12 +1463,16 @@ static int ks8851_probe(struct spi_device *spi)
 	} else {
 	} else {
 		ret = regulator_enable(ks->vdd_reg);
 		ret = regulator_enable(ks->vdd_reg);
 		if (ret) {
 		if (ret) {
-			dev_err(&spi->dev, "regulator enable fail: %d\n",
+			dev_err(&spi->dev, "regulator vdd enable fail: %d\n",
 				ret);
 				ret);
-			goto err_reg_en;
+			goto err_reg;
 		}
 		}
 	}
 	}
 
 
+	if (gpio_is_valid(gpio)) {
+		usleep_range(10000, 11000);
+		gpio_set_value(gpio, 1);
+	}
 
 
 	mutex_init(&ks->lock);
 	mutex_init(&ks->lock);
 	spin_lock_init(&ks->statelock);
 	spin_lock_init(&ks->statelock);
@@ -1527,13 +1569,16 @@ err_netdev:
 	free_irq(ndev->irq, ks);
 	free_irq(ndev->irq, ks);
 
 
 err_irq:
 err_irq:
+	if (gpio_is_valid(gpio))
+		gpio_set_value(gpio, 0);
 err_id:
 err_id:
 	if (!IS_ERR(ks->vdd_reg))
 	if (!IS_ERR(ks->vdd_reg))
 		regulator_disable(ks->vdd_reg);
 		regulator_disable(ks->vdd_reg);
-err_reg_en:
-	if (!IS_ERR(ks->vdd_reg))
-		regulator_put(ks->vdd_reg);
 err_reg:
 err_reg:
+	if (!IS_ERR(ks->vdd_io))
+		regulator_disable(ks->vdd_io);
+err_reg_io:
+err_gpio:
 	free_netdev(ndev);
 	free_netdev(ndev);
 	return ret;
 	return ret;
 }
 }
@@ -1547,18 +1592,26 @@ static int ks8851_remove(struct spi_device *spi)
 
 
 	unregister_netdev(priv->netdev);
 	unregister_netdev(priv->netdev);
 	free_irq(spi->irq, priv);
 	free_irq(spi->irq, priv);
-	if (!IS_ERR(priv->vdd_reg)) {
+	if (gpio_is_valid(priv->gpio))
+		gpio_set_value(priv->gpio, 0);
+	if (!IS_ERR(priv->vdd_reg))
 		regulator_disable(priv->vdd_reg);
 		regulator_disable(priv->vdd_reg);
-		regulator_put(priv->vdd_reg);
-	}
+	if (!IS_ERR(priv->vdd_io))
+		regulator_disable(priv->vdd_io);
 	free_netdev(priv->netdev);
 	free_netdev(priv->netdev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static const struct of_device_id ks8851_match_table[] = {
+	{ .compatible = "micrel,ks8851" },
+	{ }
+};
+
 static struct spi_driver ks8851_driver = {
 static struct spi_driver ks8851_driver = {
 	.driver = {
 	.driver = {
 		.name = "ks8851",
 		.name = "ks8851",
+		.of_match_table = ks8851_match_table,
 		.owner = THIS_MODULE,
 		.owner = THIS_MODULE,
 		.pm = &ks8851_pm_ops,
 		.pm = &ks8851_pm_ops,
 	},
 	},