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