// SPDX-License-Identifier: GPL-2.0-only
/*
* mISDNinfineon.c
* Support for cards based on following Infineon ISDN chipsets
* - ISAC + HSCX
* - IPAC and IPAC-X
* - ISAC-SX + HSCX
*
* Supported cards:
* - Dialogic Diva 2.0
* - Dialogic Diva 2.0U
* - Dialogic Diva 2.01
* - Dialogic Diva 2.02
* - Sedlbauer Speedwin
* - HST Saphir3
* - Develo (former ELSA) Microlink PCI (Quickstep 1000)
* - Develo (former ELSA) Quickstep 3000
* - Berkom Scitel BRIX Quadro
* - Dr.Neuhaus (Sagem) Niccy
*
* Author Karsten Keil <keil@isdn4linux.de>
*
* Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
#include <linux/slab.h>
#include "ipac.h"
#define INFINEON_REV "1.0"
static int inf_cnt;
static u32 debug;
static u32 irqloops = 4;
enum inf_types {
INF_NONE,
INF_DIVA20,
INF_DIVA20U,
INF_DIVA201,
INF_DIVA202,
INF_SPEEDWIN,
INF_SAPHIR3,
INF_QS1000,
INF_QS3000,
INF_NICCY,
INF_SCT_1,
INF_SCT_2,
INF_SCT_3,
INF_SCT_4,
INF_GAZEL_R685,
INF_GAZEL_R753
};
enum addr_mode {
AM_NONE = 0,
AM_IO,
AM_MEMIO,
AM_IND_IO,
};
struct inf_cinfo {
enum inf_types typ;
const char *full;
const char *name;
enum addr_mode cfg_mode;
enum addr_mode addr_mode;
u8 cfg_bar;
u8 addr_bar;
void *irqfunc;
};
struct _ioaddr {
enum addr_mode mode;
union {
void __iomem *p;
struct _ioport io;
} a;
};
struct _iohandle {
enum addr_mode mode;
resource_size_t size;
resource_size_t start;
void __iomem *p;
};
struct inf_hw {
struct list_head list;
struct pci_dev *pdev;
const struct inf_cinfo *ci;
char name[MISDN_MAX_IDLEN];
u32 irq;
u32 irqcnt;
struct _iohandle cfg;
struct _iohandle addr;
struct _ioaddr isac;
struct _ioaddr hscx;
spinlock_t lock; /* HW access lock */
struct ipac_hw ipac;
struct inf_hw *sc[3]; /* slave cards */
};
#define PCI_SUBVENDOR_HST_SAPHIR3 0x52
#define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
#define PCI_SUB_ID_SEDLBAUER 0x01
static struct pci_device_id infineon_ids[] = {
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
INF_SPEEDWIN },
{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
{ PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
INF_SCT_1 },
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
{ }
};
MODULE_DEVICE_TABLE(pci, infineon_ids);
/* PCI interface specific defines */
/* Diva 2.0/2.0U */
#define DIVA_HSCX_PORT 0x00
#define DIVA_HSCX_ALE 0x04
#define DIVA_ISAC_PORT 0x08
#define DIVA_ISAC_ALE 0x0C
#define DIVA_PCI_CTRL 0x10
/* DIVA_PCI_CTRL bits */
#define DIVA_IRQ_BIT 0x01
#define DIVA_RESET_BIT 0x08
#define DIVA_EEPROM_CLK 0x40
#define DIVA_LED_A 0x10
#define DIVA_LED_B 0x20
#define DIVA_IRQ_CLR 0x80
/* Diva 2.01/2.02 */
/* Siemens PITA */
#define PITA_ICR_REG 0x00
#define PITA_INT0_STATUS 0x02
#define PITA_MISC_REG 0x1c
#define PITA_PARA_SOFTRESET 0x01000000
#define PITA_SER_SOFTRESET 0x02000000
#define PITA_PARA_MPX_MODE 0x04000000
#define PITA_INT0_ENABLE 0x00020000
/* TIGER 100 Registers */
#define TIGER_RESET_ADDR 0x00
#define TIGER_EXTERN_RESET 0x01
#define TIGER_AUX_CTRL 0x02
#define TIGER_AUX_DATA 0x03
#define TIGER_AUX_IRQMASK 0x05
#define TIGER_AUX_STATUS 0x07
/* Tiger AUX BITs */
#define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
#define TIGER_IRQ_BIT 0x02
#define TIGER_IPAC_ALE 0xC0
#define TIGER_IPAC_PORT 0xC8
/* ELSA (now Develo) PCI cards */
#define ELSA_IRQ_ADDR 0x4c
#define ELSA_IRQ_MASK 0x04
#define QS1000_IRQ_OFF 0x01
#define QS3000_IRQ_OFF 0x03
#define QS1000_IRQ_ON 0x41
#define QS3000_IRQ_ON 0x43
/* Dr Neuhaus/Sagem Niccy */
#define NICCY_ISAC_PORT 0x00
#define NICCY_HSCX_PORT 0x01
#define NICCY_ISAC_ALE 0x02
#define NICCY_HSCX_ALE 0x03
#define NICCY_IRQ_CTRL_REG 0x38
#define NICCY_IRQ_ENABLE 0x001f00
#define NICCY_IRQ_DISABLE 0xff0000
#define NICCY_IRQ_BIT 0x800000
/* Scitel PLX */
#define SCT_PLX_IRQ_ADDR 0x4c
#define SCT_PLX_RESET_ADDR 0x50
#define SCT_PLX_IRQ_ENABLE 0x41
#define SCT_PLX_RESET_BIT 0x04
/* Gazel */
#define GAZEL_IPAC_DATA_PORT 0x04
/* Gazel PLX */
#define GAZEL_CNTRL 0x50
#define GAZEL_RESET 0x04
#define GAZEL_RESET_9050 0x40000000
#define GAZEL_INCSR 0x4C
#define GAZEL_ISAC_EN 0x08
#define GAZEL_INT_ISAC 0x20
#define GAZEL_HSCX_EN 0x01
#define GAZEL_INT_HSCX 0x04