All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch
@ 2016-02-08 17:35 Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 1/6] net: phy: spi_ks8995: introduce spi_device_id table Helmut Buchsbaum
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-08 17:35 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev, Helmut Buchsbaum

This patch series refactors the spi-ks8995 driver to finally add support
for the MICREL KSZ8795CLX. Additionally support for controlling a GPIO
line for resetting the switch is added.

Helmut

Changes since v1:
 - removed initializing registers from Device Tree following Florian's
   advice
 - fixed GPIO handling for reset according to Andrew's remark.

Helmut Buchsbaum (6):
  net: phy: spi_ks8995: introduce spi_device_id table
  net: phy: spi_ks8995: verify chip and determine revision
  net: phy: spi_ks8995: add support for resetting switch using GPIO
  net: phy: spi_ks8995: generalize creation of SPI commands
  net: phy: spi_ks8995: add support for MICREL KSZ8795CLX
  dt-bindings: net: ks8995: add bindings documentation for ks8995

 .../devicetree/bindings/net/micrel-ks8995.txt      |  20 ++
 drivers/net/phy/spi_ks8995.c                       | 304 +++++++++++++++++----
 2 files changed, 265 insertions(+), 59 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/micrel-ks8995.txt

-- 
2.1.4

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/6] net: phy: spi_ks8995: introduce spi_device_id table
  2016-02-08 17:35 [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch Helmut Buchsbaum
@ 2016-02-08 17:35 ` Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 2/6] net: phy: spi_ks8995: verify chip and determine revision Helmut Buchsbaum
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-08 17:35 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev, Helmut Buchsbaum

Refactor to use spi_device_id table to facilitate easy
extendability.

Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
---
 drivers/net/phy/spi_ks8995.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
index f091d69..e848ad9 100644
--- a/drivers/net/phy/spi_ks8995.c
+++ b/drivers/net/phy/spi_ks8995.c
@@ -89,6 +89,28 @@
 
 #define KS8995_RESET_DELAY	10 /* usec */
 
+enum ks8995_chip_variant {
+	ks8995,
+	ksz8864,
+	max_variant
+};
+
+struct ks8995_chip_params {
+	char *name;
+	int regs_size;
+};
+
+static const struct ks8995_chip_params ks8995_chip[] = {
+	[ks8995] = {
+		.name = "KS8995MA",
+		.regs_size = KS8995_REGS_SIZE,
+	},
+	[ksz8864] = {
+		.name = "KSZ8864RMN",
+		.regs_size = KSZ8864_REGS_SIZE,
+	},
+};
+
 struct ks8995_pdata {
 	/* not yet implemented */
 };
@@ -98,8 +120,16 @@ struct ks8995_switch {
 	struct mutex		lock;
 	struct ks8995_pdata	*pdata;
 	struct bin_attribute	regs_attr;
+	const struct ks8995_chip_params	*chip;
 };
 
+static const struct spi_device_id ks8995_id[] = {
+	{"ks8995", ks8995},
+	{"ksz8864", ksz8864},
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, ks8995_id);
+
 static inline u8 get_chip_id(u8 val)
 {
 	return (val >> ID1_CHIPID_S) & ID1_CHIPID_M;
@@ -244,17 +274,22 @@ static const struct bin_attribute ks8995_registers_attr = {
 };
 
 /* ------------------------------------------------------------------------ */
-
 static int ks8995_probe(struct spi_device *spi)
 {
 	struct ks8995_switch    *ks;
 	struct ks8995_pdata     *pdata;
 	u8      ids[2];
 	int     err;
+	int variant = spi_get_device_id(spi)->driver_data;
 
 	/* Chip description */
 	pdata = spi->dev.platform_data;
 
+	if (variant >= max_variant) {
+		dev_err(&spi->dev, "bad chip variant %d\n", variant);
+		return -ENODEV;
+	}
+
 	ks = devm_kzalloc(&spi->dev, sizeof(*ks), GFP_KERNEL);
 	if (!ks)
 		return -ENOMEM;
@@ -262,6 +297,8 @@ static int ks8995_probe(struct spi_device *spi)
 	mutex_init(&ks->lock);
 	ks->pdata = pdata;
 	ks->spi = spi_dev_get(spi);
+	ks->chip = &ks8995_chip[variant];
+
 	spi_set_drvdata(spi, ks);
 
 	spi->mode = SPI_MODE_0;
@@ -287,6 +324,7 @@ static int ks8995_probe(struct spi_device *spi)
 		return -ENODEV;
 	}
 
+	ks->regs_attr.size = ks->chip->regs_size;
 	memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr));
 	if (get_chip_id(ids[1]) != CHIPID_M) {
 		u8 val;
@@ -303,7 +341,6 @@ static int ks8995_probe(struct spi_device *spi)
 			dev_err(&spi->dev, "unknown chip:%02x,0\n", ids[1]);
 			return err;
 		}
-		ks->regs_attr.size = KSZ8864_REGS_SIZE;
 	}
 
 	err = ks8995_reset(ks);
@@ -347,6 +384,7 @@ static struct spi_driver ks8995_driver = {
 	},
 	.probe	  = ks8995_probe,
 	.remove	  = ks8995_remove,
+	.id_table = ks8995_id,
 };
 
 module_spi_driver(ks8995_driver);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/6] net: phy: spi_ks8995: verify chip and determine revision
  2016-02-08 17:35 [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 1/6] net: phy: spi_ks8995: introduce spi_device_id table Helmut Buchsbaum
@ 2016-02-08 17:35 ` Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 3/6] net: phy: spi_ks8995: add support for resetting switch using GPIO Helmut Buchsbaum
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-08 17:35 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev, Helmut Buchsbaum

Since the chip variant is now determined by spi_device_id, verify
family and chip id and determine the revision id.

Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
---
 drivers/net/phy/spi_ks8995.c | 118 +++++++++++++++++++++++++++++--------------
 1 file changed, 80 insertions(+), 38 deletions(-)

diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
index e848ad9..2803c8e 100644
--- a/drivers/net/phy/spi_ks8995.c
+++ b/drivers/net/phy/spi_ks8995.c
@@ -83,6 +83,8 @@
 
 #define FAMILY_KS8995		0x95
 #define CHIPID_M		0
+#define KS8995_CHIP_ID		0x00
+#define KSZ8864_CHIP_ID		0x01
 
 #define KS8995_CMD_WRITE	0x02U
 #define KS8995_CMD_READ		0x03U
@@ -97,16 +99,22 @@ enum ks8995_chip_variant {
 
 struct ks8995_chip_params {
 	char *name;
+	int family_id;
+	int chip_id;
 	int regs_size;
 };
 
 static const struct ks8995_chip_params ks8995_chip[] = {
 	[ks8995] = {
 		.name = "KS8995MA",
+		.family_id = FAMILY_KS8995,
+		.chip_id = KS8995_CHIP_ID,
 		.regs_size = KS8995_REGS_SIZE,
 	},
 	[ksz8864] = {
 		.name = "KSZ8864RMN",
+		.family_id = FAMILY_KS8995,
+		.chip_id = KSZ8864_CHIP_ID,
 		.regs_size = KSZ8864_REGS_SIZE,
 	},
 };
@@ -121,6 +129,7 @@ struct ks8995_switch {
 	struct ks8995_pdata	*pdata;
 	struct bin_attribute	regs_attr;
 	const struct ks8995_chip_params	*chip;
+	int			revision_id;
 };
 
 static const struct spi_device_id ks8995_id[] = {
@@ -263,6 +272,73 @@ static ssize_t ks8995_registers_write(struct file *filp, struct kobject *kobj,
 	return ks8995_write(ks8995, buf, off, count);
 }
 
+/* ks8995_get_revision - get chip revision
+ * @ks: pointer to switch instance
+ *
+ * Verify chip family and id and get chip revision.
+ */
+static int ks8995_get_revision(struct ks8995_switch *ks)
+{
+	int err;
+	u8 id0, id1, ksz8864_id;
+
+	/* read family id */
+	err = ks8995_read_reg(ks, KS8995_REG_ID0, &id0);
+	if (err) {
+		err = -EIO;
+		goto err_out;
+	}
+
+	/* verify family id */
+	if (id0 != ks->chip->family_id) {
+		dev_err(&ks->spi->dev, "chip family id mismatch: expected 0x%02x but 0x%02x read\n",
+			ks->chip->family_id, id0);
+		err = -ENODEV;
+		goto err_out;
+	}
+
+	switch (ks->chip->family_id) {
+	case FAMILY_KS8995:
+		/* try reading chip id at CHIP ID1 */
+		err = ks8995_read_reg(ks, KS8995_REG_ID1, &id1);
+		if (err) {
+			err = -EIO;
+			goto err_out;
+		}
+
+		/* verify chip id */
+		if ((get_chip_id(id1) == CHIPID_M) &&
+		    (get_chip_id(id1) == ks->chip->chip_id)) {
+			/* KS8995MA */
+			ks->revision_id = get_chip_rev(id1);
+		} else if (get_chip_id(id1) != CHIPID_M) {
+			/* KSZ8864RMN */
+			err = ks8995_read_reg(ks, KS8995_REG_ID1, &ksz8864_id);
+			if (err) {
+				err = -EIO;
+				goto err_out;
+			}
+
+			if ((ksz8864_id & 0x80) &&
+			    (ks->chip->chip_id == KSZ8864_CHIP_ID)) {
+				ks->revision_id = get_chip_rev(id1);
+			}
+
+		} else {
+			dev_err(&ks->spi->dev, "unsupported chip id for KS8995 family: 0x%02x\n",
+				id1);
+			err = -ENODEV;
+		}
+		break;
+	default:
+		dev_err(&ks->spi->dev, "unsupported family id: 0x%02x\n", id0);
+		err = -ENODEV;
+		break;
+	}
+err_out:
+	return err;
+}
+
 static const struct bin_attribute ks8995_registers_attr = {
 	.attr = {
 		.name   = "registers",
@@ -278,7 +354,6 @@ static int ks8995_probe(struct spi_device *spi)
 {
 	struct ks8995_switch    *ks;
 	struct ks8995_pdata     *pdata;
-	u8      ids[2];
 	int     err;
 	int variant = spi_get_device_id(spi)->driver_data;
 
@@ -309,39 +384,12 @@ static int ks8995_probe(struct spi_device *spi)
 		return err;
 	}
 
-	err = ks8995_read(ks, ids, KS8995_REG_ID0, sizeof(ids));
-	if (err < 0) {
-		dev_err(&spi->dev, "unable to read id registers, err=%d\n",
-				err);
+	err = ks8995_get_revision(ks);
+	if (err)
 		return err;
-	}
-
-	switch (ids[0]) {
-	case FAMILY_KS8995:
-		break;
-	default:
-		dev_err(&spi->dev, "unknown family id:%02x\n", ids[0]);
-		return -ENODEV;
-	}
 
 	ks->regs_attr.size = ks->chip->regs_size;
 	memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr));
-	if (get_chip_id(ids[1]) != CHIPID_M) {
-		u8 val;
-
-		/* Check if this is a KSZ8864RMN */
-		err = ks8995_read(ks, &val, KSZ8864_REG_ID1, sizeof(val));
-		if (err < 0) {
-			dev_err(&spi->dev,
-				"unable to read chip id register, err=%d\n",
-				err);
-			return err;
-		}
-		if ((val & 0x80) == 0) {
-			dev_err(&spi->dev, "unknown chip:%02x,0\n", ids[1]);
-			return err;
-		}
-	}
 
 	err = ks8995_reset(ks);
 	if (err)
@@ -354,14 +402,8 @@ static int ks8995_probe(struct spi_device *spi)
 		return err;
 	}
 
-	if (get_chip_id(ids[1]) == CHIPID_M) {
-		dev_info(&spi->dev,
-			 "KS8995 device found, Chip ID:%x, Revision:%x\n",
-			 get_chip_id(ids[1]), get_chip_rev(ids[1]));
-	} else {
-		dev_info(&spi->dev, "KSZ8864 device found, Revision:%x\n",
-			 get_chip_rev(ids[1]));
-	}
+	dev_info(&spi->dev, "%s device found, Chip ID:%x, Revision:%x\n",
+		 ks->chip->name, ks->chip->chip_id, ks->revision_id);
 
 	return 0;
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/6] net: phy: spi_ks8995: add support for resetting switch using GPIO
  2016-02-08 17:35 [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 1/6] net: phy: spi_ks8995: introduce spi_device_id table Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 2/6] net: phy: spi_ks8995: verify chip and determine revision Helmut Buchsbaum
@ 2016-02-08 17:35 ` Helmut Buchsbaum
  2016-02-09  8:32   ` Andrew Lunn
  2016-02-08 17:35 ` [PATCH v2 4/6] net: phy: spi_ks8995: generalize creation of SPI commands Helmut Buchsbaum
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-08 17:35 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev, Helmut Buchsbaum

When using device tree it is no more possible to reset the PHY at board
level. Furthermore, doing in the driver allows to power down the switch
when it is not used any more.

The patch introduces a new optional property "reset-gpios" denoting an
appropriate GPIO handle, e.g.:

reset-gpios = <&gpio0 46 1>

Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
---
 drivers/net/phy/spi_ks8995.c | 71 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 62 insertions(+), 9 deletions(-)

diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
index 2803c8e..04d468f 100644
--- a/drivers/net/phy/spi_ks8995.c
+++ b/drivers/net/phy/spi_ks8995.c
@@ -18,6 +18,9 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/of.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 #include <linux/spi/spi.h>
 
@@ -120,7 +123,8 @@ static const struct ks8995_chip_params ks8995_chip[] = {
 };
 
 struct ks8995_pdata {
-	/* not yet implemented */
+	int reset_gpio;
+	enum of_gpio_flags reset_gpio_flags;
 };
 
 struct ks8995_switch {
@@ -339,6 +343,24 @@ err_out:
 	return err;
 }
 
+/* ks8995_parse_dt - setup platform data from devicetree
+ * @ks: pointer to switch instance
+ *
+ * Parses supported DT properties and sets up platform data
+ * accordingly.
+ */
+static void ks8995_parse_dt(struct ks8995_switch *ks)
+{
+	struct device_node *np = ks->spi->dev.of_node;
+	struct ks8995_pdata *pdata = ks->pdata;
+
+	if (!np)
+		return;
+
+	pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0,
+		&pdata->reset_gpio_flags);
+}
+
 static const struct bin_attribute ks8995_registers_attr = {
 	.attr = {
 		.name   = "registers",
@@ -352,14 +374,10 @@ static const struct bin_attribute ks8995_registers_attr = {
 /* ------------------------------------------------------------------------ */
 static int ks8995_probe(struct spi_device *spi)
 {
-	struct ks8995_switch    *ks;
-	struct ks8995_pdata     *pdata;
-	int     err;
+	struct ks8995_switch *ks;
+	int err;
 	int variant = spi_get_device_id(spi)->driver_data;
 
-	/* Chip description */
-	pdata = spi->dev.platform_data;
-
 	if (variant >= max_variant) {
 		dev_err(&spi->dev, "bad chip variant %d\n", variant);
 		return -ENODEV;
@@ -370,10 +388,42 @@ static int ks8995_probe(struct spi_device *spi)
 		return -ENOMEM;
 
 	mutex_init(&ks->lock);
-	ks->pdata = pdata;
 	ks->spi = spi_dev_get(spi);
 	ks->chip = &ks8995_chip[variant];
 
+	if (ks->spi->dev.of_node) {
+		ks->pdata = devm_kzalloc(&spi->dev, sizeof(*ks->pdata),
+					 GFP_KERNEL);
+		if (!ks->pdata)
+			return -ENOMEM;
+
+		ks->pdata->reset_gpio = -1;
+
+		ks8995_parse_dt(ks);
+	}
+
+	if (!ks->pdata)
+		ks->pdata = spi->dev.platform_data;
+
+	/* de-assert switch reset */
+	if (ks->pdata && gpio_is_valid(ks->pdata->reset_gpio)) {
+		unsigned long flags;
+
+		flags = (ks->pdata->reset_gpio_flags == OF_GPIO_ACTIVE_LOW ?
+			 GPIOF_ACTIVE_LOW : 0);
+
+		err = devm_gpio_request_one(&spi->dev,
+					    ks->pdata->reset_gpio,
+					    flags, "switch-reset");
+		if (err) {
+			dev_err(&spi->dev,
+				"failed to get reset-gpios: %d\n", err);
+			return -EIO;
+		}
+
+		gpiod_set_value(gpio_to_desc(ks->pdata->reset_gpio), 0);
+	}
+
 	spi_set_drvdata(spi, ks);
 
 	spi->mode = SPI_MODE_0;
@@ -414,11 +464,14 @@ static int ks8995_remove(struct spi_device *spi)
 
 	sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr);
 
+	/* assert reset */
+	if (ks->pdata && gpio_is_valid(ks->pdata->reset_gpio))
+		gpiod_set_value(gpio_to_desc(ks->pdata->reset_gpio), 1);
+
 	return 0;
 }
 
 /* ------------------------------------------------------------------------ */
-
 static struct spi_driver ks8995_driver = {
 	.driver = {
 		.name	    = "spi-ks8995",
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/6] net: phy: spi_ks8995: generalize creation of SPI commands
  2016-02-08 17:35 [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch Helmut Buchsbaum
                   ` (2 preceding siblings ...)
  2016-02-08 17:35 ` [PATCH v2 3/6] net: phy: spi_ks8995: add support for resetting switch using GPIO Helmut Buchsbaum
@ 2016-02-08 17:35 ` Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 5/6] net: phy: spi_ks8995: add support for MICREL KSZ8795CLX Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995 Helmut Buchsbaum
  5 siblings, 0 replies; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-08 17:35 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev, Helmut Buchsbaum

Prepare creating SPI reads and writes for other switch families.
The KS8995 family uses the straight forward
	<8bit CMD><8bit ADDR>
sequence.
To be able to support KSZ8795 family, which uses
	<3bit CMD><12bit ADDR><1 bit TR>
make the SPI command creation chip variant dependent.

Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
---
 drivers/net/phy/spi_ks8995.c | 46 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
index 04d468f..f866786 100644
--- a/drivers/net/phy/spi_ks8995.c
+++ b/drivers/net/phy/spi_ks8995.c
@@ -105,6 +105,8 @@ struct ks8995_chip_params {
 	int family_id;
 	int chip_id;
 	int regs_size;
+	int addr_width;
+	int addr_shift;
 };
 
 static const struct ks8995_chip_params ks8995_chip[] = {
@@ -113,12 +115,16 @@ static const struct ks8995_chip_params ks8995_chip[] = {
 		.family_id = FAMILY_KS8995,
 		.chip_id = KS8995_CHIP_ID,
 		.regs_size = KS8995_REGS_SIZE,
+		.addr_width = 8,
+		.addr_shift = 0,
 	},
 	[ksz8864] = {
 		.name = "KSZ8864RMN",
 		.family_id = FAMILY_KS8995,
 		.chip_id = KSZ8864_CHIP_ID,
 		.regs_size = KSZ8864_REGS_SIZE,
+		.addr_width = 8,
+		.addr_shift = 0,
 	},
 };
 
@@ -153,20 +159,44 @@ static inline u8 get_chip_rev(u8 val)
 	return (val >> ID1_REVISION_S) & ID1_REVISION_M;
 }
 
+/* create_spi_cmd - create a chip specific SPI command header
+ * @ks: pointer to switch instance
+ * @cmd: SPI command for switch
+ * @address: register address for command
+ *
+ * Different chip families use different bit pattern to address the switches
+ * registers:
+ *
+ * KS8995: 8bit command + 8bit address
+ * KSZ8795: 3bit command + 12bit address + 1bit TR (?)
+ */
+static inline __be16 create_spi_cmd(struct ks8995_switch *ks, int cmd,
+				    unsigned address)
+{
+	u16 result = cmd;
+
+	/* make room for address (incl. address shift) */
+	result <<= ks->chip->addr_width + ks->chip->addr_shift;
+	/* add address */
+	result |= address << ks->chip->addr_shift;
+	/* SPI protocol needs big endian */
+	return cpu_to_be16(result);
+}
 /* ------------------------------------------------------------------------ */
 static int ks8995_read(struct ks8995_switch *ks, char *buf,
 		 unsigned offset, size_t count)
 {
-	u8 cmd[2];
+	__be16 cmd;
 	struct spi_transfer t[2];
 	struct spi_message m;
 	int err;
 
+	cmd = create_spi_cmd(ks, KS8995_CMD_READ, offset);
 	spi_message_init(&m);
 
 	memset(&t, 0, sizeof(t));
 
-	t[0].tx_buf = cmd;
+	t[0].tx_buf = &cmd;
 	t[0].len = sizeof(cmd);
 	spi_message_add_tail(&t[0], &m);
 
@@ -174,9 +204,6 @@ static int ks8995_read(struct ks8995_switch *ks, char *buf,
 	t[1].len = count;
 	spi_message_add_tail(&t[1], &m);
 
-	cmd[0] = KS8995_CMD_READ;
-	cmd[1] = offset;
-
 	mutex_lock(&ks->lock);
 	err = spi_sync(ks->spi, &m);
 	mutex_unlock(&ks->lock);
@@ -184,20 +211,20 @@ static int ks8995_read(struct ks8995_switch *ks, char *buf,
 	return err ? err : count;
 }
 
-
 static int ks8995_write(struct ks8995_switch *ks, char *buf,
 		 unsigned offset, size_t count)
 {
-	u8 cmd[2];
+	__be16 cmd;
 	struct spi_transfer t[2];
 	struct spi_message m;
 	int err;
 
+	cmd = create_spi_cmd(ks, KS8995_CMD_WRITE, offset);
 	spi_message_init(&m);
 
 	memset(&t, 0, sizeof(t));
 
-	t[0].tx_buf = cmd;
+	t[0].tx_buf = &cmd;
 	t[0].len = sizeof(cmd);
 	spi_message_add_tail(&t[0], &m);
 
@@ -205,9 +232,6 @@ static int ks8995_write(struct ks8995_switch *ks, char *buf,
 	t[1].len = count;
 	spi_message_add_tail(&t[1], &m);
 
-	cmd[0] = KS8995_CMD_WRITE;
-	cmd[1] = offset;
-
 	mutex_lock(&ks->lock);
 	err = spi_sync(ks->spi, &m);
 	mutex_unlock(&ks->lock);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/6] net: phy: spi_ks8995: add support for MICREL KSZ8795CLX
  2016-02-08 17:35 [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch Helmut Buchsbaum
                   ` (3 preceding siblings ...)
  2016-02-08 17:35 ` [PATCH v2 4/6] net: phy: spi_ks8995: generalize creation of SPI commands Helmut Buchsbaum
@ 2016-02-08 17:35 ` Helmut Buchsbaum
  2016-02-08 17:35 ` [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995 Helmut Buchsbaum
  5 siblings, 0 replies; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-08 17:35 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev, Helmut Buchsbaum

Add support for MICREL KSZ8795CLX Integrated 5-Port, 10-/100-Managed
Ethernet Switch with Gigabit GMII/RGMII and MII/RMII interfaces.

Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
---
 drivers/net/phy/spi_ks8995.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
index f866786..c2d6c23 100644
--- a/drivers/net/phy/spi_ks8995.c
+++ b/drivers/net/phy/spi_ks8995.c
@@ -77,6 +77,7 @@
 
 #define KS8995_REGS_SIZE	0x80
 #define KSZ8864_REGS_SIZE	0x100
+#define KSZ8795_REGS_SIZE	0x100
 
 #define ID1_CHIPID_M		0xf
 #define ID1_CHIPID_S		4
@@ -85,9 +86,11 @@
 #define ID1_START_SW		1	/* start the switch */
 
 #define FAMILY_KS8995		0x95
+#define FAMILY_KSZ8795		0x87
 #define CHIPID_M		0
 #define KS8995_CHIP_ID		0x00
 #define KSZ8864_CHIP_ID		0x01
+#define KSZ8795_CHIP_ID		0x09
 
 #define KS8995_CMD_WRITE	0x02U
 #define KS8995_CMD_READ		0x03U
@@ -97,6 +100,7 @@
 enum ks8995_chip_variant {
 	ks8995,
 	ksz8864,
+	ksz8795,
 	max_variant
 };
 
@@ -126,6 +130,14 @@ static const struct ks8995_chip_params ks8995_chip[] = {
 		.addr_width = 8,
 		.addr_shift = 0,
 	},
+	[ksz8795] = {
+		.name = "KSZ8795CLX",
+		.family_id = FAMILY_KSZ8795,
+		.chip_id = KSZ8795_CHIP_ID,
+		.regs_size = KSZ8795_REGS_SIZE,
+		.addr_width = 12,
+		.addr_shift = 1,
+	},
 };
 
 struct ks8995_pdata {
@@ -145,6 +157,7 @@ struct ks8995_switch {
 static const struct spi_device_id ks8995_id[] = {
 	{"ks8995", ks8995},
 	{"ksz8864", ksz8864},
+	{"ksz8795", ksz8795},
 	{ }
 };
 MODULE_DEVICE_TABLE(spi, ks8995_id);
@@ -358,6 +371,22 @@ static int ks8995_get_revision(struct ks8995_switch *ks)
 			err = -ENODEV;
 		}
 		break;
+	case FAMILY_KSZ8795:
+		/* try reading chip id at CHIP ID1 */
+		err = ks8995_read_reg(ks, KS8995_REG_ID1, &id1);
+		if (err) {
+			err = -EIO;
+			goto err_out;
+		}
+
+		if (get_chip_id(id1) == ks->chip->chip_id) {
+			ks->revision_id = get_chip_rev(id1);
+		} else {
+			dev_err(&ks->spi->dev, "unsupported chip id for KSZ8795 family: 0x%02x\n",
+				id1);
+			err = -ENODEV;
+		}
+		break;
 	default:
 		dev_err(&ks->spi->dev, "unsupported family id: 0x%02x\n", id0);
 		err = -ENODEV;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995
  2016-02-08 17:35 [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch Helmut Buchsbaum
                   ` (4 preceding siblings ...)
  2016-02-08 17:35 ` [PATCH v2 5/6] net: phy: spi_ks8995: add support for MICREL KSZ8795CLX Helmut Buchsbaum
@ 2016-02-08 17:35 ` Helmut Buchsbaum
  2016-02-08 18:44   ` Sergei Shtylyov
  5 siblings, 1 reply; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-08 17:35 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev, Helmut Buchsbaum

Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
---
 .../devicetree/bindings/net/micrel-ks8995.txt        | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/micrel-ks8995.txt

diff --git a/Documentation/devicetree/bindings/net/micrel-ks8995.txt b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
new file mode 100644
index 0000000..7f11ca6
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
@@ -0,0 +1,20 @@
+Micrel KS8995 SPI controlled Ethernet Switch families
+
+Required properties (according to spi-bus.txt):
+- compatible: either "micrel,ks8995", "micrel,ksz8864" or "micrel,ksz8795"
+
+Optional properties:
+- reset-gpios : phandle of gpio that will be used to reset chip during probe
+
+Example:
+
+spi-master {
+	...
+	ksz8795 {
+		compatible = "micrel,ksz8795";
+
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		reset-gpios = <&gpio0 46 1>;
+	};
+};
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995
  2016-02-08 17:35 ` [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995 Helmut Buchsbaum
@ 2016-02-08 18:44   ` Sergei Shtylyov
  2016-02-09  8:07     ` Helmut Buchsbaum
  0 siblings, 1 reply; 11+ messages in thread
From: Sergei Shtylyov @ 2016-02-08 18:44 UTC (permalink / raw)
  To: Helmut Buchsbaum, David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev

Hello.

On 02/08/2016 08:35 PM, Helmut Buchsbaum wrote:

> Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
> ---
>   .../devicetree/bindings/net/micrel-ks8995.txt        | 20 ++++++++++++++++++++
>   1 file changed, 20 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/net/micrel-ks8995.txt
>
> diff --git a/Documentation/devicetree/bindings/net/micrel-ks8995.txt b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
> new file mode 100644
> index 0000000..7f11ca6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
> @@ -0,0 +1,20 @@
> +Micrel KS8995 SPI controlled Ethernet Switch families
> +
> +Required properties (according to spi-bus.txt):
> +- compatible: either "micrel,ks8995", "micrel,ksz8864" or "micrel,ksz8795"
> +
> +Optional properties:
> +- reset-gpios : phandle of gpio that will be used to reset chip during probe
> +
> +Example:
> +
> +spi-master {
> +	...
> +	ksz8795 {

    ePAPR tells to name the nodes generically, according to their function.

> +		compatible = "micrel,ksz8795";
> +
> +		reg = <0>;
> +		spi-max-frequency = <50000000>;
> +		reset-gpios = <&gpio0 46 1>;
> +	};
> +};

MBR, Sergei

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995
  2016-02-08 18:44   ` Sergei Shtylyov
@ 2016-02-09  8:07     ` Helmut Buchsbaum
  2016-02-09 10:43       ` Sergei Shtylyov
  0 siblings, 1 reply; 11+ messages in thread
From: Helmut Buchsbaum @ 2016-02-09  8:07 UTC (permalink / raw)
  To: Sergei Shtylyov, David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev

On 02/08/2016 07:44 PM, Sergei Shtylyov wrote:
> Hello.
>
> On 02/08/2016 08:35 PM, Helmut Buchsbaum wrote:
>
>> Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
>> ---
>>   .../devicetree/bindings/net/micrel-ks8995.txt        | 20
>> ++++++++++++++++++++
>>   1 file changed, 20 insertions(+)
>>   create mode 100644
>> Documentation/devicetree/bindings/net/micrel-ks8995.txt
>>
>> diff --git a/Documentation/devicetree/bindings/net/micrel-ks8995.txt
>> b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
>> new file mode 100644
>> index 0000000..7f11ca6
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
>> @@ -0,0 +1,20 @@
>> +Micrel KS8995 SPI controlled Ethernet Switch families
>> +
>> +Required properties (according to spi-bus.txt):
>> +- compatible: either "micrel,ks8995", "micrel,ksz8864" or
>> "micrel,ksz8795"
>> +
>> +Optional properties:
>> +- reset-gpios : phandle of gpio that will be used to reset chip
>> during probe
>> +
>> +Example:
>> +
>> +spi-master {
>> +    ...
>> +    ksz8795 {
>
>     ePAPR tells to name the nodes generically, according to their function.
>
>> +        compatible = "micrel,ksz8795";
>> +
>> +        reg = <0>;
>> +        spi-max-frequency = <50000000>;
>> +        reset-gpios = <&gpio0 46 1>;
>> +    };
>> +};
>
> MBR, Sergei
>
Hello Sergei,

just to avoid any misunderstandings: you refer to ePAPR, ch. 2.2.1 Node 
Names. Your definitely right, I'll correct the naming in my example!

Thanks,
Helmut

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/6] net: phy: spi_ks8995: add support for resetting switch using GPIO
  2016-02-08 17:35 ` [PATCH v2 3/6] net: phy: spi_ks8995: add support for resetting switch using GPIO Helmut Buchsbaum
@ 2016-02-09  8:32   ` Andrew Lunn
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Lunn @ 2016-02-09  8:32 UTC (permalink / raw)
  To: Helmut Buchsbaum; +Cc: David S. Miller, Florian Fainelli, netdev

On Mon, Feb 08, 2016 at 06:35:34PM +0100, Helmut Buchsbaum wrote:
> When using device tree it is no more possible to reset the PHY at board
> level. Furthermore, doing in the driver allows to power down the switch
> when it is not used any more.
> 
> The patch introduces a new optional property "reset-gpios" denoting an
> appropriate GPIO handle, e.g.:
> 
> reset-gpios = <&gpio0 46 1>

Hi Helmut

Since you are respinning, please change the 1 to GPIO_ACTIVE_LOW.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

Thanks
	Andrew

> 
> Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
> ---
>  drivers/net/phy/spi_ks8995.c | 71 ++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 62 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
> index 2803c8e..04d468f 100644
> --- a/drivers/net/phy/spi_ks8995.c
> +++ b/drivers/net/phy/spi_ks8995.c
> @@ -18,6 +18,9 @@
>  #include <linux/module.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/of.h>
> +#include <linux/gpio.h>
> +#include <linux/of_gpio.h>
>  
>  #include <linux/spi/spi.h>
>  
> @@ -120,7 +123,8 @@ static const struct ks8995_chip_params ks8995_chip[] = {
>  };
>  
>  struct ks8995_pdata {
> -	/* not yet implemented */
> +	int reset_gpio;
> +	enum of_gpio_flags reset_gpio_flags;
>  };
>  
>  struct ks8995_switch {
> @@ -339,6 +343,24 @@ err_out:
>  	return err;
>  }
>  
> +/* ks8995_parse_dt - setup platform data from devicetree
> + * @ks: pointer to switch instance
> + *
> + * Parses supported DT properties and sets up platform data
> + * accordingly.
> + */
> +static void ks8995_parse_dt(struct ks8995_switch *ks)
> +{
> +	struct device_node *np = ks->spi->dev.of_node;
> +	struct ks8995_pdata *pdata = ks->pdata;
> +
> +	if (!np)
> +		return;
> +
> +	pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0,
> +		&pdata->reset_gpio_flags);
> +}
> +
>  static const struct bin_attribute ks8995_registers_attr = {
>  	.attr = {
>  		.name   = "registers",
> @@ -352,14 +374,10 @@ static const struct bin_attribute ks8995_registers_attr = {
>  /* ------------------------------------------------------------------------ */
>  static int ks8995_probe(struct spi_device *spi)
>  {
> -	struct ks8995_switch    *ks;
> -	struct ks8995_pdata     *pdata;
> -	int     err;
> +	struct ks8995_switch *ks;
> +	int err;
>  	int variant = spi_get_device_id(spi)->driver_data;
>  
> -	/* Chip description */
> -	pdata = spi->dev.platform_data;
> -
>  	if (variant >= max_variant) {
>  		dev_err(&spi->dev, "bad chip variant %d\n", variant);
>  		return -ENODEV;
> @@ -370,10 +388,42 @@ static int ks8995_probe(struct spi_device *spi)
>  		return -ENOMEM;
>  
>  	mutex_init(&ks->lock);
> -	ks->pdata = pdata;
>  	ks->spi = spi_dev_get(spi);
>  	ks->chip = &ks8995_chip[variant];
>  
> +	if (ks->spi->dev.of_node) {
> +		ks->pdata = devm_kzalloc(&spi->dev, sizeof(*ks->pdata),
> +					 GFP_KERNEL);
> +		if (!ks->pdata)
> +			return -ENOMEM;
> +
> +		ks->pdata->reset_gpio = -1;
> +
> +		ks8995_parse_dt(ks);
> +	}
> +
> +	if (!ks->pdata)
> +		ks->pdata = spi->dev.platform_data;
> +
> +	/* de-assert switch reset */
> +	if (ks->pdata && gpio_is_valid(ks->pdata->reset_gpio)) {
> +		unsigned long flags;
> +
> +		flags = (ks->pdata->reset_gpio_flags == OF_GPIO_ACTIVE_LOW ?
> +			 GPIOF_ACTIVE_LOW : 0);
> +
> +		err = devm_gpio_request_one(&spi->dev,
> +					    ks->pdata->reset_gpio,
> +					    flags, "switch-reset");
> +		if (err) {
> +			dev_err(&spi->dev,
> +				"failed to get reset-gpios: %d\n", err);
> +			return -EIO;
> +		}
> +
> +		gpiod_set_value(gpio_to_desc(ks->pdata->reset_gpio), 0);
> +	}
> +
>  	spi_set_drvdata(spi, ks);
>  
>  	spi->mode = SPI_MODE_0;
> @@ -414,11 +464,14 @@ static int ks8995_remove(struct spi_device *spi)
>  
>  	sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr);
>  
> +	/* assert reset */
> +	if (ks->pdata && gpio_is_valid(ks->pdata->reset_gpio))
> +		gpiod_set_value(gpio_to_desc(ks->pdata->reset_gpio), 1);
> +
>  	return 0;
>  }
>  
>  /* ------------------------------------------------------------------------ */
> -
>  static struct spi_driver ks8995_driver = {
>  	.driver = {
>  		.name	    = "spi-ks8995",
> -- 
> 2.1.4
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995
  2016-02-09  8:07     ` Helmut Buchsbaum
@ 2016-02-09 10:43       ` Sergei Shtylyov
  0 siblings, 0 replies; 11+ messages in thread
From: Sergei Shtylyov @ 2016-02-09 10:43 UTC (permalink / raw)
  To: Helmut Buchsbaum, David S. Miller, Florian Fainelli, Andrew Lunn; +Cc: netdev

On 2/9/2016 11:07 AM, Helmut Buchsbaum wrote:

>>> Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
>>> ---
>>>   .../devicetree/bindings/net/micrel-ks8995.txt        | 20
>>> ++++++++++++++++++++
>>>   1 file changed, 20 insertions(+)
>>>   create mode 100644
>>> Documentation/devicetree/bindings/net/micrel-ks8995.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/micrel-ks8995.txt
>>> b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
>>> new file mode 100644
>>> index 0000000..7f11ca6
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/net/micrel-ks8995.txt
>>> @@ -0,0 +1,20 @@
>>> +Micrel KS8995 SPI controlled Ethernet Switch families
>>> +
>>> +Required properties (according to spi-bus.txt):
>>> +- compatible: either "micrel,ks8995", "micrel,ksz8864" or
>>> "micrel,ksz8795"
>>> +
>>> +Optional properties:
>>> +- reset-gpios : phandle of gpio that will be used to reset chip
>>> during probe
>>> +
>>> +Example:
>>> +
>>> +spi-master {
>>> +    ...
>>> +    ksz8795 {
>>
>>     ePAPR tells to name the nodes generically, according to their function.
>>
>>> +        compatible = "micrel,ksz8795";
>>> +
>>> +        reg = <0>;
>>> +        spi-max-frequency = <50000000>;
>>> +        reset-gpios = <&gpio0 46 1>;
>>> +    };
>>> +};
>>
>> MBR, Sergei
>>
> Hello Sergei,
>
> just to avoid any misunderstandings: you refer to ePAPR, ch. 2.2.1 Node Names.

    "2.2.2, Generic Names Recommendation", actually. :-)

> Your definitely right, I'll correct the naming in my example!

    TIA.

> Thanks,
> Helmut

MBR, Sergei

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-02-09 10:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-08 17:35 [PATCH v2 0/6] Add support for MICREL KSZ8795CLX 5-port switch Helmut Buchsbaum
2016-02-08 17:35 ` [PATCH v2 1/6] net: phy: spi_ks8995: introduce spi_device_id table Helmut Buchsbaum
2016-02-08 17:35 ` [PATCH v2 2/6] net: phy: spi_ks8995: verify chip and determine revision Helmut Buchsbaum
2016-02-08 17:35 ` [PATCH v2 3/6] net: phy: spi_ks8995: add support for resetting switch using GPIO Helmut Buchsbaum
2016-02-09  8:32   ` Andrew Lunn
2016-02-08 17:35 ` [PATCH v2 4/6] net: phy: spi_ks8995: generalize creation of SPI commands Helmut Buchsbaum
2016-02-08 17:35 ` [PATCH v2 5/6] net: phy: spi_ks8995: add support for MICREL KSZ8795CLX Helmut Buchsbaum
2016-02-08 17:35 ` [PATCH v2 6/6] dt-bindings: net: ks8995: add bindings documentation for ks8995 Helmut Buchsbaum
2016-02-08 18:44   ` Sergei Shtylyov
2016-02-09  8:07     ` Helmut Buchsbaum
2016-02-09 10:43       ` Sergei Shtylyov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.