linux/drivers/isdn/hardware/mISDN/mISDNinfineon.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * mISDNinfineon.c
   4 *              Support for cards based on following Infineon ISDN chipsets
   5 *              - ISAC + HSCX
   6 *              - IPAC and IPAC-X
   7 *              - ISAC-SX + HSCX
   8 *
   9 * Supported cards:
  10 *              - Dialogic Diva 2.0
  11 *              - Dialogic Diva 2.0U
  12 *              - Dialogic Diva 2.01
  13 *              - Dialogic Diva 2.02
  14 *              - Sedlbauer Speedwin
  15 *              - HST Saphir3
  16 *              - Develo (former ELSA) Microlink PCI (Quickstep 1000)
  17 *              - Develo (former ELSA) Quickstep 3000
  18 *              - Berkom Scitel BRIX Quadro
  19 *              - Dr.Neuhaus (Sagem) Niccy
  20 *
  21 * Author       Karsten Keil <keil@isdn4linux.de>
  22 *
  23 * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
  24 */
  25
  26#include <linux/interrupt.h>
  27#include <linux/module.h>
  28#include <linux/pci.h>
  29#include <linux/delay.h>
  30#include <linux/mISDNhw.h>
  31#include <linux/slab.h>
  32#include "ipac.h"
  33
  34#define INFINEON_REV    "1.0"
  35
  36static int inf_cnt;
  37static u32 debug;
  38static u32 irqloops = 4;
  39
  40enum inf_types {
  41        INF_NONE,
  42        INF_DIVA20,
  43        INF_DIVA20U,
  44        INF_DIVA201,
  45        INF_DIVA202,
  46        INF_SPEEDWIN,
  47        INF_SAPHIR3,
  48        INF_QS1000,
  49        INF_QS3000,
  50        INF_NICCY,
  51        INF_SCT_1,
  52        INF_SCT_2,
  53        INF_SCT_3,
  54        INF_SCT_4,
  55        INF_GAZEL_R685,
  56        INF_GAZEL_R753
  57};
  58
  59enum addr_mode {
  60        AM_NONE = 0,
  61        AM_IO,
  62        AM_MEMIO,
  63        AM_IND_IO,
  64};
  65
  66struct inf_cinfo {
  67        enum inf_types  typ;
  68        const char      *full;
  69        const char      *name;
  70        enum addr_mode  cfg_mode;
  71        enum addr_mode  addr_mode;
  72        u8              cfg_bar;
  73        u8              addr_bar;
  74        void            *irqfunc;
  75};
  76
  77struct _ioaddr {
  78        enum addr_mode  mode;
  79        union {
  80                void __iomem    *p;
  81                struct _ioport  io;
  82        } a;
  83};
  84
  85struct _iohandle {
  86        enum addr_mode  mode;
  87        resource_size_t size;
  88        resource_size_t start;
  89        void __iomem    *p;
  90};
  91
  92struct inf_hw {
  93        struct list_head        list;
  94        struct pci_dev          *pdev;
  95        const struct inf_cinfo  *ci;
  96        char                    name[MISDN_MAX_IDLEN];
  97        u32                     irq;
  98        u32                     irqcnt;
  99        struct _iohandle        cfg;
 100        struct _iohandle        addr;
 101        struct _ioaddr          isac;
 102        struct _ioaddr          hscx;
 103        spinlock_t              lock;   /* HW access lock */
 104        struct ipac_hw          ipac;
 105        struct inf_hw           *sc[3]; /* slave cards */
 106};
 107
 108
 109#define PCI_SUBVENDOR_HST_SAPHIR3       0x52
 110#define PCI_SUBVENDOR_SEDLBAUER_PCI     0x53
 111#define PCI_SUB_ID_SEDLBAUER            0x01
 112
 113static struct pci_device_id infineon_ids[] = {
 114        { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
 115        { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
 116        { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
 117        { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
 118        { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
 119          PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
 120          INF_SPEEDWIN },
 121        { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
 122          PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
 123        { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
 124        { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
 125        { PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
 126        { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
 127          PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
 128          INF_SCT_1 },
 129        { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
 130        { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
 131        { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
 132        { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
 133        { }
 134};
 135MODULE_DEVICE_TABLE(pci, infineon_ids);
 136
 137/* PCI interface specific defines */
 138/* Diva 2.0/2.0U */
 139#define DIVA_HSCX_PORT          0x00
 140#define DIVA_HSCX_ALE           0x04
 141#define DIVA_ISAC_PORT          0x08
 142#define DIVA_ISAC_ALE           0x0C
 143#define DIVA_PCI_CTRL           0x10
 144
 145/* DIVA_PCI_CTRL bits */
 146#define DIVA_IRQ_BIT            0x01
 147#define DIVA_RESET_BIT          0x08
 148#define DIVA_EEPROM_CLK         0x40
 149#define DIVA_LED_A              0x10
 150#define DIVA_LED_B              0x20
 151#define DIVA_IRQ_CLR            0x80
 152
 153/* Diva 2.01/2.02 */
 154/* Siemens PITA */
 155#define PITA_ICR_REG            0x00
 156#define PITA_INT0_STATUS        0x02
 157
 158#define PITA_MISC_REG           0x1c
 159#define PITA_PARA_SOFTRESET     0x01000000
 160#define PITA_SER_SOFTRESET      0x02000000
 161#define PITA_PARA_MPX_MODE      0x04000000
 162#define PITA_INT0_ENABLE        0x00020000
 163
 164/* TIGER 100 Registers */
 165#define TIGER_RESET_ADDR        0x00
 166#define TIGER_EXTERN_RESET      0x01
 167#define TIGER_AUX_CTRL          0x02
 168#define TIGER_AUX_DATA          0x03
 169#define TIGER_AUX_IRQMASK       0x05
 170#define TIGER_AUX_STATUS        0x07
 171
 172/* Tiger AUX BITs */
 173#define TIGER_IOMASK            0xdd    /* 1 and 5 are inputs */
 174#define TIGER_IRQ_BIT           0x02
 175
 176#define TIGER_IPAC_ALE          0xC0
 177#define TIGER_IPAC_PORT         0xC8
 178
 179/* ELSA (now Develo) PCI cards */
 180#define ELSA_IRQ_ADDR           0x4c
 181#define ELSA_IRQ_MASK           0x04
 182#define QS1000_IRQ_OFF          0x01
 183#define QS3000_IRQ_OFF          0x03
 184#define QS1000_IRQ_ON           0x41
 185#define QS3000_IRQ_ON           0x43
 186
 187/* Dr Neuhaus/Sagem Niccy */
 188#define NICCY_ISAC_PORT         0x00
 189#define NICCY_HSCX_PORT         0x01
 190#define NICCY_ISAC_ALE          0x02
 191#define NICCY_HSCX_ALE          0x03
 192
 193#define NICCY_IRQ_CTRL_REG      0x38
 194#define NICCY_IRQ_ENABLE        0x001f00
 195#define NICCY_IRQ_DISABLE       0xff0000
 196#define NICCY_IRQ_BIT           0x800000
 197
 198
 199/* Scitel PLX */
 200#define SCT_PLX_IRQ_ADDR        0x4c
 201#define SCT_PLX_RESET_ADDR      0x50
 202#define SCT_PLX_IRQ_ENABLE      0x41
 203#define SCT_PLX_RESET_BIT       0x04
 204
 205/* Gazel */
 206#define GAZEL_IPAC_DATA_PORT    0x04
 207/* Gazel PLX */
 208#define GAZEL_CNTRL             0x50
 209#define GAZEL_RESET             0x04
 210#define GAZEL_RESET_9050        0x40000000
 211#define GAZEL_INCSR             0x4C
 212#define GAZEL_ISAC_EN           0x08
 213#define GAZEL_INT_ISAC          0x20
 214#define GAZEL_HSCX_EN           0x01
 215#define GAZEL_INT_HSCX          0x04
 216#define GAZEL_PCI_EN            0x40
 217#define GAZEL_IPAC_EN           0x03
 218
 219
 220static LIST_HEAD(Cards);
 221static DEFINE_RWLOCK(card_lock); /* protect Cards */
 222
 223static void
 224_set_debug(struct inf_hw *card)
 225{
 226        card->ipac.isac.dch.debug = debug;
 227        card->ipac.hscx[0].bch.debug = debug;
 228        card->ipac.hscx[1].bch.debug = debug;
 229}
 230
 231static int
 232set_debug(const char *val, const struct kernel_param *kp)
 233{
 234        int ret;
 235        struct inf_hw *card;
 236
 237        ret = param_set_uint(val, kp);
 238        if (!ret) {
 239                read_lock(&card_lock);
 240                list_for_each_entry(card, &Cards, list)
 241                        _set_debug(card);
 242                read_unlock(&card_lock);
 243        }
 244        return ret;
 245}
 246
 247MODULE_AUTHOR("Karsten Keil");
 248MODULE_LICENSE("GPL v2");
 249MODULE_VERSION(INFINEON_REV);
 250module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
 251MODULE_PARM_DESC(debug, "infineon debug mask");
 252module_param(irqloops, uint, S_IRUGO | S_IWUSR);
 253MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
 254
 255/* Interface functions */
 256
 257IOFUNC_IO(ISAC, inf_hw, isac.a.io)
 258IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
 259IOFUNC_IND(ISAC, inf_hw, isac.a.io)
 260IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
 261IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
 262IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
 263
 264static irqreturn_t
 265diva_irq(int intno, void *dev_id)
 266{
 267        struct inf_hw *hw = dev_id;
 268        u8 val;
 269
 270        spin_lock(&hw->lock);
 271        val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
 272        if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
 273                spin_unlock(&hw->lock);
 274                return IRQ_NONE; /* shared */
 275        }
 276        hw->irqcnt++;
 277        mISDNipac_irq(&hw->ipac, irqloops);
 278        spin_unlock(&hw->lock);
 279        return IRQ_HANDLED;
 280}
 281
 282static irqreturn_t
 283diva20x_irq(int intno, void *dev_id)
 284{
 285        struct inf_hw *hw = dev_id;
 286        u8 val;
 287
 288        spin_lock(&hw->lock);
 289        val = readb(hw->cfg.p);
 290        if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
 291                spin_unlock(&hw->lock);
 292                return IRQ_NONE; /* shared */
 293        }
 294        hw->irqcnt++;
 295        mISDNipac_irq(&hw->ipac, irqloops);
 296        writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
 297        spin_unlock(&hw->lock);
 298        return IRQ_HANDLED;
 299}
 300
 301static irqreturn_t
 302tiger_irq(int intno, void *dev_id)
 303{
 304        struct inf_hw *hw = dev_id;
 305        u8 val;
 306
 307        spin_lock(&hw->lock);
 308        val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
 309        if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
 310                spin_unlock(&hw->lock);
 311                return IRQ_NONE; /* shared */
 312        }
 313        hw->irqcnt++;
 314        mISDNipac_irq(&hw->ipac, irqloops);
 315        spin_unlock(&hw->lock);
 316        return IRQ_HANDLED;
 317}
 318
 319static irqreturn_t
 320elsa_irq(int intno, void *dev_id)
 321{
 322        struct inf_hw *hw = dev_id;
 323        u8 val;
 324
 325        spin_lock(&hw->lock);
 326        val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
 327        if (!(val & ELSA_IRQ_MASK)) {
 328                spin_unlock(&hw->lock);
 329                return IRQ_NONE; /* shared */
 330        }
 331        hw->irqcnt++;
 332        mISDNipac_irq(&hw->ipac, irqloops);
 333        spin_unlock(&hw->lock);
 334        return IRQ_HANDLED;
 335}
 336
 337static irqreturn_t
 338niccy_irq(int intno, void *dev_id)
 339{
 340        struct inf_hw *hw = dev_id;
 341        u32 val;
 342
 343        spin_lock(&hw->lock);
 344        val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
 345        if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
 346                spin_unlock(&hw->lock);
 347                return IRQ_NONE; /* shared */
 348        }
 349        outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
 350        hw->irqcnt++;
 351        mISDNipac_irq(&hw->ipac, irqloops);
 352        spin_unlock(&hw->lock);
 353        return IRQ_HANDLED;
 354}
 355
 356static irqreturn_t
 357gazel_irq(int intno, void *dev_id)
 358{
 359        struct inf_hw *hw = dev_id;
 360        irqreturn_t ret;
 361
 362        spin_lock(&hw->lock);
 363        ret = mISDNipac_irq(&hw->ipac, irqloops);
 364        spin_unlock(&hw->lock);
 365        return ret;
 366}
 367
 368static irqreturn_t
 369ipac_irq(int intno, void *dev_id)
 370{
 371        struct inf_hw *hw = dev_id;
 372        u8 val;
 373
 374        spin_lock(&hw->lock);
 375        val = hw->ipac.read_reg(hw, IPAC_ISTA);
 376        if (!(val & 0x3f)) {
 377                spin_unlock(&hw->lock);
 378                return IRQ_NONE; /* shared */
 379        }
 380        hw->irqcnt++;
 381        mISDNipac_irq(&hw->ipac, irqloops);
 382        spin_unlock(&hw->lock);
 383        return IRQ_HANDLED;
 384}
 385
 386static void
 387enable_hwirq(struct inf_hw *hw)
 388{
 389        u16 w;
 390        u32 val;
 391
 392        switch (hw->ci->typ) {
 393        case INF_DIVA201:
 394        case INF_DIVA202:
 395                writel(PITA_INT0_ENABLE, hw->cfg.p);
 396                break;
 397        case INF_SPEEDWIN:
 398        case INF_SAPHIR3:
 399                outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
 400                break;
 401        case INF_QS1000:
 402                outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
 403                break;
 404        case INF_QS3000:
 405                outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
 406                break;
 407        case INF_NICCY:
 408                val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
 409                val |= NICCY_IRQ_ENABLE;
 410                outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
 411                break;
 412        case INF_SCT_1:
 413                w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
 414                w |= SCT_PLX_IRQ_ENABLE;
 415                outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
 416                break;
 417        case INF_GAZEL_R685:
 418                outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
 419                     (u32)hw->cfg.start + GAZEL_INCSR);
 420                break;
 421        case INF_GAZEL_R753:
 422                outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
 423                     (u32)hw->cfg.start + GAZEL_INCSR);
 424                break;
 425        default:
 426                break;
 427        }
 428}
 429
 430static void
 431disable_hwirq(struct inf_hw *hw)
 432{
 433        u16 w;
 434        u32 val;
 435
 436        switch (hw->ci->typ) {
 437        case INF_DIVA201:
 438        case INF_DIVA202:
 439                writel(0, hw->cfg.p);
 440                break;
 441        case INF_SPEEDWIN:
 442        case INF_SAPHIR3:
 443                outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
 444                break;
 445        case INF_QS1000:
 446                outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
 447                break;
 448        case INF_QS3000:
 449                outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
 450                break;
 451        case INF_NICCY:
 452                val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
 453                val &= NICCY_IRQ_DISABLE;
 454                outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
 455                break;
 456        case INF_SCT_1:
 457                w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
 458                w &= (~SCT_PLX_IRQ_ENABLE);
 459                outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
 460                break;
 461        case INF_GAZEL_R685:
 462        case INF_GAZEL_R753:
 463                outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
 464                break;
 465        default:
 466                break;
 467        }
 468}
 469
 470static void
 471ipac_chip_reset(struct inf_hw *hw)
 472{
 473        hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
 474        mdelay(5);
 475        hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
 476        mdelay(5);
 477        hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
 478        hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
 479}
 480
 481static void
 482reset_inf(struct inf_hw *hw)
 483{
 484        u16 w;
 485        u32 val;
 486
 487        if (debug & DEBUG_HW)
 488                pr_notice("%s: resetting card\n", hw->name);
 489        switch (hw->ci->typ) {
 490        case INF_DIVA20:
 491        case INF_DIVA20U:
 492                outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
 493                mdelay(10);
 494                outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
 495                mdelay(10);
 496                /* Workaround PCI9060 */
 497                outb(9, (u32)hw->cfg.start + 0x69);
 498                outb(DIVA_RESET_BIT | DIVA_LED_A,
 499                     (u32)hw->cfg.start + DIVA_PCI_CTRL);
 500                break;
 501        case INF_DIVA201:
 502                writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
 503                       hw->cfg.p + PITA_MISC_REG);
 504                mdelay(1);
 505                writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
 506                mdelay(10);
 507                break;
 508        case INF_DIVA202:
 509                writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
 510                       hw->cfg.p + PITA_MISC_REG);
 511                mdelay(1);
 512                writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
 513                       hw->cfg.p + PITA_MISC_REG);
 514                mdelay(10);
 515                break;
 516        case INF_SPEEDWIN:
 517        case INF_SAPHIR3:
 518                ipac_chip_reset(hw);
 519                hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
 520                hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
 521                hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
 522                break;
 523        case INF_QS1000:
 524        case INF_QS3000:
 525                ipac_chip_reset(hw);
 526                hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
 527                hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
 528                hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
 529                break;
 530        case INF_NICCY:
 531                break;
 532        case INF_SCT_1:
 533                w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
 534                w &= (~SCT_PLX_RESET_BIT);
 535                outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
 536                mdelay(10);
 537                w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
 538                w |= SCT_PLX_RESET_BIT;
 539                outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
 540                mdelay(10);
 541                break;
 542        case INF_GAZEL_R685:
 543                val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
 544                val |= (GAZEL_RESET_9050 + GAZEL_RESET);
 545                outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
 546                val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
 547                mdelay(4);
 548                outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
 549                mdelay(10);
 550                hw->ipac.isac.adf2 = 0x87;
 551                hw->ipac.hscx[0].slot = 0x1f;
 552                hw->ipac.hscx[1].slot = 0x23;
 553                break;
 554        case INF_GAZEL_R753:
 555                val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
 556                val |= (GAZEL_RESET_9050 + GAZEL_RESET);
 557                outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
 558                val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
 559                mdelay(4);
 560                outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
 561                mdelay(10);
 562                ipac_chip_reset(hw);
 563                hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
 564                hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
 565                hw->ipac.conf = 0x01; /* IOM off */
 566                break;
 567        default:
 568                return;
 569        }
 570        enable_hwirq(hw);
 571}
 572
 573static int
 574inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
 575{
 576        int ret = 0;
 577
 578        switch (cmd) {
 579        case HW_RESET_REQ:
 580                reset_inf(hw);
 581                break;
 582        default:
 583                pr_info("%s: %s unknown command %x %lx\n",
 584                        hw->name, __func__, cmd, arg);
 585                ret = -EINVAL;
 586                break;
 587        }
 588        return ret;
 589}
 590
 591static int
 592init_irq(struct inf_hw *hw)
 593{
 594        int     ret, cnt = 3;
 595        u_long  flags;
 596
 597        if (!hw->ci->irqfunc)
 598                return -EINVAL;
 599        ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
 600        if (ret) {
 601                pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
 602                return ret;
 603        }
 604        while (cnt--) {
 605                spin_lock_irqsave(&hw->lock, flags);
 606                reset_inf(hw);
 607                ret = hw->ipac.init(&hw->ipac);
 608                if (ret) {
 609                        spin_unlock_irqrestore(&hw->lock, flags);
 610                        pr_info("%s: ISAC init failed with %d\n",
 611                                hw->name, ret);
 612                        break;
 613                }
 614                spin_unlock_irqrestore(&hw->lock, flags);
 615                msleep_interruptible(10);
 616                if (debug & DEBUG_HW)
 617                        pr_notice("%s: IRQ %d count %d\n", hw->name,
 618                                  hw->irq, hw->irqcnt);
 619                if (!hw->irqcnt) {
 620                        pr_info("%s: IRQ(%d) got no requests during init %d\n",
 621                                hw->name, hw->irq, 3 - cnt);
 622                } else
 623                        return 0;
 624        }
 625        free_irq(hw->irq, hw);
 626        return -EIO;
 627}
 628
 629static void
 630release_io(struct inf_hw *hw)
 631{
 632        if (hw->cfg.mode) {
 633                if (hw->cfg.p) {
 634                        release_mem_region(hw->cfg.start, hw->cfg.size);
 635                        iounmap(hw->cfg.p);
 636                } else
 637                        release_region(hw->cfg.start, hw->cfg.size);
 638                hw->cfg.mode = AM_NONE;
 639        }
 640        if (hw->addr.mode) {
 641                if (hw->addr.p) {
 642                        release_mem_region(hw->addr.start, hw->addr.size);
 643                        iounmap(hw->addr.p);
 644                } else
 645                        release_region(hw->addr.start, hw->addr.size);
 646                hw->addr.mode = AM_NONE;
 647        }
 648}
 649
 650static int
 651setup_io(struct inf_hw *hw)
 652{
 653        int err = 0;
 654
 655        if (hw->ci->cfg_mode) {
 656                hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
 657                hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
 658                if (hw->ci->cfg_mode == AM_MEMIO) {
 659                        if (!request_mem_region(hw->cfg.start, hw->cfg.size,
 660                                                hw->name))
 661                                err = -EBUSY;
 662                } else {
 663                        if (!request_region(hw->cfg.start, hw->cfg.size,
 664                                            hw->name))
 665                                err = -EBUSY;
 666                }
 667                if (err) {
 668                        pr_info("mISDN: %s config port %lx (%lu bytes)"
 669                                "already in use\n", hw->name,
 670                                (ulong)hw->cfg.start, (ulong)hw->cfg.size);
 671                        return err;
 672                }
 673                if (hw->ci->cfg_mode == AM_MEMIO)
 674                        hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
 675                hw->cfg.mode = hw->ci->cfg_mode;
 676                if (debug & DEBUG_HW)
 677                        pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
 678                                  hw->name, (ulong)hw->cfg.start,
 679                                  (ulong)hw->cfg.size, hw->ci->cfg_mode);
 680
 681        }
 682        if (hw->ci->addr_mode) {
 683                hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
 684                hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
 685                if (hw->ci->addr_mode == AM_MEMIO) {
 686                        if (!request_mem_region(hw->addr.start, hw->addr.size,
 687                                                hw->name))
 688                                err = -EBUSY;
 689                } else {
 690                        if (!request_region(hw->addr.start, hw->addr.size,
 691                                            hw->name))
 692                                err = -EBUSY;
 693                }
 694                if (err) {
 695                        pr_info("mISDN: %s address port %lx (%lu bytes)"
 696                                "already in use\n", hw->name,
 697                                (ulong)hw->addr.start, (ulong)hw->addr.size);
 698                        return err;
 699                }
 700                if (hw->ci->addr_mode == AM_MEMIO) {
 701                        hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
 702                        if (unlikely(!hw->addr.p))
 703                                return -ENOMEM;
 704                }
 705                hw->addr.mode = hw->ci->addr_mode;
 706                if (debug & DEBUG_HW)
 707                        pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
 708                                  hw->name, (ulong)hw->addr.start,
 709                                  (ulong)hw->addr.size, hw->ci->addr_mode);
 710
 711        }
 712
 713        switch (hw->ci->typ) {
 714        case INF_DIVA20:
 715        case INF_DIVA20U:
 716                hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
 717                hw->isac.mode = hw->cfg.mode;
 718                hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
 719                hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
 720                hw->hscx.mode = hw->cfg.mode;
 721                hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
 722                hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
 723                break;
 724        case INF_DIVA201:
 725                hw->ipac.type = IPAC_TYPE_IPAC;
 726                hw->ipac.isac.off = 0x80;
 727                hw->isac.mode = hw->addr.mode;
 728                hw->isac.a.p = hw->addr.p;
 729                hw->hscx.mode = hw->addr.mode;
 730                hw->hscx.a.p = hw->addr.p;
 731                break;
 732        case INF_DIVA202:
 733                hw->ipac.type = IPAC_TYPE_IPACX;
 734                hw->isac.mode = hw->addr.mode;
 735                hw->isac.a.p = hw->addr.p;
 736                hw->hscx.mode = hw->addr.mode;
 737                hw->hscx.a.p = hw->addr.p;
 738                break;
 739        case INF_SPEEDWIN:
 740        case INF_SAPHIR3:
 741                hw->ipac.type = IPAC_TYPE_IPAC;
 742                hw->ipac.isac.off = 0x80;
 743                hw->isac.mode = hw->cfg.mode;
 744                hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
 745                hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
 746                hw->hscx.mode = hw->cfg.mode;
 747                hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
 748                hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
 749                outb(0xff, (ulong)hw->cfg.start);
 750                mdelay(1);
 751                outb(0x00, (ulong)hw->cfg.start);
 752                mdelay(1);
 753                outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
 754                break;
 755        case INF_QS1000:
 756        case INF_QS3000:
 757                hw->ipac.type = IPAC_TYPE_IPAC;
 758                hw->ipac.isac.off = 0x80;
 759                hw->isac.a.io.ale = (u32)hw->addr.start;
 760                hw->isac.a.io.port = (u32)hw->addr.start + 1;
 761                hw->isac.mode = hw->addr.mode;
 762                hw->hscx.a.io.ale = (u32)hw->addr.start;
 763                hw->hscx.a.io.port = (u32)hw->addr.start + 1;
 764                hw->hscx.mode = hw->addr.mode;
 765                break;
 766        case INF_NICCY:
 767                hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
 768                hw->isac.mode = hw->addr.mode;
 769                hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
 770                hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
 771                hw->hscx.mode = hw->addr.mode;
 772                hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
 773                hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
 774                break;
 775        case INF_SCT_1:
 776                hw->ipac.type = IPAC_TYPE_IPAC;
 777                hw->ipac.isac.off = 0x80;
 778                hw->isac.a.io.ale = (u32)hw->addr.start;
 779                hw->isac.a.io.port = hw->isac.a.io.ale + 4;
 780                hw->isac.mode = hw->addr.mode;
 781                hw->hscx.a.io.ale = hw->isac.a.io.ale;
 782                hw->hscx.a.io.port = hw->isac.a.io.port;
 783                hw->hscx.mode = hw->addr.mode;
 784                break;
 785        case INF_SCT_2:
 786                hw->ipac.type = IPAC_TYPE_IPAC;
 787                hw->ipac.isac.off = 0x80;
 788                hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
 789                hw->isac.a.io.port = hw->isac.a.io.ale + 4;
 790                hw->isac.mode = hw->addr.mode;
 791                hw->hscx.a.io.ale = hw->isac.a.io.ale;
 792                hw->hscx.a.io.port = hw->isac.a.io.port;
 793                hw->hscx.mode = hw->addr.mode;
 794                break;
 795        case INF_SCT_3:
 796                hw->ipac.type = IPAC_TYPE_IPAC;
 797                hw->ipac.isac.off = 0x80;
 798                hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
 799                hw->isac.a.io.port = hw->isac.a.io.ale + 4;
 800                hw->isac.mode = hw->addr.mode;
 801                hw->hscx.a.io.ale = hw->isac.a.io.ale;
 802                hw->hscx.a.io.port = hw->isac.a.io.port;
 803                hw->hscx.mode = hw->addr.mode;
 804                break;
 805        case INF_SCT_4:
 806                hw->ipac.type = IPAC_TYPE_IPAC;
 807                hw->ipac.isac.off = 0x80;
 808                hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
 809                hw->isac.a.io.port = hw->isac.a.io.ale + 4;
 810                hw->isac.mode = hw->addr.mode;
 811                hw->hscx.a.io.ale = hw->isac.a.io.ale;
 812                hw->hscx.a.io.port = hw->isac.a.io.port;
 813                hw->hscx.mode = hw->addr.mode;
 814                break;
 815        case INF_GAZEL_R685:
 816                hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
 817                hw->ipac.isac.off = 0x80;
 818                hw->isac.mode = hw->addr.mode;
 819                hw->isac.a.io.port = (u32)hw->addr.start;
 820                hw->hscx.mode = hw->addr.mode;
 821                hw->hscx.a.io.port = hw->isac.a.io.port;
 822                break;
 823        case INF_GAZEL_R753:
 824                hw->ipac.type = IPAC_TYPE_IPAC;
 825                hw->ipac.isac.off = 0x80;
 826                hw->isac.mode = hw->addr.mode;
 827                hw->isac.a.io.ale = (u32)hw->addr.start;
 828                hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
 829                hw->hscx.mode = hw->addr.mode;
 830                hw->hscx.a.io.ale = hw->isac.a.io.ale;
 831                hw->hscx.a.io.port = hw->isac.a.io.port;
 832                break;
 833        default:
 834                return -EINVAL;
 835        }
 836        switch (hw->isac.mode) {
 837        case AM_MEMIO:
 838                ASSIGN_FUNC_IPAC(MIO, hw->ipac);
 839                break;
 840        case AM_IND_IO:
 841                ASSIGN_FUNC_IPAC(IND, hw->ipac);
 842                break;
 843        case AM_IO:
 844                ASSIGN_FUNC_IPAC(IO, hw->ipac);
 845                break;
 846        default:
 847                return -EINVAL;
 848        }
 849        return 0;
 850}
 851
 852static void
 853release_card(struct inf_hw *card) {
 854        ulong   flags;
 855        int     i;
 856
 857        spin_lock_irqsave(&card->lock, flags);
 858        disable_hwirq(card);
 859        spin_unlock_irqrestore(&card->lock, flags);
 860        card->ipac.isac.release(&card->ipac.isac);
 861        free_irq(card->irq, card);
 862        mISDN_unregister_device(&card->ipac.isac.dch.dev);
 863        release_io(card);
 864        write_lock_irqsave(&card_lock, flags);
 865        list_del(&card->list);
 866        write_unlock_irqrestore(&card_lock, flags);
 867        switch (card->ci->typ) {
 868        case INF_SCT_2:
 869        case INF_SCT_3:
 870        case INF_SCT_4:
 871                break;
 872        case INF_SCT_1:
 873                for (i = 0; i < 3; i++) {
 874                        if (card->sc[i])
 875                                release_card(card->sc[i]);
 876                        card->sc[i] = NULL;
 877                }
 878                /* fall through */
 879        default:
 880                pci_disable_device(card->pdev);
 881                pci_set_drvdata(card->pdev, NULL);
 882                break;
 883        }
 884        kfree(card);
 885        inf_cnt--;
 886}
 887
 888static int
 889setup_instance(struct inf_hw *card)
 890{
 891        int err;
 892        ulong flags;
 893
 894        snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
 895                 inf_cnt + 1);
 896        write_lock_irqsave(&card_lock, flags);
 897        list_add_tail(&card->list, &Cards);
 898        write_unlock_irqrestore(&card_lock, flags);
 899
 900        _set_debug(card);
 901        card->ipac.isac.name = card->name;
 902        card->ipac.name = card->name;
 903        card->ipac.owner = THIS_MODULE;
 904        spin_lock_init(&card->lock);
 905        card->ipac.isac.hwlock = &card->lock;
 906        card->ipac.hwlock = &card->lock;
 907        card->ipac.ctrl = (void *)&inf_ctrl;
 908
 909        err = setup_io(card);
 910        if (err)
 911                goto error_setup;
 912
 913        card->ipac.isac.dch.dev.Bprotocols =
 914                mISDNipac_init(&card->ipac, card);
 915
 916        if (card->ipac.isac.dch.dev.Bprotocols == 0)
 917                goto error_setup;
 918
 919        err = mISDN_register_device(&card->ipac.isac.dch.dev,
 920                                    &card->pdev->dev, card->name);
 921        if (err)
 922                goto error;
 923
 924        err = init_irq(card);
 925        if (!err)  {
 926                inf_cnt++;
 927                pr_notice("Infineon %d cards installed\n", inf_cnt);
 928                return 0;
 929        }
 930        mISDN_unregister_device(&card->ipac.isac.dch.dev);
 931error:
 932        card->ipac.release(&card->ipac);
 933error_setup:
 934        release_io(card);
 935        write_lock_irqsave(&card_lock, flags);
 936        list_del(&card->list);
 937        write_unlock_irqrestore(&card_lock, flags);
 938        return err;
 939}
 940
 941static const struct inf_cinfo inf_card_info[] = {
 942        {
 943                INF_DIVA20,
 944                "Dialogic Diva 2.0",
 945                "diva20",
 946                AM_IND_IO, AM_NONE, 2, 0,
 947                &diva_irq
 948        },
 949        {
 950                INF_DIVA20U,
 951                "Dialogic Diva 2.0U",
 952                "diva20U",
 953                AM_IND_IO, AM_NONE, 2, 0,
 954                &diva_irq
 955        },
 956        {
 957                INF_DIVA201,
 958                "Dialogic Diva 2.01",
 959                "diva201",
 960                AM_MEMIO, AM_MEMIO, 0, 1,
 961                &diva20x_irq
 962        },
 963        {
 964                INF_DIVA202,
 965                "Dialogic Diva 2.02",
 966                "diva202",
 967                AM_MEMIO, AM_MEMIO, 0, 1,
 968                &diva20x_irq
 969        },
 970        {
 971                INF_SPEEDWIN,
 972                "Sedlbauer SpeedWin PCI",
 973                "speedwin",
 974                AM_IND_IO, AM_NONE, 0, 0,
 975                &tiger_irq
 976        },
 977        {
 978                INF_SAPHIR3,
 979                "HST Saphir 3",
 980                "saphir",
 981                AM_IND_IO, AM_NONE, 0, 0,
 982                &tiger_irq
 983        },
 984        {
 985                INF_QS1000,
 986                "Develo Microlink PCI",
 987                "qs1000",
 988                AM_IO, AM_IND_IO, 1, 3,
 989                &elsa_irq
 990        },
 991        {
 992                INF_QS3000,
 993                "Develo QuickStep 3000",
 994                "qs3000",
 995                AM_IO, AM_IND_IO, 1, 3,
 996                &elsa_irq
 997        },
 998        {
 999                INF_NICCY,
1000                "Sagem NICCY",
1001                "niccy",
1002                AM_IO, AM_IND_IO, 0, 1,
1003                &niccy_irq
1004        },
1005        {
1006                INF_SCT_1,
1007                "SciTel Quadro",
1008                "p1_scitel",
1009                AM_IO, AM_IND_IO, 1, 5,
1010                &ipac_irq
1011        },
1012        {
1013                INF_SCT_2,
1014                "SciTel Quadro",
1015                "p2_scitel",
1016                AM_NONE, AM_IND_IO, 0, 4,
1017                &ipac_irq
1018        },
1019        {
1020                INF_SCT_3,
1021                "SciTel Quadro",
1022                "p3_scitel",
1023                AM_NONE, AM_IND_IO, 0, 3,
1024                &ipac_irq
1025        },
1026        {
1027                INF_SCT_4,
1028                "SciTel Quadro",
1029                "p4_scitel",
1030                AM_NONE, AM_IND_IO, 0, 2,
1031                &ipac_irq
1032        },
1033        {
1034                INF_GAZEL_R685,
1035                "Gazel R685",
1036                "gazel685",
1037                AM_IO, AM_IO, 1, 2,
1038                &gazel_irq
1039        },
1040        {
1041                INF_GAZEL_R753,
1042                "Gazel R753",
1043                "gazel753",
1044                AM_IO, AM_IND_IO, 1, 2,
1045                &ipac_irq
1046        },
1047        {
1048                INF_NONE,
1049        }
1050};
1051
1052static const struct inf_cinfo *
1053get_card_info(enum inf_types typ)
1054{
1055        const struct inf_cinfo *ci = inf_card_info;
1056
1057        while (ci->typ != INF_NONE) {
1058                if (ci->typ == typ)
1059                        return ci;
1060                ci++;
1061        }
1062        return NULL;
1063}
1064
1065static int
1066inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1067{
1068        int err = -ENOMEM;
1069        struct inf_hw *card;
1070
1071        card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1072        if (!card) {
1073                pr_info("No memory for Infineon ISDN card\n");
1074                return err;
1075        }
1076        card->pdev = pdev;
1077        err = pci_enable_device(pdev);
1078        if (err) {
1079                kfree(card);
1080                return err;
1081        }
1082        card->ci = get_card_info(ent->driver_data);
1083        if (!card->ci) {
1084                pr_info("mISDN: do not have information about adapter at %s\n",
1085                        pci_name(pdev));
1086                kfree(card);
1087                pci_disable_device(pdev);
1088                return -EINVAL;
1089        } else
1090                pr_notice("mISDN: found adapter %s at %s\n",
1091                          card->ci->full, pci_name(pdev));
1092
1093        card->irq = pdev->irq;
1094        pci_set_drvdata(pdev, card);
1095        err = setup_instance(card);
1096        if (err) {
1097                pci_disable_device(pdev);
1098                kfree(card);
1099                pci_set_drvdata(pdev, NULL);
1100        } else if (ent->driver_data == INF_SCT_1) {
1101                int i;
1102                struct inf_hw *sc;
1103
1104                for (i = 1; i < 4; i++) {
1105                        sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1106                        if (!sc) {
1107                                release_card(card);
1108                                pci_disable_device(pdev);
1109                                return -ENOMEM;
1110                        }
1111                        sc->irq = card->irq;
1112                        sc->pdev = card->pdev;
1113                        sc->ci = card->ci + i;
1114                        err = setup_instance(sc);
1115                        if (err) {
1116                                pci_disable_device(pdev);
1117                                kfree(sc);
1118                                release_card(card);
1119                                break;
1120                        } else
1121                                card->sc[i - 1] = sc;
1122                }
1123        }
1124        return err;
1125}
1126
1127static void
1128inf_remove(struct pci_dev *pdev)
1129{
1130        struct inf_hw   *card = pci_get_drvdata(pdev);
1131
1132        if (card)
1133                release_card(card);
1134        else
1135                pr_debug("%s: drvdata already removed\n", __func__);
1136}
1137
1138static struct pci_driver infineon_driver = {
1139        .name = "ISDN Infineon pci",
1140        .probe = inf_probe,
1141        .remove = inf_remove,
1142        .id_table = infineon_ids,
1143};
1144
1145static int __init
1146infineon_init(void)
1147{
1148        int err;
1149
1150        pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1151        err = pci_register_driver(&infineon_driver);
1152        return err;
1153}
1154
1155static void __exit
1156infineon_cleanup(void)
1157{
1158        pci_unregister_driver(&infineon_driver);
1159}
1160
1161module_init(infineon_init);
1162module_exit(infineon_cleanup);
1163