linux/drivers/parport/parport_serial.c
<<
>>
Prefs
   1/*
   2 * Support for common PCI multi-I/O cards (which is most of them)
   3 *
   4 * Copyright (C) 2001  Tim Waugh <twaugh@redhat.com>
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 *
  11 *
  12 * Multi-function PCI cards are supposed to present separate logical
  13 * devices on the bus.  A common thing to do seems to be to just use
  14 * one logical device with lots of base address registers for both
  15 * parallel ports and serial ports.  This driver is for dealing with
  16 * that.
  17 *
  18 */
  19
  20#include <linux/types.h>
  21#include <linux/module.h>
  22#include <linux/init.h>
  23#include <linux/slab.h>
  24#include <linux/pci.h>
  25#include <linux/interrupt.h>
  26#include <linux/parport.h>
  27#include <linux/parport_pc.h>
  28#include <linux/8250_pci.h>
  29
  30enum parport_pc_pci_cards {
  31        titan_110l = 0,
  32        titan_210l,
  33        netmos_9xx5_combo,
  34        netmos_9855,
  35        netmos_9855_2p,
  36        avlab_1s1p,
  37        avlab_1s2p,
  38        avlab_2s1p,
  39        siig_1s1p_10x,
  40        siig_2s1p_10x,
  41        siig_2p1s_20x,
  42        siig_1s1p_20x,
  43        siig_2s1p_20x,
  44};
  45
  46/* each element directly indexed from enum list, above */
  47struct parport_pc_pci {
  48        int numports;
  49        struct { /* BAR (base address registers) numbers in the config
  50                    space header */
  51                int lo;
  52                int hi; /* -1 if not there, >6 for offset-method (max
  53                           BAR is 6) */
  54        } addr[4];
  55
  56        /* If set, this is called immediately after pci_enable_device.
  57         * If it returns non-zero, no probing will take place and the
  58         * ports will not be used. */
  59        int (*preinit_hook) (struct pci_dev *pdev, struct parport_pc_pci *card,
  60                                int autoirq, int autodma);
  61
  62        /* If set, this is called after probing for ports.  If 'failed'
  63         * is non-zero we couldn't use any of the ports. */
  64        void (*postinit_hook) (struct pci_dev *pdev,
  65                                struct parport_pc_pci *card, int failed);
  66};
  67
  68static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, int autoirq, int autodma)
  69{
  70        /* the rule described below doesn't hold for this device */
  71        if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
  72                        dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
  73                        dev->subsystem_device == 0x0299)
  74                return -ENODEV;
  75        /*
  76         * Netmos uses the subdevice ID to indicate the number of parallel
  77         * and serial ports.  The form is 0x00PS, where <P> is the number of
  78         * parallel ports and <S> is the number of serial ports.
  79         */
  80        par->numports = (dev->subsystem_device & 0xf0) >> 4;
  81        if (par->numports > ARRAY_SIZE(par->addr))
  82                par->numports = ARRAY_SIZE(par->addr);
  83        /*
  84         * This function is currently only called for cards with up to
  85         * one parallel port.
  86         * Parallel port BAR is either before or after serial ports BARS;
  87         * hence, lo should be either 0 or equal to the number of serial ports.
  88         */
  89        if (par->addr[0].lo != 0)
  90                par->addr[0].lo = dev->subsystem_device & 0xf;
  91        return 0;
  92}
  93
  94static struct parport_pc_pci cards[] __devinitdata = {
  95        /* titan_110l */                { 1, { { 3, -1 }, } },
  96        /* titan_210l */                { 1, { { 3, -1 }, } },
  97        /* netmos_9xx5_combo */         { 1, { { 2, -1 }, }, netmos_parallel_init },
  98        /* netmos_9855 */               { 1, { { 0, -1 }, }, netmos_parallel_init },
  99        /* netmos_9855_2p */            { 2, { { 0, -1 }, { 2, -1 }, } },
 100        /* avlab_1s1p     */            { 1, { { 1, 2}, } },
 101        /* avlab_1s2p     */            { 2, { { 1, 2}, { 3, 4 },} },
 102        /* avlab_2s1p     */            { 1, { { 2, 3}, } },
 103        /* siig_1s1p_10x */             { 1, { { 3, 4 }, } },
 104        /* siig_2s1p_10x */             { 1, { { 4, 5 }, } },
 105        /* siig_2p1s_20x */             { 2, { { 1, 2 }, { 3, 4 }, } },
 106        /* siig_1s1p_20x */             { 1, { { 1, 2 }, } },
 107        /* siig_2s1p_20x */             { 1, { { 2, 3 }, } },
 108};
 109
 110static struct pci_device_id parport_serial_pci_tbl[] = {
 111        /* PCI cards */
 112        { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L,
 113          PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l },
 114        { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L,
 115          PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l },
 116        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735,
 117          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 118        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9745,
 119          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 120        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
 121          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 122        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
 123          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 124        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
 125          0x1000, 0x0020, 0, 0, netmos_9855_2p },
 126        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
 127          0x1000, 0x0022, 0, 0, netmos_9855_2p },
 128        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
 129          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
 130        /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
 131        { PCI_VENDOR_ID_AFAVLAB, 0x2110,
 132          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
 133        { PCI_VENDOR_ID_AFAVLAB, 0x2111,
 134          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
 135        { PCI_VENDOR_ID_AFAVLAB, 0x2112,
 136          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
 137        { PCI_VENDOR_ID_AFAVLAB, 0x2140,
 138          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
 139        { PCI_VENDOR_ID_AFAVLAB, 0x2141,
 140          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
 141        { PCI_VENDOR_ID_AFAVLAB, 0x2142,
 142          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
 143        { PCI_VENDOR_ID_AFAVLAB, 0x2160,
 144          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
 145        { PCI_VENDOR_ID_AFAVLAB, 0x2161,
 146          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
 147        { PCI_VENDOR_ID_AFAVLAB, 0x2162,
 148          PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
 149        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
 150          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
 151        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
 152          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
 153        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
 154          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
 155        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
 156          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
 157        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
 158          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
 159        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
 160          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
 161        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
 162          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
 163        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
 164          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
 165        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
 166          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
 167        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
 168          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 169        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
 170          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
 171        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
 172          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
 173        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
 174          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 175        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
 176          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 177        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
 178          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 179
 180        { 0, } /* terminate list */
 181};
 182MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
 183
 184/*
 185 * This table describes the serial "geometry" of these boards.  Any
 186 * quirks for these can be found in drivers/serial/8250_pci.c
 187 *
 188 * Cards not tested are marked n/t
 189 * If you have one of these cards and it works for you, please tell me..
 190 */
 191static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
 192        [titan_110l] = {
 193                .flags          = FL_BASE1 | FL_BASE_BARS,
 194                .num_ports      = 1,
 195                .base_baud      = 921600,
 196                .uart_offset    = 8,
 197        },
 198        [titan_210l] = {
 199                .flags          = FL_BASE1 | FL_BASE_BARS,
 200                .num_ports      = 2,
 201                .base_baud      = 921600,
 202                .uart_offset    = 8,
 203        },
 204        [netmos_9xx5_combo] = {
 205                .flags          = FL_BASE0 | FL_BASE_BARS,
 206                .num_ports      = 1,
 207                .base_baud      = 115200,
 208                .uart_offset    = 8,
 209        },
 210        [netmos_9855] = {
 211                .flags          = FL_BASE2 | FL_BASE_BARS,
 212                .num_ports      = 1,
 213                .base_baud      = 115200,
 214                .uart_offset    = 8,
 215        },
 216        [netmos_9855_2p] = {
 217                .flags          = FL_BASE4 | FL_BASE_BARS,
 218                .num_ports      = 1,
 219                .base_baud      = 115200,
 220                .uart_offset    = 8,
 221        },
 222        [avlab_1s1p] = { /* n/t */
 223                .flags          = FL_BASE0 | FL_BASE_BARS,
 224                .num_ports      = 1,
 225                .base_baud      = 115200,
 226                .uart_offset    = 8,
 227        },
 228        [avlab_1s2p] = { /* n/t */
 229                .flags          = FL_BASE0 | FL_BASE_BARS,
 230                .num_ports      = 1,
 231                .base_baud      = 115200,
 232                .uart_offset    = 8,
 233        },
 234        [avlab_2s1p] = { /* n/t */
 235                .flags          = FL_BASE0 | FL_BASE_BARS,
 236                .num_ports      = 2,
 237                .base_baud      = 115200,
 238                .uart_offset    = 8,
 239        },
 240        [siig_1s1p_10x] = {
 241                .flags          = FL_BASE2,
 242                .num_ports      = 1,
 243                .base_baud      = 460800,
 244                .uart_offset    = 8,
 245        },
 246        [siig_2s1p_10x] = {
 247                .flags          = FL_BASE2,
 248                .num_ports      = 1,
 249                .base_baud      = 921600,
 250                .uart_offset    = 8,
 251        },
 252        [siig_2p1s_20x] = {
 253                .flags          = FL_BASE0,
 254                .num_ports      = 1,
 255                .base_baud      = 921600,
 256                .uart_offset    = 8,
 257        },
 258        [siig_1s1p_20x] = {
 259                .flags          = FL_BASE0,
 260                .num_ports      = 1,
 261                .base_baud      = 921600,
 262                .uart_offset    = 8,
 263        },
 264        [siig_2s1p_20x] = {
 265                .flags          = FL_BASE0,
 266                .num_ports      = 1,
 267                .base_baud      = 921600,
 268                .uart_offset    = 8,
 269        },
 270};
 271
 272struct parport_serial_private {
 273        struct serial_private   *serial;
 274        int num_par;
 275        struct parport *port[PARPORT_MAX];
 276        struct parport_pc_pci par;
 277};
 278
 279/* Register the serial port(s) of a PCI card. */
 280static int __devinit serial_register (struct pci_dev *dev,
 281                                      const struct pci_device_id *id)
 282{
 283        struct parport_serial_private *priv = pci_get_drvdata (dev);
 284        struct pciserial_board *board;
 285        struct serial_private *serial;
 286
 287        board = &pci_parport_serial_boards[id->driver_data];
 288        serial = pciserial_init_ports(dev, board);
 289
 290        if (IS_ERR(serial))
 291                return PTR_ERR(serial);
 292
 293        priv->serial = serial;
 294        return 0;
 295}
 296
 297/* Register the parallel port(s) of a PCI card. */
 298static int __devinit parport_register (struct pci_dev *dev,
 299                                       const struct pci_device_id *id)
 300{
 301        struct parport_pc_pci *card;
 302        struct parport_serial_private *priv = pci_get_drvdata (dev);
 303        int n, success = 0;
 304
 305        priv->par = cards[id->driver_data];
 306        card = &priv->par;
 307        if (card->preinit_hook &&
 308            card->preinit_hook (dev, card, PARPORT_IRQ_NONE, PARPORT_DMA_NONE))
 309                return -ENODEV;
 310
 311        for (n = 0; n < card->numports; n++) {
 312                struct parport *port;
 313                int lo = card->addr[n].lo;
 314                int hi = card->addr[n].hi;
 315                unsigned long io_lo, io_hi;
 316                int irq;
 317
 318                if (priv->num_par == ARRAY_SIZE (priv->port)) {
 319                        printk (KERN_WARNING
 320                                "parport_serial: %s: only %zu parallel ports "
 321                                "supported (%d reported)\n", pci_name (dev),
 322                                ARRAY_SIZE(priv->port), card->numports);
 323                        break;
 324                }
 325
 326                io_lo = pci_resource_start (dev, lo);
 327                io_hi = 0;
 328                if ((hi >= 0) && (hi <= 6))
 329                        io_hi = pci_resource_start (dev, hi);
 330                else if (hi > 6)
 331                        io_lo += hi; /* Reinterpret the meaning of
 332                                        "hi" as an offset (see SYBA
 333                                        def.) */
 334                /* TODO: test if sharing interrupts works */
 335                irq = dev->irq;
 336                if (irq == IRQ_NONE) {
 337                        dev_dbg(&dev->dev,
 338                        "PCI parallel port detected: I/O at %#lx(%#lx)\n",
 339                                io_lo, io_hi);
 340                        irq = PARPORT_IRQ_NONE;
 341                } else {
 342                        dev_dbg(&dev->dev,
 343                "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
 344                                io_lo, io_hi, irq);
 345                }
 346                port = parport_pc_probe_port (io_lo, io_hi, irq,
 347                              PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
 348                if (port) {
 349                        priv->port[priv->num_par++] = port;
 350                        success = 1;
 351                }
 352        }
 353
 354        if (card->postinit_hook)
 355                card->postinit_hook (dev, card, !success);
 356
 357        return 0;
 358}
 359
 360static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
 361                                               const struct pci_device_id *id)
 362{
 363        struct parport_serial_private *priv;
 364        int err;
 365
 366        priv = kzalloc (sizeof *priv, GFP_KERNEL);
 367        if (!priv)
 368                return -ENOMEM;
 369        pci_set_drvdata (dev, priv);
 370
 371        err = pci_enable_device (dev);
 372        if (err) {
 373                pci_set_drvdata (dev, NULL);
 374                kfree (priv);
 375                return err;
 376        }
 377
 378        if (parport_register (dev, id)) {
 379                pci_set_drvdata (dev, NULL);
 380                kfree (priv);
 381                return -ENODEV;
 382        }
 383
 384        if (serial_register (dev, id)) {
 385                int i;
 386                for (i = 0; i < priv->num_par; i++)
 387                        parport_pc_unregister_port (priv->port[i]);
 388                pci_set_drvdata (dev, NULL);
 389                kfree (priv);
 390                return -ENODEV;
 391        }
 392
 393        return 0;
 394}
 395
 396static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
 397{
 398        struct parport_serial_private *priv = pci_get_drvdata (dev);
 399        int i;
 400
 401        pci_set_drvdata(dev, NULL);
 402
 403        // Serial ports
 404        if (priv->serial)
 405                pciserial_remove_ports(priv->serial);
 406
 407        // Parallel ports
 408        for (i = 0; i < priv->num_par; i++)
 409                parport_pc_unregister_port (priv->port[i]);
 410
 411        kfree (priv);
 412        return;
 413}
 414
 415#ifdef CONFIG_PM
 416static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
 417{
 418        struct parport_serial_private *priv = pci_get_drvdata(dev);
 419
 420        if (priv->serial)
 421                pciserial_suspend_ports(priv->serial);
 422
 423        /* FIXME: What about parport? */
 424
 425        pci_save_state(dev);
 426        pci_set_power_state(dev, pci_choose_state(dev, state));
 427        return 0;
 428}
 429
 430static int parport_serial_pci_resume(struct pci_dev *dev)
 431{
 432        struct parport_serial_private *priv = pci_get_drvdata(dev);
 433        int err;
 434
 435        pci_set_power_state(dev, PCI_D0);
 436        pci_restore_state(dev);
 437
 438        /*
 439         * The device may have been disabled.  Re-enable it.
 440         */
 441        err = pci_enable_device(dev);
 442        if (err) {
 443                printk(KERN_ERR "parport_serial: %s: error enabling "
 444                        "device for resume (%d)\n", pci_name(dev), err);
 445                return err;
 446        }
 447
 448        if (priv->serial)
 449                pciserial_resume_ports(priv->serial);
 450
 451        /* FIXME: What about parport? */
 452
 453        return 0;
 454}
 455#endif
 456
 457static struct pci_driver parport_serial_pci_driver = {
 458        .name           = "parport_serial",
 459        .id_table       = parport_serial_pci_tbl,
 460        .probe          = parport_serial_pci_probe,
 461        .remove         = __devexit_p(parport_serial_pci_remove),
 462#ifdef CONFIG_PM
 463        .suspend        = parport_serial_pci_suspend,
 464        .resume         = parport_serial_pci_resume,
 465#endif
 466};
 467
 468
 469static int __init parport_serial_init (void)
 470{
 471        return pci_register_driver (&parport_serial_pci_driver);
 472}
 473
 474static void __exit parport_serial_exit (void)
 475{
 476        pci_unregister_driver (&parport_serial_pci_driver);
 477        return;
 478}
 479
 480MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>");
 481MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");
 482MODULE_LICENSE("GPL");
 483
 484module_init(parport_serial_init);
 485module_exit(parport_serial_exit);
 486