]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/arcnet/com20020-pci.c
Merge remote-tracking branch 'input-current/for-linus'
[karo-tx-linux.git] / drivers / net / arcnet / com20020-pci.c
index 06621e95bd383bd004aa3e8f429ab011eb30d790..239de38fbd6a588bbb0e90e3452ea60ca1e5a161 100644 (file)
@@ -26,6 +26,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/arcdevice.h>
-#include <linux/com20020.h>
 #include <linux/list.h>
+#include <linux/io.h>
+#include <linux/leds.h>
 
-#include <asm/io.h>
-
-#define VERSION "arcnet: COM20020 PCI support\n"
+#include "arcdevice.h"
+#include "com20020.h"
 
 /* Module parameters */
 
@@ -61,11 +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)
+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;
@@ -82,9 +116,22 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 
        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;
@@ -94,18 +141,19 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
                        ret = -ENOMEM;
                        goto out_port;
                }
+               dev->dev_port = i;
 
                dev->netdev_ops = &com20020_netdev_ops;
 
                lp = netdev_priv(dev);
 
-               BUGMSG(D_NORMAL, "%s Controls\n", ci->name);
+               arc_printk(D_NORMAL, dev, "%s Controls\n", ci->name);
                ioaddr = pci_resource_start(pdev, cm->bar) + cm->offset;
 
                r = devm_request_region(&pdev->dev, ioaddr, cm->size,
                                        "com20020-pci");
                if (!r) {
-                       pr_err("IO region %xh-%xh already allocated.\n",
+                       pr_err("IO region %xh-%xh already allocated\n",
                               ioaddr, ioaddr + cm->size - 1);
                        ret = -EBUSY;
                        goto out_port;
@@ -115,8 +163,8 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
                 * ARCNET controller needs
                 * this access to detect bustype
                 */
-               outb(0x00, ioaddr + 1);
-               inb(ioaddr + 1);
+               arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND);
+               arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT);
 
                dev->base_addr = ioaddr;
                dev->dev_addr[0] = node;
@@ -129,7 +177,14 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
                lp->timeout = timeout;
                lp->hw.owner = THIS_MODULE;
 
-               if (ASTATUS() == 0xFF) {
+               /* 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;
                        goto out_port;
@@ -141,21 +196,46 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 
                card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
                                    GFP_KERNEL);
-               if (!card) {
-                       pr_err("%s out of memory!\n", __func__);
+               if (!card)
                        return -ENOMEM;
-               }
 
                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);
        }
 
@@ -188,7 +268,11 @@ static struct com20020_pci_card_info card_info_10mbit = {
        .name = "ARC-PCI",
        .devcount = 1,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               },
        },
        .flags = ARC_CAN_10MBIT,
 };
@@ -197,7 +281,11 @@ static struct com20020_pci_card_info card_info_5mbit = {
        .name = "ARC-PCI",
        .devcount = 1,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               },
        },
        .flags = ARC_IS_5MBIT,
 };
@@ -207,7 +295,11 @@ static struct com20020_pci_card_info card_info_sohard = {
        .devcount = 1,
        /* SOHARD needs PCI base addr 4 */
        .chan_map_tbl = {
-               {4, 0x00, 0x08},
+               {
+                       .bar = 4,
+                       .offset = 0x00,
+                       .size = 0x08
+               },
        },
        .flags = ARC_CAN_10MBIT,
 };
@@ -216,8 +308,24 @@ static struct com20020_pci_card_info card_info_eae_arc1 = {
        .name = "EAE PLX-PCI ARC1",
        .devcount = 1,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               },
        },
+       .misc_map = {
+               .bar = 2,
+               .offset = 0x10,
+               .size = 0x04,
+       },
+       .leds = {
+               {
+                       .green = 0x0,
+                       .red = 0x1,
+               },
+       },
+       .rotary = 0x0,
        .flags = ARC_CAN_10MBIT,
 };
 
@@ -225,9 +333,31 @@ static struct com20020_pci_card_info card_info_eae_ma1 = {
        .name = "EAE PLX-PCI MA1",
        .devcount = 2,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
-               { 2, 0x08, 0x08 }
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               }, {
+                       .bar = 2,
+                       .offset = 0x08,
+                       .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,
 };
 
@@ -402,7 +532,8 @@ static struct pci_driver com20020pci_driver = {
 
 static int __init com20020pci_init(void)
 {
-       BUGLVL(D_NORMAL) printk(VERSION);
+       if (BUGLVL(D_NORMAL))
+               pr_info("%s\n", "COM20020 PCI support");
        return pci_register_driver(&com20020pci_driver);
 }