18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Linux ARCnet driver - COM20020 PCI support 38c2ecf20Sopenharmony_ci * Contemporary Controls PCI20 and SOHARD SH-ARC PCI 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Written 1994-1999 by Avery Pennarun, 68c2ecf20Sopenharmony_ci * based on an ISA version by David Woodhouse. 78c2ecf20Sopenharmony_ci * Written 1999-2000 by Martin Mares <mj@ucw.cz>. 88c2ecf20Sopenharmony_ci * Derived from skeleton.c by Donald Becker. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com) 118c2ecf20Sopenharmony_ci * for sponsoring the further development of this driver. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * ********************** 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * The original copyright of skeleton.c was as follows: 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * skeleton.c Written 1993 by Donald Becker. 188c2ecf20Sopenharmony_ci * Copyright 1993 United States Government as represented by the 198c2ecf20Sopenharmony_ci * Director, National Security Agency. This software may only be used 208c2ecf20Sopenharmony_ci * and distributed according to the terms of the GNU General Public License as 218c2ecf20Sopenharmony_ci * modified by SRC, incorporated herein by reference. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * ********************** 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * For more details, see drivers/net/arcnet.c 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * ********************** 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#include <linux/module.h> 338c2ecf20Sopenharmony_ci#include <linux/moduleparam.h> 348c2ecf20Sopenharmony_ci#include <linux/kernel.h> 358c2ecf20Sopenharmony_ci#include <linux/types.h> 368c2ecf20Sopenharmony_ci#include <linux/ioport.h> 378c2ecf20Sopenharmony_ci#include <linux/errno.h> 388c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 398c2ecf20Sopenharmony_ci#include <linux/init.h> 408c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 418c2ecf20Sopenharmony_ci#include <linux/pci.h> 428c2ecf20Sopenharmony_ci#include <linux/list.h> 438c2ecf20Sopenharmony_ci#include <linux/io.h> 448c2ecf20Sopenharmony_ci#include <linux/leds.h> 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#include "arcdevice.h" 478c2ecf20Sopenharmony_ci#include "com20020.h" 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/* Module parameters */ 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic int node; 528c2ecf20Sopenharmony_cistatic char device[9]; /* use eg. device="arc1" to change name */ 538c2ecf20Sopenharmony_cistatic int timeout = 3; 548c2ecf20Sopenharmony_cistatic int backplane; 558c2ecf20Sopenharmony_cistatic int clockp; 568c2ecf20Sopenharmony_cistatic int clockm; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cimodule_param(node, int, 0); 598c2ecf20Sopenharmony_cimodule_param_string(device, device, sizeof(device), 0); 608c2ecf20Sopenharmony_cimodule_param(timeout, int, 0); 618c2ecf20Sopenharmony_cimodule_param(backplane, int, 0); 628c2ecf20Sopenharmony_cimodule_param(clockp, int, 0); 638c2ecf20Sopenharmony_cimodule_param(clockm, int, 0); 648c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic void led_tx_set(struct led_classdev *led_cdev, 678c2ecf20Sopenharmony_ci enum led_brightness value) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci struct com20020_dev *card; 708c2ecf20Sopenharmony_ci struct com20020_priv *priv; 718c2ecf20Sopenharmony_ci struct com20020_pci_card_info *ci; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci card = container_of(led_cdev, struct com20020_dev, tx_led); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci priv = card->pci_priv; 768c2ecf20Sopenharmony_ci ci = priv->ci; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci outb(!!value, priv->misc + ci->leds[card->index].green); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic void led_recon_set(struct led_classdev *led_cdev, 828c2ecf20Sopenharmony_ci enum led_brightness value) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci struct com20020_dev *card; 858c2ecf20Sopenharmony_ci struct com20020_priv *priv; 868c2ecf20Sopenharmony_ci struct com20020_pci_card_info *ci; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci card = container_of(led_cdev, struct com20020_dev, recon_led); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci priv = card->pci_priv; 918c2ecf20Sopenharmony_ci ci = priv->ci; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci outb(!!value, priv->misc + ci->leds[card->index].red); 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistatic ssize_t backplane_mode_show(struct device *dev, 978c2ecf20Sopenharmony_ci struct device_attribute *attr, 988c2ecf20Sopenharmony_ci char *buf) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci struct net_device *net_dev = to_net_dev(dev); 1018c2ecf20Sopenharmony_ci struct arcnet_local *lp = netdev_priv(net_dev); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", lp->backplane ? "true" : "false"); 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(backplane_mode); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic struct attribute *com20020_state_attrs[] = { 1088c2ecf20Sopenharmony_ci &dev_attr_backplane_mode.attr, 1098c2ecf20Sopenharmony_ci NULL, 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cistatic const struct attribute_group com20020_state_group = { 1138c2ecf20Sopenharmony_ci .name = NULL, 1148c2ecf20Sopenharmony_ci .attrs = com20020_state_attrs, 1158c2ecf20Sopenharmony_ci}; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistatic void com20020pci_remove(struct pci_dev *pdev); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistatic int com20020pci_probe(struct pci_dev *pdev, 1208c2ecf20Sopenharmony_ci const struct pci_device_id *id) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci struct com20020_pci_card_info *ci; 1238c2ecf20Sopenharmony_ci struct com20020_pci_channel_map *mm; 1248c2ecf20Sopenharmony_ci struct net_device *dev; 1258c2ecf20Sopenharmony_ci struct arcnet_local *lp; 1268c2ecf20Sopenharmony_ci struct com20020_priv *priv; 1278c2ecf20Sopenharmony_ci int i, ioaddr, ret; 1288c2ecf20Sopenharmony_ci struct resource *r; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci ret = 0; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci if (pci_enable_device(pdev)) 1338c2ecf20Sopenharmony_ci return -EIO; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci priv = devm_kzalloc(&pdev->dev, sizeof(struct com20020_priv), 1368c2ecf20Sopenharmony_ci GFP_KERNEL); 1378c2ecf20Sopenharmony_ci if (!priv) 1388c2ecf20Sopenharmony_ci return -ENOMEM; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci ci = (struct com20020_pci_card_info *)id->driver_data; 1418c2ecf20Sopenharmony_ci if (!ci) 1428c2ecf20Sopenharmony_ci return -EINVAL; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci priv->ci = ci; 1458c2ecf20Sopenharmony_ci mm = &ci->misc_map; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci pci_set_drvdata(pdev, priv); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&priv->list_dev); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if (mm->size) { 1528c2ecf20Sopenharmony_ci ioaddr = pci_resource_start(pdev, mm->bar) + mm->offset; 1538c2ecf20Sopenharmony_ci r = devm_request_region(&pdev->dev, ioaddr, mm->size, 1548c2ecf20Sopenharmony_ci "com20020-pci"); 1558c2ecf20Sopenharmony_ci if (!r) { 1568c2ecf20Sopenharmony_ci pr_err("IO region %xh-%xh already allocated.\n", 1578c2ecf20Sopenharmony_ci ioaddr, ioaddr + mm->size - 1); 1588c2ecf20Sopenharmony_ci return -EBUSY; 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci priv->misc = ioaddr; 1618c2ecf20Sopenharmony_ci } 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci for (i = 0; i < ci->devcount; i++) { 1648c2ecf20Sopenharmony_ci struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i]; 1658c2ecf20Sopenharmony_ci struct com20020_dev *card; 1668c2ecf20Sopenharmony_ci int dev_id_mask = 0xf; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci dev = alloc_arcdev(device); 1698c2ecf20Sopenharmony_ci if (!dev) { 1708c2ecf20Sopenharmony_ci ret = -ENOMEM; 1718c2ecf20Sopenharmony_ci break; 1728c2ecf20Sopenharmony_ci } 1738c2ecf20Sopenharmony_ci dev->dev_port = i; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci dev->netdev_ops = &com20020_netdev_ops; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci lp = netdev_priv(dev); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci arc_printk(D_NORMAL, dev, "%s Controls\n", ci->name); 1808c2ecf20Sopenharmony_ci ioaddr = pci_resource_start(pdev, cm->bar) + cm->offset; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci r = devm_request_region(&pdev->dev, ioaddr, cm->size, 1838c2ecf20Sopenharmony_ci "com20020-pci"); 1848c2ecf20Sopenharmony_ci if (!r) { 1858c2ecf20Sopenharmony_ci pr_err("IO region %xh-%xh already allocated\n", 1868c2ecf20Sopenharmony_ci ioaddr, ioaddr + cm->size - 1); 1878c2ecf20Sopenharmony_ci ret = -EBUSY; 1888c2ecf20Sopenharmony_ci goto err_free_arcdev; 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci /* Dummy access after Reset 1928c2ecf20Sopenharmony_ci * ARCNET controller needs 1938c2ecf20Sopenharmony_ci * this access to detect bustype 1948c2ecf20Sopenharmony_ci */ 1958c2ecf20Sopenharmony_ci arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND); 1968c2ecf20Sopenharmony_ci arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT); 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci SET_NETDEV_DEV(dev, &pdev->dev); 1998c2ecf20Sopenharmony_ci dev->base_addr = ioaddr; 2008c2ecf20Sopenharmony_ci dev->dev_addr[0] = node; 2018c2ecf20Sopenharmony_ci dev->sysfs_groups[0] = &com20020_state_group; 2028c2ecf20Sopenharmony_ci dev->irq = pdev->irq; 2038c2ecf20Sopenharmony_ci lp->card_name = "PCI COM20020"; 2048c2ecf20Sopenharmony_ci lp->card_flags = ci->flags; 2058c2ecf20Sopenharmony_ci lp->backplane = backplane; 2068c2ecf20Sopenharmony_ci lp->clockp = clockp & 7; 2078c2ecf20Sopenharmony_ci lp->clockm = clockm & 3; 2088c2ecf20Sopenharmony_ci lp->timeout = timeout; 2098c2ecf20Sopenharmony_ci lp->hw.owner = THIS_MODULE; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci lp->backplane = (inb(priv->misc) >> (2 + i)) & 0x1; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15)) 2148c2ecf20Sopenharmony_ci lp->backplane = 1; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci if (ci->flags & ARC_HAS_ROTARY) { 2178c2ecf20Sopenharmony_ci /* Get the dev_id from the PLX rotary coder */ 2188c2ecf20Sopenharmony_ci if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) 2198c2ecf20Sopenharmony_ci dev_id_mask = 0x3; 2208c2ecf20Sopenharmony_ci dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; 2218c2ecf20Sopenharmony_ci snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { 2258c2ecf20Sopenharmony_ci pr_err("IO address %Xh is empty!\n", ioaddr); 2268c2ecf20Sopenharmony_ci ret = -EIO; 2278c2ecf20Sopenharmony_ci goto err_free_arcdev; 2288c2ecf20Sopenharmony_ci } 2298c2ecf20Sopenharmony_ci if (com20020_check(dev)) { 2308c2ecf20Sopenharmony_ci ret = -EIO; 2318c2ecf20Sopenharmony_ci goto err_free_arcdev; 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci ret = com20020_found(dev, IRQF_SHARED); 2358c2ecf20Sopenharmony_ci if (ret) 2368c2ecf20Sopenharmony_ci goto err_free_arcdev; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), 2398c2ecf20Sopenharmony_ci GFP_KERNEL); 2408c2ecf20Sopenharmony_ci if (!card) { 2418c2ecf20Sopenharmony_ci ret = -ENOMEM; 2428c2ecf20Sopenharmony_ci goto err_free_arcdev; 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci card->index = i; 2468c2ecf20Sopenharmony_ci card->pci_priv = priv; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci if (ci->flags & ARC_HAS_LED) { 2498c2ecf20Sopenharmony_ci card->tx_led.brightness_set = led_tx_set; 2508c2ecf20Sopenharmony_ci card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, 2518c2ecf20Sopenharmony_ci GFP_KERNEL, "arc%d-%d-tx", 2528c2ecf20Sopenharmony_ci dev->dev_id, i); 2538c2ecf20Sopenharmony_ci card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, 2548c2ecf20Sopenharmony_ci "pci:green:tx:%d-%d", 2558c2ecf20Sopenharmony_ci dev->dev_id, i); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci card->tx_led.dev = &dev->dev; 2588c2ecf20Sopenharmony_ci card->recon_led.brightness_set = led_recon_set; 2598c2ecf20Sopenharmony_ci card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, 2608c2ecf20Sopenharmony_ci GFP_KERNEL, "arc%d-%d-recon", 2618c2ecf20Sopenharmony_ci dev->dev_id, i); 2628c2ecf20Sopenharmony_ci card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, 2638c2ecf20Sopenharmony_ci "pci:red:recon:%d-%d", 2648c2ecf20Sopenharmony_ci dev->dev_id, i); 2658c2ecf20Sopenharmony_ci card->recon_led.dev = &dev->dev; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); 2688c2ecf20Sopenharmony_ci if (ret) 2698c2ecf20Sopenharmony_ci goto err_free_arcdev; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); 2728c2ecf20Sopenharmony_ci if (ret) 2738c2ecf20Sopenharmony_ci goto err_free_arcdev; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci dev_set_drvdata(&dev->dev, card); 2768c2ecf20Sopenharmony_ci devm_arcnet_led_init(dev, dev->dev_id, i); 2778c2ecf20Sopenharmony_ci } 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci card->dev = dev; 2808c2ecf20Sopenharmony_ci list_add(&card->list, &priv->list_dev); 2818c2ecf20Sopenharmony_ci continue; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cierr_free_arcdev: 2848c2ecf20Sopenharmony_ci free_arcdev(dev); 2858c2ecf20Sopenharmony_ci break; 2868c2ecf20Sopenharmony_ci } 2878c2ecf20Sopenharmony_ci if (ret) 2888c2ecf20Sopenharmony_ci com20020pci_remove(pdev); 2898c2ecf20Sopenharmony_ci return ret; 2908c2ecf20Sopenharmony_ci} 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cistatic void com20020pci_remove(struct pci_dev *pdev) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci struct com20020_dev *card, *tmpcard; 2958c2ecf20Sopenharmony_ci struct com20020_priv *priv; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci priv = pci_get_drvdata(pdev); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci list_for_each_entry_safe(card, tmpcard, &priv->list_dev, list) { 3008c2ecf20Sopenharmony_ci struct net_device *dev = card->dev; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci unregister_netdev(dev); 3038c2ecf20Sopenharmony_ci free_irq(dev->irq, dev); 3048c2ecf20Sopenharmony_ci free_arcdev(dev); 3058c2ecf20Sopenharmony_ci } 3068c2ecf20Sopenharmony_ci} 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_cistatic struct com20020_pci_card_info card_info_10mbit = { 3098c2ecf20Sopenharmony_ci .name = "ARC-PCI", 3108c2ecf20Sopenharmony_ci .devcount = 1, 3118c2ecf20Sopenharmony_ci .chan_map_tbl = { 3128c2ecf20Sopenharmony_ci { 3138c2ecf20Sopenharmony_ci .bar = 2, 3148c2ecf20Sopenharmony_ci .offset = 0x00, 3158c2ecf20Sopenharmony_ci .size = 0x08, 3168c2ecf20Sopenharmony_ci }, 3178c2ecf20Sopenharmony_ci }, 3188c2ecf20Sopenharmony_ci .flags = ARC_CAN_10MBIT, 3198c2ecf20Sopenharmony_ci}; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistatic struct com20020_pci_card_info card_info_5mbit = { 3228c2ecf20Sopenharmony_ci .name = "ARC-PCI", 3238c2ecf20Sopenharmony_ci .devcount = 1, 3248c2ecf20Sopenharmony_ci .chan_map_tbl = { 3258c2ecf20Sopenharmony_ci { 3268c2ecf20Sopenharmony_ci .bar = 2, 3278c2ecf20Sopenharmony_ci .offset = 0x00, 3288c2ecf20Sopenharmony_ci .size = 0x08, 3298c2ecf20Sopenharmony_ci }, 3308c2ecf20Sopenharmony_ci }, 3318c2ecf20Sopenharmony_ci .flags = ARC_IS_5MBIT, 3328c2ecf20Sopenharmony_ci}; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistatic struct com20020_pci_card_info card_info_sohard = { 3358c2ecf20Sopenharmony_ci .name = "SOHARD SH ARC-PCI", 3368c2ecf20Sopenharmony_ci .devcount = 1, 3378c2ecf20Sopenharmony_ci /* SOHARD needs PCI base addr 4 */ 3388c2ecf20Sopenharmony_ci .chan_map_tbl = { 3398c2ecf20Sopenharmony_ci { 3408c2ecf20Sopenharmony_ci .bar = 4, 3418c2ecf20Sopenharmony_ci .offset = 0x00, 3428c2ecf20Sopenharmony_ci .size = 0x08 3438c2ecf20Sopenharmony_ci }, 3448c2ecf20Sopenharmony_ci }, 3458c2ecf20Sopenharmony_ci .flags = ARC_CAN_10MBIT, 3468c2ecf20Sopenharmony_ci}; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic struct com20020_pci_card_info card_info_eae_arc1 = { 3498c2ecf20Sopenharmony_ci .name = "EAE PLX-PCI ARC1", 3508c2ecf20Sopenharmony_ci .devcount = 1, 3518c2ecf20Sopenharmony_ci .chan_map_tbl = { 3528c2ecf20Sopenharmony_ci { 3538c2ecf20Sopenharmony_ci .bar = 2, 3548c2ecf20Sopenharmony_ci .offset = 0x00, 3558c2ecf20Sopenharmony_ci .size = 0x08, 3568c2ecf20Sopenharmony_ci }, 3578c2ecf20Sopenharmony_ci }, 3588c2ecf20Sopenharmony_ci .misc_map = { 3598c2ecf20Sopenharmony_ci .bar = 2, 3608c2ecf20Sopenharmony_ci .offset = 0x10, 3618c2ecf20Sopenharmony_ci .size = 0x04, 3628c2ecf20Sopenharmony_ci }, 3638c2ecf20Sopenharmony_ci .leds = { 3648c2ecf20Sopenharmony_ci { 3658c2ecf20Sopenharmony_ci .green = 0x0, 3668c2ecf20Sopenharmony_ci .red = 0x1, 3678c2ecf20Sopenharmony_ci }, 3688c2ecf20Sopenharmony_ci }, 3698c2ecf20Sopenharmony_ci .rotary = 0x0, 3708c2ecf20Sopenharmony_ci .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, 3718c2ecf20Sopenharmony_ci}; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_cistatic struct com20020_pci_card_info card_info_eae_ma1 = { 3748c2ecf20Sopenharmony_ci .name = "EAE PLX-PCI MA1", 3758c2ecf20Sopenharmony_ci .devcount = 2, 3768c2ecf20Sopenharmony_ci .chan_map_tbl = { 3778c2ecf20Sopenharmony_ci { 3788c2ecf20Sopenharmony_ci .bar = 2, 3798c2ecf20Sopenharmony_ci .offset = 0x00, 3808c2ecf20Sopenharmony_ci .size = 0x08, 3818c2ecf20Sopenharmony_ci }, { 3828c2ecf20Sopenharmony_ci .bar = 2, 3838c2ecf20Sopenharmony_ci .offset = 0x08, 3848c2ecf20Sopenharmony_ci .size = 0x08, 3858c2ecf20Sopenharmony_ci } 3868c2ecf20Sopenharmony_ci }, 3878c2ecf20Sopenharmony_ci .misc_map = { 3888c2ecf20Sopenharmony_ci .bar = 2, 3898c2ecf20Sopenharmony_ci .offset = 0x10, 3908c2ecf20Sopenharmony_ci .size = 0x04, 3918c2ecf20Sopenharmony_ci }, 3928c2ecf20Sopenharmony_ci .leds = { 3938c2ecf20Sopenharmony_ci { 3948c2ecf20Sopenharmony_ci .green = 0x0, 3958c2ecf20Sopenharmony_ci .red = 0x1, 3968c2ecf20Sopenharmony_ci }, { 3978c2ecf20Sopenharmony_ci .green = 0x2, 3988c2ecf20Sopenharmony_ci .red = 0x3, 3998c2ecf20Sopenharmony_ci }, 4008c2ecf20Sopenharmony_ci }, 4018c2ecf20Sopenharmony_ci .rotary = 0x0, 4028c2ecf20Sopenharmony_ci .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, 4038c2ecf20Sopenharmony_ci}; 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_cistatic struct com20020_pci_card_info card_info_eae_fb2 = { 4068c2ecf20Sopenharmony_ci .name = "EAE PLX-PCI FB2", 4078c2ecf20Sopenharmony_ci .devcount = 1, 4088c2ecf20Sopenharmony_ci .chan_map_tbl = { 4098c2ecf20Sopenharmony_ci { 4108c2ecf20Sopenharmony_ci .bar = 2, 4118c2ecf20Sopenharmony_ci .offset = 0x00, 4128c2ecf20Sopenharmony_ci .size = 0x08, 4138c2ecf20Sopenharmony_ci }, 4148c2ecf20Sopenharmony_ci }, 4158c2ecf20Sopenharmony_ci .misc_map = { 4168c2ecf20Sopenharmony_ci .bar = 2, 4178c2ecf20Sopenharmony_ci .offset = 0x10, 4188c2ecf20Sopenharmony_ci .size = 0x04, 4198c2ecf20Sopenharmony_ci }, 4208c2ecf20Sopenharmony_ci .leds = { 4218c2ecf20Sopenharmony_ci { 4228c2ecf20Sopenharmony_ci .green = 0x0, 4238c2ecf20Sopenharmony_ci .red = 0x1, 4248c2ecf20Sopenharmony_ci }, 4258c2ecf20Sopenharmony_ci }, 4268c2ecf20Sopenharmony_ci .rotary = 0x0, 4278c2ecf20Sopenharmony_ci .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, 4288c2ecf20Sopenharmony_ci}; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_cistatic const struct pci_device_id com20020pci_id_table[] = { 4318c2ecf20Sopenharmony_ci { 4328c2ecf20Sopenharmony_ci 0x1571, 0xa001, 4338c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4348c2ecf20Sopenharmony_ci 0, 0, 4358c2ecf20Sopenharmony_ci 0, 4368c2ecf20Sopenharmony_ci }, 4378c2ecf20Sopenharmony_ci { 4388c2ecf20Sopenharmony_ci 0x1571, 0xa002, 4398c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4408c2ecf20Sopenharmony_ci 0, 0, 4418c2ecf20Sopenharmony_ci 0, 4428c2ecf20Sopenharmony_ci }, 4438c2ecf20Sopenharmony_ci { 4448c2ecf20Sopenharmony_ci 0x1571, 0xa003, 4458c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4468c2ecf20Sopenharmony_ci 0, 0, 4478c2ecf20Sopenharmony_ci 0 4488c2ecf20Sopenharmony_ci }, 4498c2ecf20Sopenharmony_ci { 4508c2ecf20Sopenharmony_ci 0x1571, 0xa004, 4518c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4528c2ecf20Sopenharmony_ci 0, 0, 4538c2ecf20Sopenharmony_ci 0, 4548c2ecf20Sopenharmony_ci }, 4558c2ecf20Sopenharmony_ci { 4568c2ecf20Sopenharmony_ci 0x1571, 0xa005, 4578c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4588c2ecf20Sopenharmony_ci 0, 0, 4598c2ecf20Sopenharmony_ci 0 4608c2ecf20Sopenharmony_ci }, 4618c2ecf20Sopenharmony_ci { 4628c2ecf20Sopenharmony_ci 0x1571, 0xa006, 4638c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4648c2ecf20Sopenharmony_ci 0, 0, 4658c2ecf20Sopenharmony_ci 0 4668c2ecf20Sopenharmony_ci }, 4678c2ecf20Sopenharmony_ci { 4688c2ecf20Sopenharmony_ci 0x1571, 0xa007, 4698c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4708c2ecf20Sopenharmony_ci 0, 0, 4718c2ecf20Sopenharmony_ci 0 4728c2ecf20Sopenharmony_ci }, 4738c2ecf20Sopenharmony_ci { 4748c2ecf20Sopenharmony_ci 0x1571, 0xa008, 4758c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4768c2ecf20Sopenharmony_ci 0, 0, 4778c2ecf20Sopenharmony_ci 0 4788c2ecf20Sopenharmony_ci }, 4798c2ecf20Sopenharmony_ci { 4808c2ecf20Sopenharmony_ci 0x1571, 0xa009, 4818c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4828c2ecf20Sopenharmony_ci 0, 0, 4838c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_5mbit 4848c2ecf20Sopenharmony_ci }, 4858c2ecf20Sopenharmony_ci { 4868c2ecf20Sopenharmony_ci 0x1571, 0xa00a, 4878c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4888c2ecf20Sopenharmony_ci 0, 0, 4898c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_5mbit 4908c2ecf20Sopenharmony_ci }, 4918c2ecf20Sopenharmony_ci { 4928c2ecf20Sopenharmony_ci 0x1571, 0xa00b, 4938c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 4948c2ecf20Sopenharmony_ci 0, 0, 4958c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_5mbit 4968c2ecf20Sopenharmony_ci }, 4978c2ecf20Sopenharmony_ci { 4988c2ecf20Sopenharmony_ci 0x1571, 0xa00c, 4998c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5008c2ecf20Sopenharmony_ci 0, 0, 5018c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_5mbit 5028c2ecf20Sopenharmony_ci }, 5038c2ecf20Sopenharmony_ci { 5048c2ecf20Sopenharmony_ci 0x1571, 0xa00d, 5058c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5068c2ecf20Sopenharmony_ci 0, 0, 5078c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_5mbit 5088c2ecf20Sopenharmony_ci }, 5098c2ecf20Sopenharmony_ci { 5108c2ecf20Sopenharmony_ci 0x1571, 0xa00e, 5118c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5128c2ecf20Sopenharmony_ci 0, 0, 5138c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_5mbit 5148c2ecf20Sopenharmony_ci }, 5158c2ecf20Sopenharmony_ci { 5168c2ecf20Sopenharmony_ci 0x1571, 0xa201, 5178c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5188c2ecf20Sopenharmony_ci 0, 0, 5198c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5208c2ecf20Sopenharmony_ci }, 5218c2ecf20Sopenharmony_ci { 5228c2ecf20Sopenharmony_ci 0x1571, 0xa202, 5238c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5248c2ecf20Sopenharmony_ci 0, 0, 5258c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5268c2ecf20Sopenharmony_ci }, 5278c2ecf20Sopenharmony_ci { 5288c2ecf20Sopenharmony_ci 0x1571, 0xa203, 5298c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5308c2ecf20Sopenharmony_ci 0, 0, 5318c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5328c2ecf20Sopenharmony_ci }, 5338c2ecf20Sopenharmony_ci { 5348c2ecf20Sopenharmony_ci 0x1571, 0xa204, 5358c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5368c2ecf20Sopenharmony_ci 0, 0, 5378c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5388c2ecf20Sopenharmony_ci }, 5398c2ecf20Sopenharmony_ci { 5408c2ecf20Sopenharmony_ci 0x1571, 0xa205, 5418c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5428c2ecf20Sopenharmony_ci 0, 0, 5438c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5448c2ecf20Sopenharmony_ci }, 5458c2ecf20Sopenharmony_ci { 5468c2ecf20Sopenharmony_ci 0x1571, 0xa206, 5478c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5488c2ecf20Sopenharmony_ci 0, 0, 5498c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5508c2ecf20Sopenharmony_ci }, 5518c2ecf20Sopenharmony_ci { 5528c2ecf20Sopenharmony_ci 0x10B5, 0x9030, 5538c2ecf20Sopenharmony_ci 0x10B5, 0x2978, 5548c2ecf20Sopenharmony_ci 0, 0, 5558c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_sohard 5568c2ecf20Sopenharmony_ci }, 5578c2ecf20Sopenharmony_ci { 5588c2ecf20Sopenharmony_ci 0x10B5, 0x9050, 5598c2ecf20Sopenharmony_ci 0x10B5, 0x2273, 5608c2ecf20Sopenharmony_ci 0, 0, 5618c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_sohard 5628c2ecf20Sopenharmony_ci }, 5638c2ecf20Sopenharmony_ci { 5648c2ecf20Sopenharmony_ci 0x10B5, 0x9050, 5658c2ecf20Sopenharmony_ci 0x10B5, 0x3263, 5668c2ecf20Sopenharmony_ci 0, 0, 5678c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_eae_arc1 5688c2ecf20Sopenharmony_ci }, 5698c2ecf20Sopenharmony_ci { 5708c2ecf20Sopenharmony_ci 0x10B5, 0x9050, 5718c2ecf20Sopenharmony_ci 0x10B5, 0x3292, 5728c2ecf20Sopenharmony_ci 0, 0, 5738c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_eae_ma1 5748c2ecf20Sopenharmony_ci }, 5758c2ecf20Sopenharmony_ci { 5768c2ecf20Sopenharmony_ci 0x10B5, 0x9050, 5778c2ecf20Sopenharmony_ci 0x10B5, 0x3294, 5788c2ecf20Sopenharmony_ci 0, 0, 5798c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_eae_fb2 5808c2ecf20Sopenharmony_ci }, 5818c2ecf20Sopenharmony_ci { 5828c2ecf20Sopenharmony_ci 0x14BA, 0x6000, 5838c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5848c2ecf20Sopenharmony_ci 0, 0, 5858c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5868c2ecf20Sopenharmony_ci }, 5878c2ecf20Sopenharmony_ci { 5888c2ecf20Sopenharmony_ci 0x10B5, 0x2200, 5898c2ecf20Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 5908c2ecf20Sopenharmony_ci 0, 0, 5918c2ecf20Sopenharmony_ci (kernel_ulong_t)&card_info_10mbit 5928c2ecf20Sopenharmony_ci }, 5938c2ecf20Sopenharmony_ci { 0, } 5948c2ecf20Sopenharmony_ci}; 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, com20020pci_id_table); 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic struct pci_driver com20020pci_driver = { 5998c2ecf20Sopenharmony_ci .name = "com20020", 6008c2ecf20Sopenharmony_ci .id_table = com20020pci_id_table, 6018c2ecf20Sopenharmony_ci .probe = com20020pci_probe, 6028c2ecf20Sopenharmony_ci .remove = com20020pci_remove, 6038c2ecf20Sopenharmony_ci}; 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_cistatic int __init com20020pci_init(void) 6068c2ecf20Sopenharmony_ci{ 6078c2ecf20Sopenharmony_ci if (BUGLVL(D_NORMAL)) 6088c2ecf20Sopenharmony_ci pr_info("%s\n", "COM20020 PCI support"); 6098c2ecf20Sopenharmony_ci return pci_register_driver(&com20020pci_driver); 6108c2ecf20Sopenharmony_ci} 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_cistatic void __exit com20020pci_cleanup(void) 6138c2ecf20Sopenharmony_ci{ 6148c2ecf20Sopenharmony_ci pci_unregister_driver(&com20020pci_driver); 6158c2ecf20Sopenharmony_ci} 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_cimodule_init(com20020pci_init) 6188c2ecf20Sopenharmony_cimodule_exit(com20020pci_cleanup) 619