mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Trent Piepho <trent.piepho@igorinstitute.com>
To: Barebox List <barebox@lists.infradead.org>
Cc: Trent Piepho <trent.piepho@igorinstitute.com>
Subject: [PATCH] net: ksz8864: Add support for KSZ87xx switches
Date: Mon, 11 Oct 2021 11:42:13 -0700
Message-ID: <20211011184213.854061-1-trent.piepho@igorinstitute.com> (raw)

This adds support for the ksz8765, ksz8794, and ksz8795 switches.

IDs for OF bindings are added.  The base chip type is "ksz8795", the
same as the Linux driver, for the ksz87xx switches added here.
"ksz8864rmn" is used for the existing switch.

The registers for these switch chips, as least as far as this simple
driver is concerned, are the same as the existing ksz8864 support.

The difference in the ksz87xx chips is the format of the command and
address bytes:

C = command
A = address (used bits)
a = address (unused bits)
p = turn around padding bit

ksz8864: 00000CCC  AAAAAAAA
ksz8795: CCCaaaaA  AAAAAAAp

CCC and AAAAAAAA are the same, it's just where they are that changes.
This is parameterized in the read/write reg functions by using two
values for the address width and pad width.

Signed-off-by: Trent Piepho <trent.piepho@igorinstitute.com>
---
 drivers/net/ksz8864rmn.c | 66 ++++++++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ksz8864rmn.c b/drivers/net/ksz8864rmn.c
index 85063ff0d..72ab86579 100644
--- a/drivers/net/ksz8864rmn.c
+++ b/drivers/net/ksz8864rmn.c
@@ -31,48 +31,55 @@
 #define CMD_WRITE		0x02
 #define CMD_READ		0x03
 
+enum ksz_type {
+	unknown,
+	ksz87,
+	ksz88
+};
+
 struct micrel_switch_priv {
 	struct cdev             cdev;
 	struct spi_device       *spi;
 	unsigned int		p_enable;
+	unsigned int		addr_width;
+	unsigned int		pad;
 };
 
-static int micrel_switch_read_reg(struct spi_device *spi, uint8_t reg)
+static int micrel_switch_read_reg(const struct micrel_switch_priv *priv, uint8_t reg)
 {
 	uint8_t tx[2];
 	uint8_t rx[1];
 	int ret;
 
-	tx[0] = CMD_READ;
-	tx[1] = reg;
+	tx[0] = CMD_READ << (priv->addr_width + priv->pad - 8) | reg >> (8 - priv->pad);
+	tx[1] = reg << priv->pad;
 
-	ret = spi_write_then_read(spi, tx, 2, rx, 1);
+	ret = spi_write_then_read(priv->spi, tx, 2, rx, 1);
 	if (ret < 0)
 		return ret;
 
 	return rx[0];
 }
 
-static void micrel_switch_write_reg(struct spi_device *spi, uint8_t reg, uint8_t val)
+static void micrel_switch_write_reg(const struct micrel_switch_priv *priv, uint8_t reg, uint8_t val)
 {
 	uint8_t tx[3];
 
-	tx[0] = CMD_WRITE;
-	tx[1] = reg;
+	tx[0] = CMD_WRITE << (priv->addr_width + priv->pad - 8) | reg >> (8 - priv->pad);
+	tx[1] = reg << priv->pad;
 	tx[2] = val;
 
-	spi_write_then_read(spi, tx, 3, NULL, 0);
+	spi_write_then_read(priv->spi, tx, 3, NULL, 0);
 }
 
 static int micrel_switch_enable_set(struct param_d *param, void *_priv)
 {
 	struct micrel_switch_priv *priv = _priv;
-	struct spi_device *spi = priv->spi;
 
 	if (priv->p_enable)
-		micrel_switch_write_reg(spi, REG_ID1, 1);
+		micrel_switch_write_reg(priv, REG_ID1, 1);
 	else
-		micrel_switch_write_reg(spi, REG_ID1, 0);
+		micrel_switch_write_reg(priv, REG_ID1, 0);
 
 	return 0;
 }
@@ -84,7 +91,7 @@ static ssize_t micel_switch_read(struct cdev *cdev, void *_buf, size_t count, lo
 	struct micrel_switch_priv *priv = cdev->priv;
 
 	for (i = 0; i < count; i++) {
-		ret = micrel_switch_read_reg(priv->spi, offset);
+		ret = micrel_switch_read_reg(priv, offset);
 		if (ret < 0)
 			return ret;
 		*buf = ret;
@@ -102,7 +109,7 @@ static ssize_t micel_switch_write(struct cdev *cdev, const void *_buf, size_t co
 	struct micrel_switch_priv *priv = cdev->priv;
 
 	for (i = 0; i < count; i++) {
-		micrel_switch_write_reg(priv->spi, offset, *buf);
+		micrel_switch_write_reg(priv, offset, *buf);
 		buf++;
 		offset++;
 	}
@@ -119,6 +126,11 @@ static int micrel_switch_probe(struct device_d *dev)
 {
 	struct micrel_switch_priv *priv;
 	int ret = 0;
+	enum ksz_type kind = (enum ksz_type)device_get_match_data(dev);
+	uint8_t id;
+
+	if (kind == unknown)
+		return -ENODEV;
 
 	priv = xzalloc(sizeof(*priv));
 
@@ -128,12 +140,27 @@ static int micrel_switch_probe(struct device_d *dev)
 	priv->spi->mode = SPI_MODE_0;
 	priv->spi->bits_per_word = 8;
 
-	ret = micrel_switch_read_reg(priv->spi, REG_ID0);
+	switch (kind) {
+	case ksz87:
+		priv->addr_width = 12;
+		priv->pad = 1;
+		id = 0x87;
+		break;
+	case ksz88:
+		priv->addr_width = 8;
+		priv->pad = 0;
+		id = 0x95;
+		break;
+	default:
+		return -ENODEV;
+	};
+
+	ret = micrel_switch_read_reg(priv, REG_ID0);
 	if (ret < 0) {
 		dev_err(&priv->spi->dev, "failed to read device id\n");
 		return ret;
 	}
-	if (ret != 0x95) {
+	if (ret != id) {
 		dev_err(&priv->spi->dev, "unknown device id: %02x\n", ret);
 		return -ENODEV;
 	}
@@ -149,13 +176,20 @@ static int micrel_switch_probe(struct device_d *dev)
 			NULL, &priv->p_enable, priv);
 
 	priv->p_enable = 1;
-	micrel_switch_write_reg(priv->spi, REG_ID1, 1);
+	micrel_switch_write_reg(priv, REG_ID1, 1);
 
 	return 0;
 }
 
+static const struct platform_device_id ksz_ids[] = {
+	{ .name = "ksz8864rmn", .driver_data = ksz88 },
+	{ .name = "ksz8795", .driver_data = ksz87 },
+	{ }
+};
+
 static struct driver_d micrel_switch_driver = {
 	.name  = "ksz8864rmn",
 	.probe = micrel_switch_probe,
+	.id_table = ksz_ids,
 };
 device_spi_driver(micrel_switch_driver);
-- 
2.31.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


             reply	other threads:[~2021-10-11 18:44 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-11 18:42 Trent Piepho [this message]
2021-10-12  7:45 ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211011184213.854061-1-trent.piepho@igorinstitute.com \
    --to=trent.piepho@igorinstitute.com \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

mail archive of the barebox mailing list

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://lore.barebox.org/barebox/0 barebox/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 barebox barebox/ https://lore.barebox.org/barebox \
		barebox@lists.infradead.org barebox@lists.infradead.org
	public-inbox-index barebox

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git