diff options
Diffstat (limited to 'drivers/net/arcnet/com20020-pci.c')
| -rw-r--r-- | drivers/net/arcnet/com20020-pci.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index a12bf83be750..239de38fbd6a 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -41,6 +41,7 @@ #include <linux/pci.h> #include <linux/list.h> #include <linux/io.h> +#include <linux/leds.h> #include "arcdevice.h" #include "com20020.h" @@ -62,12 +63,43 @@ module_param(clockp, int, 0); module_param(clockm, int, 0); MODULE_LICENSE("GPL"); +static void led_tx_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct com20020_dev *card; + struct com20020_priv *priv; + struct com20020_pci_card_info *ci; + + card = container_of(led_cdev, struct com20020_dev, tx_led); + + priv = card->pci_priv; + ci = priv->ci; + + outb(!!value, priv->misc + ci->leds[card->index].green); +} + +static void led_recon_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct com20020_dev *card; + struct com20020_priv *priv; + struct com20020_pci_card_info *ci; + + card = container_of(led_cdev, struct com20020_dev, recon_led); + + priv = card->pci_priv; + ci = priv->ci; + + outb(!!value, priv->misc + ci->leds[card->index].red); +} + static void com20020pci_remove(struct pci_dev *pdev); static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct com20020_pci_card_info *ci; + struct com20020_pci_channel_map *mm; struct net_device *dev; struct arcnet_local *lp; struct com20020_priv *priv; @@ -84,9 +116,22 @@ static int com20020pci_probe(struct pci_dev *pdev, ci = (struct com20020_pci_card_info *)id->driver_data; priv->ci = ci; + mm = &ci->misc_map; INIT_LIST_HEAD(&priv->list_dev); + if (mm->size) { + ioaddr = pci_resource_start(pdev, mm->bar) + mm->offset; + r = devm_request_region(&pdev->dev, ioaddr, mm->size, + "com20020-pci"); + if (!r) { + pr_err("IO region %xh-%xh already allocated.\n", + ioaddr, ioaddr + mm->size - 1); + return -EBUSY; + } + priv->misc = ioaddr; + } + for (i = 0; i < ci->devcount; i++) { struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i]; struct com20020_dev *card; @@ -96,6 +141,7 @@ static int com20020pci_probe(struct pci_dev *pdev, ret = -ENOMEM; goto out_port; } + dev->dev_port = i; dev->netdev_ops = &com20020_netdev_ops; @@ -131,6 +177,13 @@ static int com20020pci_probe(struct pci_dev *pdev, lp->timeout = timeout; lp->hw.owner = THIS_MODULE; + /* Get the dev_id from the PLX rotary coder */ + if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) + dev->dev_id = 0xc; + dev->dev_id ^= inb(priv->misc + ci->rotary) >> 4; + + snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); + if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { pr_err("IO address %Xh is empty!\n", ioaddr); ret = -EIO; @@ -148,14 +201,41 @@ static int com20020pci_probe(struct pci_dev *pdev, card->index = i; card->pci_priv = priv; + card->tx_led.brightness_set = led_tx_set; + card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, + GFP_KERNEL, "arc%d-%d-tx", + dev->dev_id, i); + card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "pci:green:tx:%d-%d", + dev->dev_id, i); + + card->tx_led.dev = &dev->dev; + card->recon_led.brightness_set = led_recon_set; + card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, + GFP_KERNEL, "arc%d-%d-recon", + dev->dev_id, i); + card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "pci:red:recon:%d-%d", + dev->dev_id, i); + card->recon_led.dev = &dev->dev; card->dev = dev; + ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); + if (ret) + goto out_port; + + ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); + if (ret) + goto out_port; + dev_set_drvdata(&dev->dev, card); ret = com20020_found(dev, IRQF_SHARED); if (ret) goto out_port; + devm_arcnet_led_init(dev, dev->dev_id, i); + list_add(&card->list, &priv->list_dev); } @@ -234,6 +314,18 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { .size = 0x08, }, }, + .misc_map = { + .bar = 2, + .offset = 0x10, + .size = 0x04, + }, + .leds = { + { + .green = 0x0, + .red = 0x1, + }, + }, + .rotary = 0x0, .flags = ARC_CAN_10MBIT, }; @@ -251,6 +343,21 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { .size = 0x08, } }, + .misc_map = { + .bar = 2, + .offset = 0x10, + .size = 0x04, + }, + .leds = { + { + .green = 0x0, + .red = 0x1, + }, { + .green = 0x2, + .red = 0x3, + }, + }, + .rotary = 0x0, .flags = ARC_CAN_10MBIT, }; |
