Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Linux ARCnet driver - COM20020 PCI support
  3 * Contemporary Controls PCI20 and SOHARD SH-ARC PCI
  4 * 
  5 * Written 1994-1999 by Avery Pennarun,
  6 *    based on an ISA version by David Woodhouse.
  7 * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
  8 * Derived from skeleton.c by Donald Becker.
  9 *
 10 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
 11 *  for sponsoring the further development of this driver.
 12 *
 13 * **********************
 14 *
 15 * The original copyright of skeleton.c was as follows:
 16 *
 17 * skeleton.c Written 1993 by Donald Becker.
 18 * Copyright 1993 United States Government as represented by the
 19 * Director, National Security Agency.  This software may only be used
 20 * and distributed according to the terms of the GNU General Public License as
 21 * modified by SRC, incorporated herein by reference.
 22 *
 23 * **********************
 24 *
 25 * For more details, see drivers/net/arcnet.c
 26 *
 27 * **********************
 28 */
 
 
 
 29#include <linux/module.h>
 30#include <linux/moduleparam.h>
 31#include <linux/kernel.h>
 32#include <linux/types.h>
 33#include <linux/ioport.h>
 34#include <linux/errno.h>
 35#include <linux/netdevice.h>
 36#include <linux/init.h>
 37#include <linux/interrupt.h>
 38#include <linux/pci.h>
 39#include <linux/arcdevice.h>
 40#include <linux/com20020.h>
 
 41
 42#include <asm/io.h>
 43
 44
 45#define VERSION "arcnet: COM20020 PCI support\n"
 46
 47/* Module parameters */
 48
 49static int node;
 50static char device[9];		/* use eg. device="arc1" to change name */
 51static int timeout = 3;
 52static int backplane;
 53static int clockp;
 54static int clockm;
 55
 56module_param(node, int, 0);
 57module_param_string(device, device, sizeof(device), 0);
 58module_param(timeout, int, 0);
 59module_param(backplane, int, 0);
 60module_param(clockp, int, 0);
 61module_param(clockm, int, 0);
 62MODULE_LICENSE("GPL");
 63
 64static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 65{
 
 
 66	struct net_device *dev;
 67	struct arcnet_local *lp;
 68	int ioaddr, err;
 
 
 
 
 69
 70	if (pci_enable_device(pdev))
 71		return -EIO;
 72	dev = alloc_arcdev(device);
 73	if (!dev)
 
 
 74		return -ENOMEM;
 75
 76	dev->netdev_ops = &com20020_netdev_ops;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 77
 78	lp = netdev_priv(dev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 79
 80	pci_set_drvdata(pdev, dev);
 
 
 
 81
 82	// SOHARD needs PCI base addr 4
 83	if (pdev->vendor==0x10B5) {
 84		BUGMSG(D_NORMAL, "SOHARD\n");
 85		ioaddr = pci_resource_start(pdev, 4);
 86	}
 87	else {
 88		BUGMSG(D_NORMAL, "Contemporary Controls\n");
 89		ioaddr = pci_resource_start(pdev, 2);
 90	}
 91
 92	if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
 93		BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
 94		       ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
 95		err = -EBUSY;
 96		goto out_dev;
 97	}
 98
 99	// Dummy access after Reset
100	// ARCNET controller needs this access to detect bustype
101	outb(0x00,ioaddr+1);
102	inb(ioaddr+1);
103
104	dev->base_addr = ioaddr;
105	dev->irq = pdev->irq;
106	dev->dev_addr[0] = node;
107	lp->card_name = "PCI COM20020";
108	lp->card_flags = id->driver_data;
109	lp->backplane = backplane;
110	lp->clockp = clockp & 7;
111	lp->clockm = clockm & 3;
112	lp->timeout = timeout;
113	lp->hw.owner = THIS_MODULE;
114
115	if (ASTATUS() == 0xFF) {
116		BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
117		       "but seems empty!\n", ioaddr);
118		err = -EIO;
119		goto out_port;
120	}
121	if (com20020_check(dev)) {
122		err = -EIO;
123		goto out_port;
124	}
 
125
126	if ((err = com20020_found(dev, IRQF_SHARED)) != 0)
127	        goto out_port;
 
 
 
 
 
 
 
 
 
 
128
129	return 0;
 
 
 
 
 
 
 
 
 
 
 
130
131out_port:
132	release_region(ioaddr, ARCNET_TOTAL_SIZE);
133out_dev:
134	free_netdev(dev);
135	return err;
136}
 
 
 
 
 
 
 
137
138static void __devexit com20020pci_remove(struct pci_dev *pdev)
139{
140	struct net_device *dev = pci_get_drvdata(pdev);
141	unregister_netdev(dev);
142	free_irq(dev->irq, dev);
143	release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
144	free_netdev(dev);
145}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
147static DEFINE_PCI_DEVICE_TABLE(com20020pci_id_table) = {
148	{ 0x1571, 0xa001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
149	{ 0x1571, 0xa002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
150	{ 0x1571, 0xa003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
151	{ 0x1571, 0xa004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
152	{ 0x1571, 0xa005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
153	{ 0x1571, 0xa006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
154	{ 0x1571, 0xa007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
155	{ 0x1571, 0xa008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
156	{ 0x1571, 0xa009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
157	{ 0x1571, 0xa00a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
158	{ 0x1571, 0xa00b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
159	{ 0x1571, 0xa00c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
160	{ 0x1571, 0xa00d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
161	{ 0x1571, 0xa00e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
162	{ 0x1571, 0xa201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
163	{ 0x1571, 0xa202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
164	{ 0x1571, 0xa203, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
165	{ 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
166	{ 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
167	{ 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
168	{ 0x10B5, 0x9030, 0x10B5,     0x2978,     0, 0, ARC_CAN_10MBIT },
169	{ 0x10B5, 0x9050, 0x10B5,     0x2273,     0, 0, ARC_CAN_10MBIT },
170	{ 0x14BA, 0x6000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
171	{ 0x10B5, 0x2200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
172	{0,}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173};
174
175MODULE_DEVICE_TABLE(pci, com20020pci_id_table);
176
177static struct pci_driver com20020pci_driver = {
178	.name		= "com20020",
179	.id_table	= com20020pci_id_table,
180	.probe		= com20020pci_probe,
181	.remove		= __devexit_p(com20020pci_remove),
182};
183
184static int __init com20020pci_init(void)
185{
186	BUGLVL(D_NORMAL) printk(VERSION);
 
187	return pci_register_driver(&com20020pci_driver);
188}
189
190static void __exit com20020pci_cleanup(void)
191{
192	pci_unregister_driver(&com20020pci_driver);
193}
194
195module_init(com20020pci_init)
196module_exit(com20020pci_cleanup)
v5.14.15
  1/*
  2 * Linux ARCnet driver - COM20020 PCI support
  3 * Contemporary Controls PCI20 and SOHARD SH-ARC PCI
  4 *
  5 * Written 1994-1999 by Avery Pennarun,
  6 *    based on an ISA version by David Woodhouse.
  7 * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
  8 * Derived from skeleton.c by Donald Becker.
  9 *
 10 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
 11 *  for sponsoring the further development of this driver.
 12 *
 13 * **********************
 14 *
 15 * The original copyright of skeleton.c was as follows:
 16 *
 17 * skeleton.c Written 1993 by Donald Becker.
 18 * Copyright 1993 United States Government as represented by the
 19 * Director, National Security Agency.  This software may only be used
 20 * and distributed according to the terms of the GNU General Public License as
 21 * modified by SRC, incorporated herein by reference.
 22 *
 23 * **********************
 24 *
 25 * For more details, see drivers/net/arcnet.c
 26 *
 27 * **********************
 28 */
 29
 30#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
 31
 32#include <linux/module.h>
 33#include <linux/moduleparam.h>
 34#include <linux/kernel.h>
 35#include <linux/types.h>
 36#include <linux/ioport.h>
 37#include <linux/errno.h>
 38#include <linux/netdevice.h>
 39#include <linux/init.h>
 40#include <linux/interrupt.h>
 41#include <linux/pci.h>
 42#include <linux/list.h>
 43#include <linux/io.h>
 44#include <linux/leds.h>
 45
 46#include "arcdevice.h"
 47#include "com20020.h"
 
 
 48
 49/* Module parameters */
 50
 51static int node;
 52static char device[9];		/* use eg. device="arc1" to change name */
 53static int timeout = 3;
 54static int backplane;
 55static int clockp;
 56static int clockm;
 57
 58module_param(node, int, 0);
 59module_param_string(device, device, sizeof(device), 0);
 60module_param(timeout, int, 0);
 61module_param(backplane, int, 0);
 62module_param(clockp, int, 0);
 63module_param(clockm, int, 0);
 64MODULE_LICENSE("GPL");
 65
 66static void led_tx_set(struct led_classdev *led_cdev,
 67			     enum led_brightness value)
 68{
 69	struct com20020_dev *card;
 70	struct com20020_priv *priv;
 71	struct com20020_pci_card_info *ci;
 72
 73	card = container_of(led_cdev, struct com20020_dev, tx_led);
 74
 75	priv = card->pci_priv;
 76	ci = priv->ci;
 77
 78	outb(!!value, priv->misc + ci->leds[card->index].green);
 79}
 80
 81static void led_recon_set(struct led_classdev *led_cdev,
 82			     enum led_brightness value)
 83{
 84	struct com20020_dev *card;
 85	struct com20020_priv *priv;
 86	struct com20020_pci_card_info *ci;
 87
 88	card = container_of(led_cdev, struct com20020_dev, recon_led);
 89
 90	priv = card->pci_priv;
 91	ci = priv->ci;
 92
 93	outb(!!value, priv->misc + ci->leds[card->index].red);
 94}
 95
 96static ssize_t backplane_mode_show(struct device *dev,
 97				   struct device_attribute *attr,
 98				   char *buf)
 99{
100	struct net_device *net_dev = to_net_dev(dev);
101	struct arcnet_local *lp = netdev_priv(net_dev);
102
103	return sprintf(buf, "%s\n", lp->backplane ? "true" : "false");
104}
105static DEVICE_ATTR_RO(backplane_mode);
106
107static struct attribute *com20020_state_attrs[] = {
108	&dev_attr_backplane_mode.attr,
109	NULL,
110};
111
112static const struct attribute_group com20020_state_group = {
113	.name = NULL,
114	.attrs = com20020_state_attrs,
115};
116
117static void com20020pci_remove(struct pci_dev *pdev);
118
119static int com20020pci_probe(struct pci_dev *pdev,
120			     const struct pci_device_id *id)
121{
122	struct com20020_pci_card_info *ci;
123	struct com20020_pci_channel_map *mm;
124	struct net_device *dev;
125	struct arcnet_local *lp;
126	struct com20020_priv *priv;
127	int i, ioaddr, ret;
128	struct resource *r;
129
130	ret = 0;
131
132	if (pci_enable_device(pdev))
133		return -EIO;
134
135	priv = devm_kzalloc(&pdev->dev, sizeof(struct com20020_priv),
136			    GFP_KERNEL);
137	if (!priv)
138		return -ENOMEM;
139
140	ci = (struct com20020_pci_card_info *)id->driver_data;
141	priv->ci = ci;
142	mm = &ci->misc_map;
143
144	pci_set_drvdata(pdev, priv);
145
146	INIT_LIST_HEAD(&priv->list_dev);
147
148	if (mm->size) {
149		ioaddr = pci_resource_start(pdev, mm->bar) + mm->offset;
150		r = devm_request_region(&pdev->dev, ioaddr, mm->size,
151					"com20020-pci");
152		if (!r) {
153			pr_err("IO region %xh-%xh already allocated.\n",
154			       ioaddr, ioaddr + mm->size - 1);
155			return -EBUSY;
156		}
157		priv->misc = ioaddr;
158	}
159
160	for (i = 0; i < ci->devcount; i++) {
161		struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i];
162		struct com20020_dev *card;
163		int dev_id_mask = 0xf;
164
165		dev = alloc_arcdev(device);
166		if (!dev) {
167			ret = -ENOMEM;
168			break;
169		}
170		dev->dev_port = i;
171
172		dev->netdev_ops = &com20020_netdev_ops;
173
174		lp = netdev_priv(dev);
175
176		arc_printk(D_NORMAL, dev, "%s Controls\n", ci->name);
177		ioaddr = pci_resource_start(pdev, cm->bar) + cm->offset;
178
179		r = devm_request_region(&pdev->dev, ioaddr, cm->size,
180					"com20020-pci");
181		if (!r) {
182			pr_err("IO region %xh-%xh already allocated\n",
183			       ioaddr, ioaddr + cm->size - 1);
184			ret = -EBUSY;
185			goto err_free_arcdev;
186		}
187
188		/* Dummy access after Reset
189		 * ARCNET controller needs
190		 * this access to detect bustype
191		 */
192		arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND);
193		arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT);
194
195		SET_NETDEV_DEV(dev, &pdev->dev);
196		dev->base_addr = ioaddr;
197		dev->dev_addr[0] = node;
198		dev->sysfs_groups[0] = &com20020_state_group;
199		dev->irq = pdev->irq;
200		lp->card_name = "PCI COM20020";
201		lp->card_flags = ci->flags;
202		lp->backplane = backplane;
203		lp->clockp = clockp & 7;
204		lp->clockm = clockm & 3;
205		lp->timeout = timeout;
206		lp->hw.owner = THIS_MODULE;
207
208		lp->backplane = (inb(priv->misc) >> (2 + i)) & 0x1;
209
210		if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15))
211			lp->backplane = 1;
212
213		/* Get the dev_id from the PLX rotary coder */
214		if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
215			dev_id_mask = 0x3;
216		dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
217
218		snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
219
220		if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
221			pr_err("IO address %Xh is empty!\n", ioaddr);
222			ret = -EIO;
223			goto err_free_arcdev;
224		}
225		if (com20020_check(dev)) {
226			ret = -EIO;
227			goto err_free_arcdev;
228		}
229
230		card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
231				    GFP_KERNEL);
232		if (!card) {
233			ret = -ENOMEM;
234			goto err_free_arcdev;
235		}
236
237		card->index = i;
238		card->pci_priv = priv;
239		card->tx_led.brightness_set = led_tx_set;
240		card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
241						GFP_KERNEL, "arc%d-%d-tx",
242						dev->dev_id, i);
243		card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
244						"pci:green:tx:%d-%d",
245						dev->dev_id, i);
246
247		card->tx_led.dev = &dev->dev;
248		card->recon_led.brightness_set = led_recon_set;
249		card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
250						GFP_KERNEL, "arc%d-%d-recon",
251						dev->dev_id, i);
252		card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
253						"pci:red:recon:%d-%d",
254						dev->dev_id, i);
255		card->recon_led.dev = &dev->dev;
256		card->dev = dev;
257
258		ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
259		if (ret)
260			goto err_free_arcdev;
261
262		ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
263		if (ret)
264			goto err_free_arcdev;
265
266		dev_set_drvdata(&dev->dev, card);
267
268		ret = com20020_found(dev, IRQF_SHARED);
269		if (ret)
270			goto err_free_arcdev;
271
272		devm_arcnet_led_init(dev, dev->dev_id, i);
273
274		list_add(&card->list, &priv->list_dev);
275		continue;
276
277err_free_arcdev:
278		free_arcdev(dev);
279		break;
280	}
281	if (ret)
282		com20020pci_remove(pdev);
283	return ret;
284}
285
286static void com20020pci_remove(struct pci_dev *pdev)
287{
288	struct com20020_dev *card, *tmpcard;
289	struct com20020_priv *priv;
290
291	priv = pci_get_drvdata(pdev);
 
 
 
 
 
 
 
 
292
293	list_for_each_entry_safe(card, tmpcard, &priv->list_dev, list) {
294		struct net_device *dev = card->dev;
 
 
 
 
295
296		unregister_netdev(dev);
297		free_irq(dev->irq, dev);
298		free_arcdev(dev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299	}
300}
301
302static struct com20020_pci_card_info card_info_10mbit = {
303	.name = "ARC-PCI",
304	.devcount = 1,
305	.chan_map_tbl = {
306		{
307			.bar = 2,
308			.offset = 0x00,
309			.size = 0x08,
310		},
311	},
312	.flags = ARC_CAN_10MBIT,
313};
314
315static struct com20020_pci_card_info card_info_5mbit = {
316	.name = "ARC-PCI",
317	.devcount = 1,
318	.chan_map_tbl = {
319		{
320			.bar = 2,
321			.offset = 0x00,
322			.size = 0x08,
323		},
324	},
325	.flags = ARC_IS_5MBIT,
326};
327
328static struct com20020_pci_card_info card_info_sohard = {
329	.name = "PLX-PCI",
330	.devcount = 1,
331	/* SOHARD needs PCI base addr 4 */
332	.chan_map_tbl = {
333		{
334			.bar = 4,
335			.offset = 0x00,
336			.size = 0x08
337		},
338	},
339	.flags = ARC_CAN_10MBIT,
340};
341
342static struct com20020_pci_card_info card_info_eae_arc1 = {
343	.name = "EAE PLX-PCI ARC1",
344	.devcount = 1,
345	.chan_map_tbl = {
346		{
347			.bar = 2,
348			.offset = 0x00,
349			.size = 0x08,
350		},
351	},
352	.misc_map = {
353		.bar = 2,
354		.offset = 0x10,
355		.size = 0x04,
356	},
357	.leds = {
358		{
359			.green = 0x0,
360			.red = 0x1,
361		},
362	},
363	.rotary = 0x0,
364	.flags = ARC_CAN_10MBIT,
365};
366
367static struct com20020_pci_card_info card_info_eae_ma1 = {
368	.name = "EAE PLX-PCI MA1",
369	.devcount = 2,
370	.chan_map_tbl = {
371		{
372			.bar = 2,
373			.offset = 0x00,
374			.size = 0x08,
375		}, {
376			.bar = 2,
377			.offset = 0x08,
378			.size = 0x08,
379		}
380	},
381	.misc_map = {
382		.bar = 2,
383		.offset = 0x10,
384		.size = 0x04,
385	},
386	.leds = {
387		{
388			.green = 0x0,
389			.red = 0x1,
390		}, {
391			.green = 0x2,
392			.red = 0x3,
393		},
394	},
395	.rotary = 0x0,
396	.flags = ARC_CAN_10MBIT,
397};
398
399static struct com20020_pci_card_info card_info_eae_fb2 = {
400	.name = "EAE PLX-PCI FB2",
401	.devcount = 1,
402	.chan_map_tbl = {
403		{
404			.bar = 2,
405			.offset = 0x00,
406			.size = 0x08,
407		},
408	},
409	.misc_map = {
410		.bar = 2,
411		.offset = 0x10,
412		.size = 0x04,
413	},
414	.leds = {
415		{
416			.green = 0x0,
417			.red = 0x1,
418		},
419	},
420	.rotary = 0x0,
421	.flags = ARC_CAN_10MBIT,
422};
423
424static const struct pci_device_id com20020pci_id_table[] = {
425	{
426		0x1571, 0xa001,
427		PCI_ANY_ID, PCI_ANY_ID,
428		0, 0,
429		0,
430	},
431	{
432		0x1571, 0xa002,
433		PCI_ANY_ID, PCI_ANY_ID,
434		0, 0,
435		0,
436	},
437	{
438		0x1571, 0xa003,
439		PCI_ANY_ID, PCI_ANY_ID,
440		0, 0,
441		0
442	},
443	{
444		0x1571, 0xa004,
445		PCI_ANY_ID, PCI_ANY_ID,
446		0, 0,
447		0,
448	},
449	{
450		0x1571, 0xa005,
451		PCI_ANY_ID, PCI_ANY_ID,
452		0, 0,
453		0
454	},
455	{
456		0x1571, 0xa006,
457		PCI_ANY_ID, PCI_ANY_ID,
458		0, 0,
459		0
460	},
461	{
462		0x1571, 0xa007,
463		PCI_ANY_ID, PCI_ANY_ID,
464		0, 0,
465		0
466	},
467	{
468		0x1571, 0xa008,
469		PCI_ANY_ID, PCI_ANY_ID,
470		0, 0,
471		0
472	},
473	{
474		0x1571, 0xa009,
475		PCI_ANY_ID, PCI_ANY_ID,
476		0, 0,
477		(kernel_ulong_t)&card_info_5mbit
478	},
479	{
480		0x1571, 0xa00a,
481		PCI_ANY_ID, PCI_ANY_ID,
482		0, 0,
483		(kernel_ulong_t)&card_info_5mbit
484	},
485	{
486		0x1571, 0xa00b,
487		PCI_ANY_ID, PCI_ANY_ID,
488		0, 0,
489		(kernel_ulong_t)&card_info_5mbit
490	},
491	{
492		0x1571, 0xa00c,
493		PCI_ANY_ID, PCI_ANY_ID,
494		0, 0,
495		(kernel_ulong_t)&card_info_5mbit
496	},
497	{
498		0x1571, 0xa00d,
499		PCI_ANY_ID, PCI_ANY_ID,
500		0, 0,
501		(kernel_ulong_t)&card_info_5mbit
502	},
503	{
504		0x1571, 0xa00e,
505		PCI_ANY_ID, PCI_ANY_ID,
506		0, 0,
507		(kernel_ulong_t)&card_info_5mbit
508	},
509	{
510		0x1571, 0xa201,
511		PCI_ANY_ID, PCI_ANY_ID,
512		0, 0,
513		(kernel_ulong_t)&card_info_10mbit
514	},
515	{
516		0x1571, 0xa202,
517		PCI_ANY_ID, PCI_ANY_ID,
518		0, 0,
519		(kernel_ulong_t)&card_info_10mbit
520	},
521	{
522		0x1571, 0xa203,
523		PCI_ANY_ID, PCI_ANY_ID,
524		0, 0,
525		(kernel_ulong_t)&card_info_10mbit
526	},
527	{
528		0x1571, 0xa204,
529		PCI_ANY_ID, PCI_ANY_ID,
530		0, 0,
531		(kernel_ulong_t)&card_info_10mbit
532	},
533	{
534		0x1571, 0xa205,
535		PCI_ANY_ID, PCI_ANY_ID,
536		0, 0,
537		(kernel_ulong_t)&card_info_10mbit
538	},
539	{
540		0x1571, 0xa206,
541		PCI_ANY_ID, PCI_ANY_ID,
542		0, 0,
543		(kernel_ulong_t)&card_info_10mbit
544	},
545	{
546		0x10B5, 0x9030,
547		0x10B5, 0x2978,
548		0, 0,
549		(kernel_ulong_t)&card_info_sohard
550	},
551	{
552		0x10B5, 0x9050,
553		0x10B5, 0x2273,
554		0, 0,
555		(kernel_ulong_t)&card_info_sohard
556	},
557	{
558		0x10B5, 0x9050,
559		0x10B5, 0x3263,
560		0, 0,
561		(kernel_ulong_t)&card_info_eae_arc1
562	},
563	{
564		0x10B5, 0x9050,
565		0x10B5, 0x3292,
566		0, 0,
567		(kernel_ulong_t)&card_info_eae_ma1
568	},
569	{
570		0x10B5, 0x9050,
571		0x10B5, 0x3294,
572		0, 0,
573		(kernel_ulong_t)&card_info_eae_fb2
574	},
575	{
576		0x14BA, 0x6000,
577		PCI_ANY_ID, PCI_ANY_ID,
578		0, 0,
579		(kernel_ulong_t)&card_info_10mbit
580	},
581	{
582		0x10B5, 0x2200,
583		PCI_ANY_ID, PCI_ANY_ID,
584		0, 0,
585		(kernel_ulong_t)&card_info_10mbit
586	},
587	{ 0, }
588};
589
590MODULE_DEVICE_TABLE(pci, com20020pci_id_table);
591
592static struct pci_driver com20020pci_driver = {
593	.name		= "com20020",
594	.id_table	= com20020pci_id_table,
595	.probe		= com20020pci_probe,
596	.remove		= com20020pci_remove,
597};
598
599static int __init com20020pci_init(void)
600{
601	if (BUGLVL(D_NORMAL))
602		pr_info("%s\n", "COM20020 PCI support");
603	return pci_register_driver(&com20020pci_driver);
604}
605
606static void __exit com20020pci_cleanup(void)
607{
608	pci_unregister_driver(&com20020pci_driver);
609}
610
611module_init(com20020pci_init)
612module_exit(com20020pci_cleanup)