From patchwork Thu Apr 7 16:16:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 607492 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3qgnmF232Yz9t62 for ; Fri, 8 Apr 2016 02:17:01 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=FACX0ITw; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756500AbcDGQQ6 (ORCPT ); Thu, 7 Apr 2016 12:16:58 -0400 Received: from mail-pa0-f67.google.com ([209.85.220.67]:34745 "EHLO mail-pa0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755498AbcDGQQ4 (ORCPT ); Thu, 7 Apr 2016 12:16:56 -0400 Received: by mail-pa0-f67.google.com with SMTP id hb4so7164910pac.1 for ; Thu, 07 Apr 2016 09:16:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RhP2L8EhP16mRRtmxQtgW9avo+weZU9+jR0BVh9xI6U=; b=FACX0ITwFkEOU4mRjvpE3ASXnMsShV2SyCZHsfElLkaQQ4DRG0jz6XtD7CZ5nXXc0b u3FNEJN38r1XYzZzDjp6W/MgWTaTF2AXOzKmiNYsqwv1KirbtFVEzMn2h2lN4LJelYSz 9QUvWOYaPmawMeKHH53zcqXahgvOpkKiv4S0eHGrmjs0D5crdV1DIXL6p28ydNeyOS4x U5SKg9GTgrB7WCIwfY8fMz/XiWpqEbpKxs+Bgojxv0yA1DFv1w1MwiP1Q6NEfJtubOGr e6i8i+qjNcEzIru5Mj5EIi8OPj6rHBPIqv6hLC1SML8eTXIqkbYbr3fRZ91Rv0y+00G9 rQGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RhP2L8EhP16mRRtmxQtgW9avo+weZU9+jR0BVh9xI6U=; b=Gq3VoGm3puHw61rpQRh5qSW7dXqcZpL3gwSL+HBebor2IcMun3W7Qaev+/SddlXJEp bNADGJiZrtA8E7abye5Cfjv3w6fk9QnWtQOIMRWQoHVWO+Eiticz0PVS3CCLXax3siuo VDgvBMwhdWTrMMNE4UEeT/xUG8pUz0XzA/jHoB5/Owx0mPm8jCyQlzp9SScLZPo58F78 CJ+SXQsU0b4yOCnDbANuaaJqVUbJhSmXgV9a6QhNIIibu5Rm8lypHQmxsffLgLkPqUjO +B7GEU6yJXR87GKh0RyoHBvk7mVqGgbNwljzNmkg1pMT7iJkQ/iiqqKAOVLt7lJrIrIa AwWw== X-Gm-Message-State: AD7BkJI64vcDXncQY9Gh0uhQ2P7eNHCyvruyHHMdhlpQSDLv05csnF1u/1rZdX9PGa0BmQ== X-Received: by 10.66.162.193 with SMTP id yc1mr5830924pab.148.1460045815755; Thu, 07 Apr 2016 09:16:55 -0700 (PDT) Received: from localhost.localdomain (KD113159139091.ppp-bb.dion.ne.jp. [113.159.139.91]) by smtp.gmail.com with ESMTPSA id i1sm13246045pfj.17.2016.04.07.09.16.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Apr 2016 09:16:54 -0700 (PDT) From: Akinobu Mita To: netdev@vger.kernel.org Cc: Akinobu Mita , Mike Sinkovsky , "David S. Miller" Subject: [PATCH v2 4/5] net: w5100: support SPI interface mode Date: Fri, 8 Apr 2016 01:16:31 +0900 Message-Id: <1460045792-30594-4-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1460045792-30594-1-git-send-email-akinobu.mita@gmail.com> References: <1460045792-30594-1-git-send-email-akinobu.mita@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This adds new w5100-spi driver which shares the bus interface independent code with existing w5100 driver. Signed-off-by: Akinobu Mita Cc: Mike Sinkovsky Cc: David S. Miller --- * v2 - Use spi_write_then_read instead of spi_write which needs DMA-safe buffer drivers/net/ethernet/wiznet/Kconfig | 14 ++++ drivers/net/ethernet/wiznet/Makefile | 1 + drivers/net/ethernet/wiznet/w5100-spi.c | 135 ++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 drivers/net/ethernet/wiznet/w5100-spi.c diff --git a/drivers/net/ethernet/wiznet/Kconfig b/drivers/net/ethernet/wiznet/Kconfig index f98b91d..d1ab353 100644 --- a/drivers/net/ethernet/wiznet/Kconfig +++ b/drivers/net/ethernet/wiznet/Kconfig @@ -69,4 +69,18 @@ config WIZNET_BUS_ANY Performance may decrease compared to explicitly selected bus mode. endchoice +config WIZNET_W5100_SPI + tristate "WIZnet W5100 Ethernet support for SPI mode" + depends on WIZNET_BUS_ANY + depends on SPI + ---help--- + In SPI mode host system accesses registers using SPI protocol + (mode 0) on the SPI bus. + + Performance decreases compared to other bus interface mode. + In W5100 SPI mode, burst READ/WRITE processing are not provided. + + To compile this driver as a module, choose M here: the module + will be called w5100-spi. + endif # NET_VENDOR_WIZNET diff --git a/drivers/net/ethernet/wiznet/Makefile b/drivers/net/ethernet/wiznet/Makefile index c614535..1e05e1a 100644 --- a/drivers/net/ethernet/wiznet/Makefile +++ b/drivers/net/ethernet/wiznet/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_WIZNET_W5100) += w5100.o +obj-$(CONFIG_WIZNET_W5100_SPI) += w5100-spi.o obj-$(CONFIG_WIZNET_W5300) += w5300.o diff --git a/drivers/net/ethernet/wiznet/w5100-spi.c b/drivers/net/ethernet/wiznet/w5100-spi.c new file mode 100644 index 0000000..bf2f434 --- /dev/null +++ b/drivers/net/ethernet/wiznet/w5100-spi.c @@ -0,0 +1,135 @@ +/* + * Ethernet driver for the WIZnet W5100 chip. + * + * Copyright (C) 2016 Akinobu Mita + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include + +#include "w5100.h" + +#define W5100_SPI_WRITE_OPCODE 0xf0 +#define W5100_SPI_READ_OPCODE 0x0f + +static int w5100_spi_read(struct net_device *ndev, u16 addr) +{ + struct spi_device *spi = to_spi_device(ndev->dev.parent); + u8 cmd[3] = { W5100_SPI_READ_OPCODE, addr >> 8, addr & 0xff }; + u8 data; + int ret; + + ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1); + + return ret ? ret : data; +} + +static int w5100_spi_write(struct net_device *ndev, u16 addr, u8 data) +{ + struct spi_device *spi = to_spi_device(ndev->dev.parent); + u8 cmd[4] = { W5100_SPI_WRITE_OPCODE, addr >> 8, addr & 0xff, data}; + + return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0); +} + +static int w5100_spi_read16(struct net_device *ndev, u16 addr) +{ + u16 data; + int ret; + + ret = w5100_spi_read(ndev, addr); + if (ret < 0) + return ret; + data = ret << 8; + ret = w5100_spi_read(ndev, addr + 1); + + return ret < 0 ? ret : data | ret; +} + +static int w5100_spi_write16(struct net_device *ndev, u16 addr, u16 data) +{ + int ret; + + ret = w5100_spi_write(ndev, addr, data >> 8); + if (ret) + return ret; + + return w5100_spi_write(ndev, addr + 1, data & 0xff); +} + +static int w5100_spi_readbulk(struct net_device *ndev, u16 addr, u8 *buf, + int len) +{ + int i; + + for (i = 0; i < len; i++) { + int ret = w5100_spi_read(ndev, addr + i); + + if (ret < 0) + return ret; + buf[i] = ret; + } + + return 0; +} + +static int w5100_spi_writebulk(struct net_device *ndev, u16 addr, const u8 *buf, + int len) +{ + int i; + + for (i = 0; i < len; i++) { + int ret = w5100_spi_write(ndev, addr + i, buf[i]); + + if (ret) + return ret; + } + + return 0; +} + +static const struct w5100_ops w5100_spi_ops = { + .may_sleep = true, + .read = w5100_spi_read, + .write = w5100_spi_write, + .read16 = w5100_spi_read16, + .write16 = w5100_spi_write16, + .readbulk = w5100_spi_readbulk, + .writebulk = w5100_spi_writebulk, +}; + +static int w5100_spi_probe(struct spi_device *spi) +{ + return w5100_probe(&spi->dev, &w5100_spi_ops, NULL, spi->irq, -EINVAL); +} + +static int w5100_spi_remove(struct spi_device *spi) +{ + return w5100_remove(&spi->dev); +} + +static const struct spi_device_id w5100_spi_ids[] = { + { "w5100", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, w5100_spi_ids); + +static struct spi_driver w5100_spi_driver = { + .driver = { + .name = "w5100", + .pm = &w5100_pm_ops, + }, + .probe = w5100_spi_probe, + .remove = w5100_spi_remove, + .id_table = w5100_spi_ids, +}; +module_spi_driver(w5100_spi_driver); + +MODULE_DESCRIPTION("WIZnet W5100 Ethernet driver for SPI mode"); +MODULE_AUTHOR("Akinobu Mita "); +MODULE_LICENSE("GPL");