Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp3262098imm; Thu, 17 May 2018 06:08:04 -0700 (PDT) X-Google-Smtp-Source: AB8JxZppmGxt+D5YWsvEeYdeCzJ+3el4Qc1ofDOSIvfU/etGCsK8gr1rF2Qt2MTn7vqkjdoOsyEK X-Received: by 2002:a17:902:7844:: with SMTP id e4-v6mr5102928pln.296.1526562484002; Thu, 17 May 2018 06:08:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526562483; cv=none; d=google.com; s=arc-20160816; b=zJvsw7RB2dGC/UIoKIrH5xh2wXhdjh5vYNHQ/zaDl0fTEq9c2Q+DB6L9Ol4e04Z4x8 likf5Sj7RTfmW11b6ufIB8WIK1s+BhoRX48WipupY0CkgwhcFAk5uKI4Uy/qEVsuk81r 129i9Vo4T+a9DcreWS6ppzfUX75J5PFOHm2HwLiYSvEXW82DwRfH0+vCjmHCtdUqnYH2 GICn5UZN+ApZG9e9DBPSfkDTJ8eS0thaIOmTOXsiXxVx0vc1HMWKXi2XYaL+CGTFNQYu 4L8DFEwFmEdQKMTLM99uLgRlfqEYQzBmp1rw9AssH9EYzT/2TFa8jbYjTzmGQ1UrxvOb s6Rg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=60yFRhfjGTfdbd/aXha23duWk/FxZoNTraAaxX2V8lU=; b=RMDwAuvMZLkQLT9x/3wU+h4SevGfVsa7N7g4l6Hazg15Ye5saMZkMMD8ddkeaL4yuv sEbIeVaeVkWBW0TUM6fEbsAUpuxIy/LjnjiC0NOfx133J2iHAwhVnCEwk0+8wKgrune1 g27yjJlZoqTnHPSfvgVy4Te8yfCGy0PSKaepbK9M1yRZxTW3img09NOHk/S16Gw1z0X5 sMMsaYNVU/ljUt19xEXXlPSAhETw52HnFck7Gi2u+w1wc9sG0jphxO9ACyz7X23YnOn2 cEePG96HrRF0SRJpKXiw1M7W+Hxvv7N+GDpETjUm96url2LYVP7KJzx1/tvgAhw/V8TP Pelw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Qf4cTbCD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c11-v6si3898330pgu.454.2018.05.17.06.07.47; Thu, 17 May 2018 06:08:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Qf4cTbCD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752211AbeEQNFt (ORCPT + 99 others); Thu, 17 May 2018 09:05:49 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:35387 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751843AbeEQNFr (ORCPT ); Thu, 17 May 2018 09:05:47 -0400 Received: by mail-wr0-f193.google.com with SMTP id i14-v6so5626895wre.2; Thu, 17 May 2018 06:05:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=60yFRhfjGTfdbd/aXha23duWk/FxZoNTraAaxX2V8lU=; b=Qf4cTbCDIH9oBcpwvcaypp7GPFqe31VrQN0rsTbLjouFqiZm/AFZ918q99l1BN7ydE nBFeNNUdCMzT6K0WerBoMDnDbAOfiKI/AfUFJkGjygwDjQ/No3OfYh6h4Xz5RFtia/BA adBpwf8+5FU3OGPu11ddhwsbQx5GEu98nAl0Yk1ASc1fT/vaiaovQk2DU286WTqpRDpf Yt4NDU0RK9DOnpRor8AVyp/aAlC151fJDid/9yvA7POjgogLIPkfslBXkNeONdTuW2f6 OaC1nfQTnPB0fatTwDo2yk+DvLmVNckthx/wPmKxLNu5/RzfjAQay2aZP3IxjBSfwvdg wEUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=60yFRhfjGTfdbd/aXha23duWk/FxZoNTraAaxX2V8lU=; b=iWyd7C4rTDl9Xrv/NS6w5XrBLI1k3Wlg68FQO1CL4au9yMvRKmTuYPOTcaAnv7K69N j+ix1ysukDi7luiP5SzXoogtDK7WAgSfP/wfJ9JPBEUwxQk6RL+cfuShRLIOXwv7y0Xk ts2yVA4+kIN9r5Y6KotsOMEJV503dt34AyvAwY/yxiq9depU6DxpzhClQAzPiBSZEpAC BNUahepQBWpqgD9pKoKInXS9yA2KD8/vUv+ug+31sBeRg/q9wOdUs1jXt204RF4X2DYC UYsMleI0rtMsY50+4WH/alL9imeslgdP6veJBncemJ9eZYMGkdVO5d4vxkKVQ4oOY8UE 7TPg== X-Gm-Message-State: ALKqPwdVyJjzKP0NmfMPVk9F6e7O/AYPnIAJ/4yzPZ4hcydX6rzy+zn/ Smht2Yye42JvRpMLaRfQYFA= X-Received: by 2002:adf:9c01:: with SMTP id f1-v6mr4043994wrc.171.1526562345624; Thu, 17 May 2018 06:05:45 -0700 (PDT) Received: from localhost.localdomain (83-103-103-194.ip.fastwebnet.it. [83.103.103.194]) by smtp.gmail.com with ESMTPSA id 33-v6sm6114579wrs.5.2018.05.17.06.05.43 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 17 May 2018 06:05:44 -0700 (PDT) From: Andrea Greco To: tobin@apporbit.com Cc: andrea.greco.gapmilano@gmail.com, Andrea Greco , Michael Grzeschik , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH 1/4] arcnet: com20020: Add com20020 io mapped version Date: Thu, 17 May 2018 15:05:29 +0200 Message-Id: <20180517130529.2684-1-andrea.greco.gapmilano@gmail.com> X-Mailer: git-send-email 2.14.3 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andrea Greco Add support for com20022I/com20020, io mapped. Signed-off-by: Andrea Greco --- drivers/net/arcnet/Kconfig | 9 +- drivers/net/arcnet/Makefile | 1 + drivers/net/arcnet/arcdevice.h | 14 ++ drivers/net/arcnet/com20020-io.c | 287 +++++++++++++++++++++++++++++++++++++++ drivers/net/arcnet/com20020.c | 5 +- 5 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 drivers/net/arcnet/com20020-io.c diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig index 39bd16f3f86d..85e60ed29fa8 100644 --- a/drivers/net/arcnet/Kconfig +++ b/drivers/net/arcnet/Kconfig @@ -3,7 +3,7 @@ # menuconfig ARCNET - depends on NETDEVICES && (ISA || PCI || PCMCIA) + depends on NETDEVICES tristate "ARCnet support" ---help--- If you have a network card of this type, say Y and check out the @@ -129,5 +129,12 @@ config ARCNET_COM20020_CS To compile this driver as a module, choose M here: the module will be called com20020_cs. If unsure, say N. +config ARCNET_COM20020_IO + bool "Support for COM20020 (IO mapped)" + depends on ARCNET_COM20020 && !(ARCNET_COM20020_PCI || ARCNET_COM20020_ISA || ARCNET_COM20020_CS) + help + Say Y here if your custom board mount com20020 chipset or friends. + Supported Chipset: com20020, com20022, com20022I-3v3 + If unsure, say N. endif # ARCNET diff --git a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile index 53525e8ea130..18da4341f404 100644 --- a/drivers/net/arcnet/Makefile +++ b/drivers/net/arcnet/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_ARCNET_COM20020) += com20020.o obj-$(CONFIG_ARCNET_COM20020_ISA) += com20020-isa.o obj-$(CONFIG_ARCNET_COM20020_PCI) += com20020-pci.o obj-$(CONFIG_ARCNET_COM20020_CS) += com20020_cs.o +obj-$(CONFIG_ARCNET_COM20020_IO) += com20020-io.o diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h index d09b2b46ab63..86c36d9b666b 100644 --- a/drivers/net/arcnet/arcdevice.h +++ b/drivers/net/arcnet/arcdevice.h @@ -371,6 +371,19 @@ void arcnet_timeout(struct net_device *dev); #define BUS_ALIGN 1 #endif +#ifdef CONFIG_ARCNET_COM20020_IO +#define arcnet_inb(addr, offset) \ + ioread8((void __iomem *)(addr) + BUS_ALIGN * offset) + +#define arcnet_outb(value, addr, offset) \ + iowrite8(value, (void __iomem *)addr + BUS_ALIGN * offset) + +#define arcnet_insb(addr, offset, buffer, count) \ + ioread8_rep((void __iomem *)addr + BUS_ALIGN * offset, buffer, count) + +#define arcnet_outsb(addr, offset, buffer, count) \ + iowrite8_rep((void __iomem *)addr + BUS_ALIGN * offset, buffer, count) +#else /* addr and offset allow register like names to define the actual IO address. * A configuration option multiplies the offset for alignment. */ @@ -388,6 +401,7 @@ void arcnet_timeout(struct net_device *dev); readb((addr) + (offset)) #define arcnet_writeb(value, addr, offset) \ writeb(value, (addr) + (offset)) +#endif #endif /* __KERNEL__ */ #endif /* _LINUX_ARCDEVICE_H */ diff --git a/drivers/net/arcnet/com20020-io.c b/drivers/net/arcnet/com20020-io.c new file mode 100644 index 000000000000..fce458242193 --- /dev/null +++ b/drivers/net/arcnet/com20020-io.c @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Linux ARCnet driver for com 20020. + * + * datasheet: + * http://ww1.microchip.com/downloads/en/DeviceDoc/200223vrevc.pdf + * http://ww1.microchip.com/downloads/en/DeviceDoc/20020.pdf + * + * Supported chip version: + * - com20020 + * - com20022 + * - com20022I-3v3 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "arcdevice.h" +#include "com20020.h" + +/* Reset (5 * xTalFreq), minimal com20020 xTal is 10Mhz */ +#define RESET_DELAY 500 + +enum com20020_xtal_freq { + freq_10Mhz = 10, + freq_20Mhz = 20, +}; + +enum com20020_arcnet_speed { + arc_speed_10M_bps = 10000000, + arc_speed_5M_bps = 5000000, + arc_speed_2M50_bps = 2500000, + arc_speed_1M25_bps = 1250000, + arc_speed_625K_bps = 625000, + arc_speed_312K5_bps = 312500, + arc_speed_156K25_bps = 156250, +}; + +enum com20020_timeout { + arc_timeout_328us = 328000, + arc_timeout_164us = 164000, + arc_timeout_82us = 82000, + arc_timeout_20u5s = 20500, +}; + +static int setup_clock(int *clockp, int *clockm, int xtal, int arcnet_speed) +{ + int pll_factor, req_clock_frq = 20; + + switch (arcnet_speed) { + case arc_speed_10M_bps: + req_clock_frq = 80; + *clockp = 0; + break; + case arc_speed_5M_bps: + req_clock_frq = 40; + *clockp = 0; + break; + case arc_speed_2M50_bps: + *clockp = 0; + break; + case arc_speed_1M25_bps: + *clockp = 1; + break; + case arc_speed_625K_bps: + *clockp = 2; + break; + case arc_speed_312K5_bps: + *clockp = 3; + break; + case arc_speed_156K25_bps: + *clockp = 4; + break; + default: + return -EINVAL; + } + + if (xtal != freq_10Mhz && xtal != freq_20Mhz) + return -EINVAL; + + pll_factor = (unsigned int)req_clock_frq / xtal; + + switch (pll_factor) { + case 1: + *clockm = 0; + break; + case 2: + *clockm = 1; + break; + case 4: + *clockm = 3; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int setup_timeout(int *timeout) +{ + switch (*timeout) { + case arc_timeout_328us: + *timeout = 0; + break; + case arc_timeout_164us: + *timeout = 1; + break; + case arc_timeout_82us: + *timeout = 2; + break; + case arc_timeout_20u5s: + *timeout = 3; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int com20020_probe(struct platform_device *pdev) +{ + struct device_node *np; + struct net_device *dev; + struct arcnet_local *lp; + struct resource res, *iores; + int ret, phy_reset; + u32 timeout, xtal, arc_speed; + int clockp, clockm; + void __iomem *ioaddr; + bool backplane = false; + + np = pdev->dev.of_node; + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + ret = of_address_to_resource(np, 0, &res); + if (ret) + return ret; + + ret = of_property_read_u32(np, "timeout-ns", &timeout); + if (ret) { + dev_err(&pdev->dev, "timeout is required param"); + return ret; + } + + ret = of_property_read_u32(np, "smsc,xtal-mhz", &xtal); + if (ret) { + dev_err(&pdev->dev, "xtal-mhz is required param"); + return ret; + } + + ret = of_property_read_u32(np, "bus-speed-bps", &arc_speed); + if (ret) { + dev_err(&pdev->dev, "Bus speed is required param"); + return ret; + } + + if (of_property_read_bool(np, "smsc,backplane-enabled")) + backplane = true; + + phy_reset = of_get_named_gpio(np, "reset-gpios", 0); + if (!gpio_is_valid(phy_reset)) { + dev_err(&pdev->dev, "reset gpio not valid"); + return phy_reset; + } + + ret = devm_gpio_request_one(&pdev->dev, phy_reset, GPIOF_OUT_INIT_LOW, + "arcnet-reset"); + if (ret) { + dev_err(&pdev->dev, "failed to get phy reset gpio: %d\n", ret); + return ret; + } + + dev = alloc_arcdev(NULL); + dev->netdev_ops = &com20020_netdev_ops; + lp = netdev_priv(dev); + + lp->card_flags = ARC_CAN_10MBIT; + + /* Will be set by userspace during if setup */ + dev->dev_addr[0] = 0; + + if (!devm_request_mem_region(&pdev->dev, res.start, resource_size(&res), + lp->card_name)) + return -EBUSY; + + ioaddr = devm_ioremap(&pdev->dev, iores->start, resource_size(iores)); + if (!ioaddr) { + dev_err(&pdev->dev, "ioremap fallied\n"); + return -ENOMEM; + } + + gpio_set_value_cansleep(phy_reset, 0); + ndelay(RESET_DELAY); + gpio_set_value_cansleep(phy_reset, 1); + + /* ARCNET controller needs this access to detect bustype */ + arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND); + arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT); + + dev->base_addr = (unsigned long)ioaddr; + + dev->irq = of_get_named_gpio(np, "interrupts", 0); + if (dev->irq == -EPROBE_DEFER) { + return dev->irq; + } else if (!gpio_is_valid(dev->irq)) { + dev_err(&pdev->dev, "irq-gpios not valid !"); + return -EIO; + } + dev->irq = gpio_to_irq(dev->irq); + + ret = setup_clock(&clockp, &clockm, xtal, arc_speed); + if (ret) { + dev_err(&pdev->dev, + "Impossible use oscillator:%dMhz and arcnet bus speed:%dKbps", + xtal, arc_speed / 1000); + return ret; + } + + ret = setup_timeout(&timeout); + if (ret) { + dev_err(&pdev->dev, "Timeout:%d is not valid value", timeout); + return ret; + } + + lp->backplane = (int)backplane; + lp->timeout = timeout; + lp->clockm = clockm; + lp->clockp = clockp; + lp->hw.owner = THIS_MODULE; + + if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { + ret = -EIO; + goto err_release_mem; + } + + if (com20020_check(dev)) { + ret = -EIO; + goto err_release_mem; + } + + ret = com20020_found(dev, IRQF_TRIGGER_FALLING); + if (ret) + goto err_release_mem; + + dev_dbg(&pdev->dev, "probe Done\n"); + return 0; + +err_release_mem: + devm_iounmap(&pdev->dev, (void __iomem *)ioaddr); + devm_release_mem_region(&pdev->dev, res.start, resource_size(&res)); + dev_err(&pdev->dev, "probe failed!\n"); + return ret; +} + +static const struct of_device_id of_com20020_match[] = { + { .compatible = "smsc,com20020", }, + { }, +}; + +MODULE_DEVICE_TABLE(of, of_com20020_match); + +static struct platform_driver of_com20020_driver = { + .driver = { + .name = "com20020-memory-bus", + .of_match_table = of_com20020_match, + }, + .probe = com20020_probe, +}; + +static int com20020_init(void) +{ + return platform_driver_register(&of_com20020_driver); +} +late_initcall(com20020_init); + +MODULE_LICENSE("GPL"); diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 78043a9c5981..2fd00d2dd6bf 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -43,7 +43,7 @@ #include "com20020.h" static const char * const clockrates[] = { - "XXXXXXX", "XXXXXXXX", "XXXXXX", "2.5 Mb/s", + "10 Mb/s", "XXXXXXXX", "XXXXXX", "2.5 Mb/s", "1.25Mb/s", "625 Kb/s", "312.5 Kb/s", "156.25 Kb/s", "Reserved", "Reserved", "Reserved" }; @@ -393,7 +393,8 @@ static void com20020_set_mc_list(struct net_device *dev) #if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \ defined(CONFIG_ARCNET_COM20020_ISA_MODULE) || \ - defined(CONFIG_ARCNET_COM20020_CS_MODULE) + defined(CONFIG_ARCNET_COM20020_CS_MODULE) || \ + defined(CONFIG_ARCNET_COM20020_IO) EXPORT_SYMBOL(com20020_check); EXPORT_SYMBOL(com20020_found); EXPORT_SYMBOL(com20020_netdev_ops); -- 2.14.3