{"id":811179,"url":"http://patchwork.ozlabs.org/api/patches/811179/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/93AF473E2DA327428DE3D46B72B1E9FD41121A95@CHN-SV-EXMX02.mchp-main.com/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/projects/7/?format=json","name":"Linux network development","link_name":"netdev","list_id":"netdev.vger.kernel.org","list_email":"netdev@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<93AF473E2DA327428DE3D46B72B1E9FD41121A95@CHN-SV-EXMX02.mchp-main.com>","list_archive_url":null,"date":"2017-09-07T21:17:33","name":"[RFC,5/5] Add KSZ8795 SPI driver","commit_ref":null,"pull_url":null,"state":"rfc","archived":true,"hash":"07e2d615b8bc290b701bf2d528bd334c48f32df4","submitter":{"id":72262,"url":"http://patchwork.ozlabs.org/api/people/72262/?format=json","name":"","email":"Tristram.Ha@microchip.com"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/93AF473E2DA327428DE3D46B72B1E9FD41121A95@CHN-SV-EXMX02.mchp-main.com/mbox/","series":[{"id":2066,"url":"http://patchwork.ozlabs.org/api/series/2066/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=2066","date":"2017-09-07T21:17:33","name":"[RFC,1/5] Add KSZ8795 switch driver support in Kconfig","version":1,"mbox":"http://patchwork.ozlabs.org/series/2066/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/811179/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/811179/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xpCwY5vzpz9s3T\n\tfor <patchwork-incoming@ozlabs.org>;\n\tFri,  8 Sep 2017 07:18:05 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S932401AbdIGVRw convert rfc822-to-8bit (ORCPT\n\t<rfc822;patchwork-incoming@ozlabs.org>);\n\tThu, 7 Sep 2017 17:17:52 -0400","from esa5.microchip.iphmx.com ([216.71.150.166]:15489 \"EHLO\n\tesa5.microchip.iphmx.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1756104AbdIGVRu (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Thu, 7 Sep 2017 17:17:50 -0400","from exsmtp01.microchip.com (HELO email.microchip.com)\n\t([198.175.253.37])\n\tby esa5.microchip.iphmx.com with ESMTP/TLS/AES128-SHA;\n\t07 Sep 2017 14:17:35 -0700","from CHN-SV-EXMX02.mchp-main.com ([fe80::7dfe:3761:863e:3963]) by\n\tCHN-SV-EXCH01.mchp-main.com ([fe80::9840:ffdf:ec5:1335%29]) with\n\tmapi id 14.03.0352.000; Thu, 7 Sep 2017 14:17:34 -0700"],"X-IronPort-AV":"E=Sophos;i=\"5.42,360,1500966000\"; d=\"scan'208\";a=\"4516676\"","From":"<Tristram.Ha@microchip.com>","To":"<andrew@lunn.ch>, <muvarov@gmail.com>, <pavel@ucw.cz>,\n\t<nathan.leigh.conrad@gmail.com>,\n\t<vivien.didelot@savoirfairelinux.com>, <f.fainelli@gmail.com>,\n\t<netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,\n\t<Woojung.Huh@microchip.com>","Subject":"[PATCH RFC 5/5] Add KSZ8795 SPI driver","Thread-Topic":"[PATCH RFC 5/5] Add KSZ8795 SPI driver","Thread-Index":"AdMoGvAezSITRaBURlyseL7iLp2KMAAA4j3g","Date":"Thu, 7 Sep 2017 21:17:33 +0000","Message-ID":"<93AF473E2DA327428DE3D46B72B1E9FD41121A95@CHN-SV-EXMX02.mchp-main.com>","Accept-Language":"en-US","Content-Language":"en-US","X-MS-Has-Attach":"","X-MS-TNEF-Correlator":"","x-originating-ip":"[10.10.76.4]","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"8BIT","MIME-Version":"1.0","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"From: Tristram Ha <Tristram.Ha@microchip.com>\n\nAdd KSZ8795 switch support with SPI access.\n\nSigned-off-by: Tristram Ha <Tristram.Ha@microchip.com>\n---","diff":"diff --git a/drivers/net/dsa/microchip/ksz8795_spi.c b/drivers/net/dsa/microchip/ksz8795_spi.c\nnew file mode 100644\nindex 0000000..0f9c731\n--- /dev/null\n+++ b/drivers/net/dsa/microchip/ksz8795_spi.c\n@@ -0,0 +1,229 @@\n+/*\n+ * Microchip KSZ8795 series register access through SPI\n+ *\n+ * Copyright (C) 2017 Microchip Technology Inc.\n+ *\tTristram Ha <Tristram.Ha@microchip.com>\n+ *\n+ * Permission to use, copy, modify, and/or distribute this software for \n+any\n+ * purpose with or without fee is hereby granted, provided that the \n+above\n+ * copyright notice and this permission notice appear in all copies.\n+ *\n+ * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL \n+WARRANTIES\n+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE \n+FOR\n+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY \n+DAMAGES\n+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN \n+AN\n+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT \n+OF\n+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n+ */\n+\n+#include <asm/unaligned.h>\n+\n+#include <linux/delay.h>\n+#include <linux/kernel.h>\n+#include <linux/module.h>\n+#include <linux/spi/spi.h>\n+\n+#include \"ksz_priv.h\"\n+\n+int ksz8795_switch_register(struct ksz_device *dev);\n+\n+/* SPI frame opcodes */\n+#define KS_SPIOP_RD\t\t\t3\n+#define KS_SPIOP_WR\t\t\t2\n+\n+#define SPI_ADDR_S\t\t\t12\n+#define SPI_ADDR_M\t\t\t(BIT(SPI_ADDR_S) - 1)\n+#define SPI_TURNAROUND_S\t\t1\n+\n+/* Enough to read all switch registers. */\n+#define SPI_TX_BUF_LEN\t\t\t0x100\n+\n+static int ksz_spi_read_reg(struct spi_device *spi, u32 reg, u8 *val,\n+\t\t\t    unsigned int len)\n+{\n+\tu16 txbuf;\n+\tint ret;\n+\n+\ttxbuf = reg & SPI_ADDR_M;\n+\ttxbuf |= KS_SPIOP_RD << SPI_ADDR_S;\n+\ttxbuf <<= SPI_TURNAROUND_S;\n+\ttxbuf = cpu_to_be16(txbuf);\n+\n+\tret = spi_write_then_read(spi, &txbuf, 2, val, len);\n+\treturn ret;\n+}\n+\n+static int ksz_spi_read(struct ksz_device *dev, u32 reg, u8 *data,\n+\t\t\tunsigned int len)\n+{\n+\tstruct spi_device *spi = dev->priv;\n+\n+\treturn ksz_spi_read_reg(spi, reg, data, len); }\n+\n+static int ksz_spi_read8(struct ksz_device *dev, u32 reg, u8 *val) {\n+\treturn ksz_spi_read(dev, reg, val, 1); }\n+\n+static int ksz_spi_read16(struct ksz_device *dev, u32 reg, u16 *val) {\n+\tint ret = ksz_spi_read(dev, reg, (u8 *)val, 2);\n+\n+\tif (!ret)\n+\t\t*val = be16_to_cpu(*val);\n+\n+\treturn ret;\n+}\n+\n+static int ksz_spi_read32(struct ksz_device *dev, u32 reg, u32 *val) {\n+\tint ret = ksz_spi_read(dev, reg, (u8 *)val, 4);\n+\n+\tif (!ret)\n+\t\t*val = be32_to_cpu(*val);\n+\n+\treturn ret;\n+}\n+\n+static int ksz_spi_write_reg(struct spi_device *spi, u32 reg, u8 *val,\n+\t\t\t     unsigned int len)\n+{\n+\tu16 *txbuf = (u16 *)val;\n+\n+\t*txbuf = reg & SPI_ADDR_M;\n+\t*txbuf |= (KS_SPIOP_WR << SPI_ADDR_S);\n+\t*txbuf <<= SPI_TURNAROUND_S;\n+\t*txbuf = cpu_to_be16(*txbuf);\n+\n+\treturn spi_write(spi, txbuf, 2 + len); }\n+\n+static int ksz_spi_write(struct ksz_device *dev, u32 reg, void *data,\n+\t\t\t unsigned int len)\n+{\n+\tstruct spi_device *spi = dev->priv;\n+\n+\tif (len > SPI_TX_BUF_LEN)\n+\t\tlen = SPI_TX_BUF_LEN;\n+\tmemcpy(&dev->txbuf[2], data, len);\n+\treturn ksz_spi_write_reg(spi, reg, dev->txbuf, len); }\n+\n+static unsigned int ksz_spi_get(struct ksz_device *dev, u32 reg, void *data,\n+\t\t\t\tunsigned int len)\n+{\n+\tint err;\n+\n+\terr = ksz_spi_read(dev, reg, data, len);\n+\tif (err)\n+\t\treturn 0;\n+\treturn len;\n+}\n+\n+static unsigned int ksz_spi_set(struct ksz_device *dev, u32 reg, void *data,\n+\t\t\t\tunsigned int len)\n+{\n+\tint err;\n+\n+\terr = ksz_spi_write(dev, reg, data, len);\n+\tif (err)\n+\t\treturn 0;\n+\treturn len;\n+}\n+\n+static int ksz_spi_write8(struct ksz_device *dev, u32 reg, u8 value) {\n+\treturn ksz_spi_write(dev, reg, &value, 1); }\n+\n+static int ksz_spi_write16(struct ksz_device *dev, u32 reg, u16 value) \n+{\n+\tvalue = cpu_to_be16(value);\n+\treturn ksz_spi_write(dev, reg, &value, 2); }\n+\n+static int ksz_spi_write32(struct ksz_device *dev, u32 reg, u32 value) \n+{\n+\tvalue = cpu_to_be32(value);\n+\treturn ksz_spi_write(dev, reg, &value, 4); }\n+\n+static const struct ksz_io_ops ksz_spi_ops = {\n+\t.read8 = ksz_spi_read8,\n+\t.read16 = ksz_spi_read16,\n+\t.read32 = ksz_spi_read32,\n+\t.write8 = ksz_spi_write8,\n+\t.write16 = ksz_spi_write16,\n+\t.write32 = ksz_spi_write32,\n+\t.get = ksz_spi_get,\n+\t.set = ksz_spi_set,\n+};\n+\n+static int ksz_spi_probe(struct spi_device *spi) {\n+\tstruct ksz_device *dev;\n+\tint ret;\n+\n+\tdev = ksz_switch_alloc(&spi->dev, &ksz_spi_ops, spi);\n+\tif (!dev)\n+\t\treturn -ENOMEM;\n+\n+\tif (spi->dev.platform_data)\n+\t\tdev->pdata = spi->dev.platform_data;\n+\n+\tdev->txbuf = devm_kzalloc(dev->dev, 2 + SPI_TX_BUF_LEN, GFP_KERNEL);\n+\n+\tret = ksz8795_switch_register(dev);\n+\n+\t/* Main DSA driver may not be started yet. */\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tspi_set_drvdata(spi, dev);\n+\n+\treturn 0;\n+}\n+\n+static int ksz_spi_remove(struct spi_device *spi) {\n+\tstruct ksz_device *dev = spi_get_drvdata(spi);\n+\n+\tif (dev)\n+\t\tksz_switch_remove(dev);\n+\n+\treturn 0;\n+}\n+\n+static void ksz_spi_shutdown(struct spi_device *spi) {\n+\tstruct ksz_device *dev = spi_get_drvdata(spi);\n+\n+\tif (dev)\n+\t\tdev->dev_ops->reset(dev);\n+}\n+\n+static const struct of_device_id ksz_dt_ids[] = {\n+\t{ .compatible = \"microchip,ksz8795\" },\n+\t{ .compatible = \"microchip,ksz8765\" },\n+\t{},\n+};\n+MODULE_DEVICE_TABLE(of, ksz_dt_ids);\n+\n+static struct spi_driver ksz_spi_driver = {\n+\t.driver = {\n+\t\t.name\t= \"ksz8795-switch\",\n+\t\t.owner\t= THIS_MODULE,\n+\t\t.of_match_table = of_match_ptr(ksz_dt_ids),\n+\t},\n+\t.probe\t= ksz_spi_probe,\n+\t.remove\t= ksz_spi_remove,\n+\t.shutdown = ksz_spi_shutdown,\n+};\n+\n+module_spi_driver(ksz_spi_driver);\n+\n+MODULE_AUTHOR(\"Tristram Ha <Tristram.Ha@microchip.com>\"); \n+MODULE_DESCRIPTION(\"Microchip KSZ8795 Series Switch SPI Driver\"); \n+MODULE_LICENSE(\"GPL\");\n\n","prefixes":["RFC","5/5"]}