Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

View file

@ -0,0 +1,94 @@
#
# Hardware for mISDN
#
comment "mISDN hardware drivers"
config MISDN_HFCPCI
tristate "Support for HFC PCI cards"
depends on MISDN
depends on PCI
help
Enable support for cards with Cologne Chip AG's
HFC PCI chip.
config MISDN_HFCMULTI
tristate "Support for HFC multiport cards (HFC-4S/8S/E1)"
depends on PCI || 8xx
depends on MISDN
help
Enable support for cards with Cologne Chip AG's HFC multiport
chip. There are three types of chips that are quite similar,
but the interface is different:
* HFC-4S (4 S/T interfaces on one chip)
* HFC-8S (8 S/T interfaces on one chip)
* HFC-E1 (E1 interface for 2Mbit ISDN)
config MISDN_HFCMULTI_8xx
boolean "Support for XHFC embedded board in HFC multiport driver"
depends on MISDN
depends on MISDN_HFCMULTI
depends on 8xx
default 8xx
help
Enable support for the XHFC embedded solution from Speech Design.
config MISDN_HFCUSB
tristate "Support for HFC-S USB based TAs"
depends on USB
help
Enable support for USB ISDN TAs with Cologne Chip AG's
HFC-S USB ISDN Controller
config MISDN_AVMFRITZ
tristate "Support for AVM FRITZ!CARD PCI"
depends on MISDN
depends on PCI
select MISDN_IPAC
help
Enable support for AVMs FRITZ!CARD PCI cards
config MISDN_SPEEDFAX
tristate "Support for Sedlbauer Speedfax+"
depends on MISDN
depends on PCI
select MISDN_IPAC
select MISDN_ISAR
help
Enable support for Sedlbauer Speedfax+.
config MISDN_INFINEON
tristate "Support for cards with Infineon chipset"
depends on MISDN
depends on PCI
select MISDN_IPAC
help
Enable support for cards with ISAC + HSCX, IPAC or IPAC-SX
chip from Infineon (former manufacturer Siemens).
config MISDN_W6692
tristate "Support for cards with Winbond 6692"
depends on MISDN
depends on PCI
help
Enable support for Winbond 6692 PCI chip based cards.
config MISDN_NETJET
tristate "Support for NETJet cards"
depends on MISDN
depends on PCI
depends on TTY
select MISDN_IPAC
select ISDN_HDLC
select ISDN_I4L
help
Enable support for Traverse Technologies NETJet PCI cards.
config MISDN_IPAC
tristate
depends on MISDN
config MISDN_ISAR
tristate
depends on MISDN

View file

@ -0,0 +1,16 @@
#
# Makefile for the modular ISDN hardware drivers
#
#
obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o
obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o
obj-$(CONFIG_MISDN_HFCUSB) += hfcsusb.o
obj-$(CONFIG_MISDN_AVMFRITZ) += avmfritz.o
obj-$(CONFIG_MISDN_SPEEDFAX) += speedfax.o
obj-$(CONFIG_MISDN_INFINEON) += mISDNinfineon.o
obj-$(CONFIG_MISDN_W6692) += w6692.o
obj-$(CONFIG_MISDN_NETJET) += netjet.o
# chip modules
obj-$(CONFIG_MISDN_IPAC) += mISDNipac.o
obj-$(CONFIG_MISDN_ISAR) += mISDNisar.o

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,167 @@
/*
* For License see notice in hfc_multi.c
*
* special IO and init functions for the embedded XHFC board
* from Speech Design
*
*/
#include <asm/8xx_immap.h>
/* Change this to the value used by your board */
#ifndef IMAP_ADDR
#define IMAP_ADDR 0xFFF00000
#endif
static void
#ifdef HFC_REGISTER_DEBUG
HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val,
const char *function, int line)
#else
HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val)
#endif
{
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
writeb(reg, hc->xhfc_memaddr);
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
writeb(val, hc->xhfc_memdata);
}
static u_char
#ifdef HFC_REGISTER_DEBUG
HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
#else
HFC_inb_embsd(struct hfc_multi *hc, u_char reg)
#endif
{
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
writeb(reg, hc->xhfc_memaddr);
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
return readb(hc->xhfc_memdata);
}
static u_short
#ifdef HFC_REGISTER_DEBUG
HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
#else
HFC_inw_embsd(struct hfc_multi *hc, u_char reg)
#endif
{
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
writeb(reg, hc->xhfc_memaddr);
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
return readb(hc->xhfc_memdata);
}
static void
#ifdef HFC_REGISTER_DEBUG
HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line)
#else
HFC_wait_embsd(struct hfc_multi *hc)
#endif
{
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
writeb(R_STATUS, hc->xhfc_memaddr);
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
while (readb(hc->xhfc_memdata) & V_BUSY)
cpu_relax();
}
/* write fifo data (EMBSD) */
void
write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
{
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
*hc->xhfc_memaddr = A_FIFO_DATA0;
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
while (len) {
*hc->xhfc_memdata = *data;
data++;
len--;
}
}
/* read fifo data (EMBSD) */
void
read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
{
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
*hc->xhfc_memaddr = A_FIFO_DATA0;
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
while (len) {
*data = (u_char)(*hc->xhfc_memdata);
data++;
len--;
}
}
static int
setup_embedded(struct hfc_multi *hc, struct hm_map *m)
{
printk(KERN_INFO
"HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
hc->pci_dev = NULL;
if (m->clock2)
test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
hc->leds = m->leds;
hc->ledstate = 0xAFFEAFFE;
hc->opticalsupport = m->opticalsupport;
hc->pci_iobase = 0;
hc->pci_membase = 0;
hc->xhfc_membase = NULL;
hc->xhfc_memaddr = NULL;
hc->xhfc_memdata = NULL;
/* set memory access methods */
if (m->io_mode) /* use mode from card config */
hc->io_mode = m->io_mode;
switch (hc->io_mode) {
case HFC_IO_MODE_EMBSD:
test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip);
hc->slots = 128; /* required */
/* fall through */
hc->HFC_outb = HFC_outb_embsd;
hc->HFC_inb = HFC_inb_embsd;
hc->HFC_inw = HFC_inw_embsd;
hc->HFC_wait = HFC_wait_embsd;
hc->read_fifo = read_fifo_embsd;
hc->write_fifo = write_fifo_embsd;
hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id;
hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase,
XHFC_MEMSIZE);
if (!hc->xhfc_membase) {
printk(KERN_WARNING
"HFC-multi: failed to remap xhfc address space. "
"(internal error)\n");
return -EIO;
}
hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4);
hc->xhfc_memdata = (u_long *)(hc->xhfc_membase);
printk(KERN_INFO
"HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
"xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
(u_long)hc->xhfc_membase, hc->xhfc_origmembase,
(u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata);
break;
default:
printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
return -EIO;
}
/* Prepare the MPC8XX PortA 10 as output (address/data selector) */
hc->immap = (struct immap *)(IMAP_ADDR);
hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0);
hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0);
hc->immap->im_ioport.iop_padir |= PA_XHFC_A0;
/* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */
hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id);
hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk);
hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk);
hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk);
/* At this point the needed config is done */
/* fifos are still not enabled */
return 0;
}

View file

@ -0,0 +1,228 @@
/*
* specific defines for CCD's HFC 2BDS0 PCI chips
*
* Author Werner Cornelius (werner@isdn4linux.de)
*
* Copyright 1999 by Werner Cornelius (werner@isdn4linux.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* thresholds for transparent B-channel mode
* change mask and threshold simultaneously
*/
#define HFCPCI_BTRANS_THRESHOLD 128
#define HFCPCI_FILLEMPTY 64
#define HFCPCI_BTRANS_THRESMASK 0x00
/* defines for PCI config */
#define PCI_ENA_MEMIO 0x02
#define PCI_ENA_MASTER 0x04
/* GCI/IOM bus monitor registers */
#define HCFPCI_C_I 0x08
#define HFCPCI_TRxR 0x0C
#define HFCPCI_MON1_D 0x28
#define HFCPCI_MON2_D 0x2C
/* GCI/IOM bus timeslot registers */
#define HFCPCI_B1_SSL 0x80
#define HFCPCI_B2_SSL 0x84
#define HFCPCI_AUX1_SSL 0x88
#define HFCPCI_AUX2_SSL 0x8C
#define HFCPCI_B1_RSL 0x90
#define HFCPCI_B2_RSL 0x94
#define HFCPCI_AUX1_RSL 0x98
#define HFCPCI_AUX2_RSL 0x9C
/* GCI/IOM bus data registers */
#define HFCPCI_B1_D 0xA0
#define HFCPCI_B2_D 0xA4
#define HFCPCI_AUX1_D 0xA8
#define HFCPCI_AUX2_D 0xAC
/* GCI/IOM bus configuration registers */
#define HFCPCI_MST_EMOD 0xB4
#define HFCPCI_MST_MODE 0xB8
#define HFCPCI_CONNECT 0xBC
/* Interrupt and status registers */
#define HFCPCI_FIFO_EN 0x44
#define HFCPCI_TRM 0x48
#define HFCPCI_B_MODE 0x4C
#define HFCPCI_CHIP_ID 0x58
#define HFCPCI_CIRM 0x60
#define HFCPCI_CTMT 0x64
#define HFCPCI_INT_M1 0x68
#define HFCPCI_INT_M2 0x6C
#define HFCPCI_INT_S1 0x78
#define HFCPCI_INT_S2 0x7C
#define HFCPCI_STATUS 0x70
/* S/T section registers */
#define HFCPCI_STATES 0xC0
#define HFCPCI_SCTRL 0xC4
#define HFCPCI_SCTRL_E 0xC8
#define HFCPCI_SCTRL_R 0xCC
#define HFCPCI_SQ 0xD0
#define HFCPCI_CLKDEL 0xDC
#define HFCPCI_B1_REC 0xF0
#define HFCPCI_B1_SEND 0xF0
#define HFCPCI_B2_REC 0xF4
#define HFCPCI_B2_SEND 0xF4
#define HFCPCI_D_REC 0xF8
#define HFCPCI_D_SEND 0xF8
#define HFCPCI_E_REC 0xFC
/* bits in status register (READ) */
#define HFCPCI_PCI_PROC 0x02
#define HFCPCI_NBUSY 0x04
#define HFCPCI_TIMER_ELAP 0x10
#define HFCPCI_STATINT 0x20
#define HFCPCI_FRAMEINT 0x40
#define HFCPCI_ANYINT 0x80
/* bits in CTMT (Write) */
#define HFCPCI_CLTIMER 0x80
#define HFCPCI_TIM3_125 0x04
#define HFCPCI_TIM25 0x10
#define HFCPCI_TIM50 0x14
#define HFCPCI_TIM400 0x18
#define HFCPCI_TIM800 0x1C
#define HFCPCI_AUTO_TIMER 0x20
#define HFCPCI_TRANSB2 0x02
#define HFCPCI_TRANSB1 0x01
/* bits in CIRM (Write) */
#define HFCPCI_AUX_MSK 0x07
#define HFCPCI_RESET 0x08
#define HFCPCI_B1_REV 0x40
#define HFCPCI_B2_REV 0x80
/* bits in INT_M1 and INT_S1 */
#define HFCPCI_INTS_B1TRANS 0x01
#define HFCPCI_INTS_B2TRANS 0x02
#define HFCPCI_INTS_DTRANS 0x04
#define HFCPCI_INTS_B1REC 0x08
#define HFCPCI_INTS_B2REC 0x10
#define HFCPCI_INTS_DREC 0x20
#define HFCPCI_INTS_L1STATE 0x40
#define HFCPCI_INTS_TIMER 0x80
/* bits in INT_M2 */
#define HFCPCI_PROC_TRANS 0x01
#define HFCPCI_GCI_I_CHG 0x02
#define HFCPCI_GCI_MON_REC 0x04
#define HFCPCI_IRQ_ENABLE 0x08
#define HFCPCI_PMESEL 0x80
/* bits in STATES */
#define HFCPCI_STATE_MSK 0x0F
#define HFCPCI_LOAD_STATE 0x10
#define HFCPCI_ACTIVATE 0x20
#define HFCPCI_DO_ACTION 0x40
#define HFCPCI_NT_G2_G3 0x80
/* bits in HFCD_MST_MODE */
#define HFCPCI_MASTER 0x01
#define HFCPCI_SLAVE 0x00
#define HFCPCI_F0IO_POSITIV 0x02
#define HFCPCI_F0_NEGATIV 0x04
#define HFCPCI_F0_2C4 0x08
/* remaining bits are for codecs control */
/* bits in HFCD_SCTRL */
#define SCTRL_B1_ENA 0x01
#define SCTRL_B2_ENA 0x02
#define SCTRL_MODE_TE 0x00
#define SCTRL_MODE_NT 0x04
#define SCTRL_LOW_PRIO 0x08
#define SCTRL_SQ_ENA 0x10
#define SCTRL_TEST 0x20
#define SCTRL_NONE_CAP 0x40
#define SCTRL_PWR_DOWN 0x80
/* bits in SCTRL_E */
#define HFCPCI_AUTO_AWAKE 0x01
#define HFCPCI_DBIT_1 0x04
#define HFCPCI_IGNORE_COL 0x08
#define HFCPCI_CHG_B1_B2 0x80
/* bits in FIFO_EN register */
#define HFCPCI_FIFOEN_B1 0x03
#define HFCPCI_FIFOEN_B2 0x0C
#define HFCPCI_FIFOEN_DTX 0x10
#define HFCPCI_FIFOEN_B1TX 0x01
#define HFCPCI_FIFOEN_B1RX 0x02
#define HFCPCI_FIFOEN_B2TX 0x04
#define HFCPCI_FIFOEN_B2RX 0x08
/* definitions of fifo memory area */
#define MAX_D_FRAMES 15
#define MAX_B_FRAMES 31
#define B_SUB_VAL 0x200
#define B_FIFO_SIZE (0x2000 - B_SUB_VAL)
#define D_FIFO_SIZE 512
#define D_FREG_MASK 0xF
struct zt {
__le16 z1; /* Z1 pointer 16 Bit */
__le16 z2; /* Z2 pointer 16 Bit */
};
struct dfifo {
u_char data[D_FIFO_SIZE]; /* FIFO data space */
u_char fill1[0x20A0 - D_FIFO_SIZE]; /* reserved, do not use */
u_char f1, f2; /* f pointers */
u_char fill2[0x20C0 - 0x20A2]; /* reserved, do not use */
/* mask index with D_FREG_MASK for access */
struct zt za[MAX_D_FRAMES + 1];
u_char fill3[0x4000 - 0x2100]; /* align 16K */
};
struct bzfifo {
struct zt za[MAX_B_FRAMES + 1]; /* only range 0x0..0x1F allowed */
u_char f1, f2; /* f pointers */
u_char fill[0x2100 - 0x2082]; /* alignment */
};
union fifo_area {
struct {
struct dfifo d_tx; /* D-send channel */
struct dfifo d_rx; /* D-receive channel */
} d_chan;
struct {
u_char fill1[0x200];
u_char txdat_b1[B_FIFO_SIZE];
struct bzfifo txbz_b1;
struct bzfifo txbz_b2;
u_char txdat_b2[B_FIFO_SIZE];
u_char fill2[D_FIFO_SIZE];
u_char rxdat_b1[B_FIFO_SIZE];
struct bzfifo rxbz_b1;
struct bzfifo rxbz_b2;
u_char rxdat_b2[B_FIFO_SIZE];
} b_chans;
u_char fill[32768];
};
#define Write_hfc(a, b, c) (writeb(c, (a->hw.pci_io) + b))
#define Read_hfc(a, b) (readb((a->hw.pci_io) + b))

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,424 @@
/*
* hfcsusb.h, HFC-S USB mISDN driver
*/
#ifndef __HFCSUSB_H__
#define __HFCSUSB_H__
#define DRIVER_NAME "HFC-S_USB"
#define DBG_HFC_CALL_TRACE 0x00010000
#define DBG_HFC_FIFO_VERBOSE 0x00020000
#define DBG_HFC_USB_VERBOSE 0x00100000
#define DBG_HFC_URB_INFO 0x00200000
#define DBG_HFC_URB_ERROR 0x00400000
#define DEFAULT_TRANSP_BURST_SZ 128
#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */
#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */
/* hfcsusb Layer1 commands */
#define HFC_L1_ACTIVATE_TE 1
#define HFC_L1_ACTIVATE_NT 2
#define HFC_L1_DEACTIVATE_NT 3
#define HFC_L1_FORCE_DEACTIVATE_TE 4
/* cmd FLAGS in HFCUSB_STATES register */
#define HFCUSB_LOAD_STATE 0x10
#define HFCUSB_ACTIVATE 0x20
#define HFCUSB_DO_ACTION 0x40
#define HFCUSB_NT_G2_G3 0x80
/* timers */
#define NT_ACTIVATION_TIMER 0x01 /* enables NT mode activation Timer */
#define NT_T1_COUNT 10
#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */
#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */
#define HFCUSB_TX_THRESHOLD 96 /* threshold for fifo report bit tx */
#define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */
#define HFCUSB_CIRM 0x00 /* cirm register index */
#define HFCUSB_USB_SIZE 0x07 /* int length register */
#define HFCUSB_USB_SIZE_I 0x06 /* iso length register */
#define HFCUSB_F_CROSS 0x0b /* bit order register */
#define HFCUSB_CLKDEL 0x37 /* bit delay register */
#define HFCUSB_CON_HDLC 0xfa /* channel connect register */
#define HFCUSB_HDLC_PAR 0xfb
#define HFCUSB_SCTRL 0x31 /* S-bus control register (tx) */
#define HFCUSB_SCTRL_E 0x32 /* same for E and special funcs */
#define HFCUSB_SCTRL_R 0x33 /* S-bus control register (rx) */
#define HFCUSB_F_THRES 0x0c /* threshold register */
#define HFCUSB_FIFO 0x0f /* fifo select register */
#define HFCUSB_F_USAGE 0x1a /* fifo usage register */
#define HFCUSB_MST_MODE0 0x14
#define HFCUSB_MST_MODE1 0x15
#define HFCUSB_P_DATA 0x1f
#define HFCUSB_INC_RES_F 0x0e
#define HFCUSB_B1_SSL 0x20
#define HFCUSB_B2_SSL 0x21
#define HFCUSB_B1_RSL 0x24
#define HFCUSB_B2_RSL 0x25
#define HFCUSB_STATES 0x30
#define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */
/* fifo registers */
#define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */
#define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */
#define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */
#define HFCUSB_B2_TX 2
#define HFCUSB_B2_RX 3
#define HFCUSB_D_TX 4
#define HFCUSB_D_RX 5
#define HFCUSB_PCM_TX 6
#define HFCUSB_PCM_RX 7
#define USB_INT 0
#define USB_BULK 1
#define USB_ISOC 2
#define ISOC_PACKETS_D 8
#define ISOC_PACKETS_B 8
#define ISO_BUFFER_SIZE 128
/* defines how much ISO packets are handled in one URB */
static int iso_packets[8] =
{ ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B,
ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
};
/* Fifo flow Control for TX ISO */
#define SINK_MAX 68
#define SINK_MIN 48
#define SINK_DMIN 12
#define SINK_DMAX 18
#define BITLINE_INF (-96 * 8)
/* HFC-S USB register access by Control-URSs */
#define write_reg_atomic(a, b, c) \
usb_control_msg((a)->dev, (a)->ctrl_out_pipe, 0, 0x40, (c), (b), \
0, 0, HFC_CTRL_TIMEOUT)
#define read_reg_atomic(a, b, c) \
usb_control_msg((a)->dev, (a)->ctrl_in_pipe, 1, 0xC0, 0, (b), (c), \
1, HFC_CTRL_TIMEOUT)
#define HFC_CTRL_BUFSIZE 64
struct ctrl_buf {
__u8 hfcs_reg; /* register number */
__u8 reg_val; /* value to be written (or read) */
};
/*
* URB error codes
* Used to represent a list of values and their respective symbolic names
*/
struct hfcusb_symbolic_list {
const int num;
const char *name;
};
static struct hfcusb_symbolic_list urb_errlist[] = {
{-ENOMEM, "No memory for allocation of internal structures"},
{-ENOSPC, "The host controller's bandwidth is already consumed"},
{-ENOENT, "URB was canceled by unlink_urb"},
{-EXDEV, "ISO transfer only partially completed"},
{-EAGAIN, "Too match scheduled for the future"},
{-ENXIO, "URB already queued"},
{-EFBIG, "Too much ISO frames requested"},
{-ENOSR, "Buffer error (overrun)"},
{-EPIPE, "Specified endpoint is stalled (device not responding)"},
{-EOVERFLOW, "Babble (bad cable?)"},
{-EPROTO, "Bit-stuff error (bad cable?)"},
{-EILSEQ, "CRC/Timeout"},
{-ETIMEDOUT, "NAK (device does not respond)"},
{-ESHUTDOWN, "Device unplugged"},
{-1, NULL}
};
static inline const char *
symbolic(struct hfcusb_symbolic_list list[], const int num)
{
int i;
for (i = 0; list[i].name != NULL; i++)
if (list[i].num == num)
return list[i].name;
return "<unknown USB Error>";
}
/* USB descriptor need to contain one of the following EndPoint combination: */
#define CNF_4INT3ISO 1 /* 4 INT IN, 3 ISO OUT */
#define CNF_3INT3ISO 2 /* 3 INT IN, 3 ISO OUT */
#define CNF_4ISO3ISO 3 /* 4 ISO IN, 3 ISO OUT */
#define CNF_3ISO3ISO 4 /* 3 ISO IN, 3 ISO OUT */
#define EP_NUL 1 /* Endpoint at this position not allowed */
#define EP_NOP 2 /* all type of endpoints allowed at this position */
#define EP_ISO 3 /* Isochron endpoint mandatory at this position */
#define EP_BLK 4 /* Bulk endpoint mandatory at this position */
#define EP_INT 5 /* Interrupt endpoint mandatory at this position */
#define HFC_CHAN_B1 0
#define HFC_CHAN_B2 1
#define HFC_CHAN_D 2
#define HFC_CHAN_E 3
/*
* List of all supported enpoints configiration sets, used to find the
* best matching endpoint configuration within a devices' USB descriptor.
* We need at least 3 RX endpoints, and 3 TX endpoints, either
* INT-in and ISO-out, or ISO-in and ISO-out)
* with 4 RX endpoints even E-Channel logging is possible
*/
static int
validconf[][19] = {
/* INT in, ISO out config */
{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL,
CNF_4INT3ISO, 2, 1},
{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_NUL,
EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL,
CNF_3INT3ISO, 2, 0},
/* ISO in, ISO out config */
{EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP,
EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NOP, EP_ISO,
CNF_4ISO3ISO, 2, 1},
{EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL,
EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NUL, EP_NUL,
CNF_3ISO3ISO, 2, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* EOL element */
};
/* string description of chosen config */
static char *conf_str[] = {
"4 Interrupt IN + 3 Isochron OUT",
"3 Interrupt IN + 3 Isochron OUT",
"4 Isochron IN + 3 Isochron OUT",
"3 Isochron IN + 3 Isochron OUT"
};
#define LED_OFF 0 /* no LED support */
#define LED_SCHEME1 1 /* LED standard scheme */
#define LED_SCHEME2 2 /* not used yet... */
#define LED_POWER_ON 1
#define LED_POWER_OFF 2
#define LED_S0_ON 3
#define LED_S0_OFF 4
#define LED_B1_ON 5
#define LED_B1_OFF 6
#define LED_B1_DATA 7
#define LED_B2_ON 8
#define LED_B2_OFF 9
#define LED_B2_DATA 10
#define LED_NORMAL 0 /* LEDs are normal */
#define LED_INVERTED 1 /* LEDs are inverted */
/* time in ms to perform a Flashing LED when B-Channel has traffic */
#define LED_TIME 250
struct hfcsusb;
struct usb_fifo;
/* structure defining input+output fifos (interrupt/bulk mode) */
struct iso_urb {
struct urb *urb;
__u8 buffer[ISO_BUFFER_SIZE]; /* buffer rx/tx USB URB data */
struct usb_fifo *owner_fifo; /* pointer to owner fifo */
__u8 indx; /* Fifos's ISO double buffer 0 or 1 ? */
#ifdef ISO_FRAME_START_DEBUG
int start_frames[ISO_FRAME_START_RING_COUNT];
__u8 iso_frm_strt_pos; /* index in start_frame[] */
#endif
};
struct usb_fifo {
int fifonum; /* fifo index attached to this structure */
int active; /* fifo is currently active */
struct hfcsusb *hw; /* pointer to main structure */
int pipe; /* address of endpoint */
__u8 usb_packet_maxlen; /* maximum length for usb transfer */
unsigned int max_size; /* maximum size of receive/send packet */
__u8 intervall; /* interrupt interval */
struct urb *urb; /* transfer structure for usb routines */
__u8 buffer[128]; /* buffer USB INT OUT URB data */
int bit_line; /* how much bits are in the fifo? */
__u8 usb_transfer_mode; /* switched between ISO and INT */
struct iso_urb iso[2]; /* two urbs to have one always
one pending */
struct dchannel *dch; /* link to hfcsusb_t->dch */
struct bchannel *bch; /* link to hfcsusb_t->bch */
struct dchannel *ech; /* link to hfcsusb_t->ech, TODO: E-CHANNEL */
int last_urblen; /* remember length of last packet */
__u8 stop_gracefull; /* stops URB retransmission */
};
struct hfcsusb {
struct list_head list;
struct dchannel dch;
struct bchannel bch[2];
struct dchannel ech; /* TODO : wait for struct echannel ;) */
struct usb_device *dev; /* our device */
struct usb_interface *intf; /* used interface */
int if_used; /* used interface number */
int alt_used; /* used alternate config */
int cfg_used; /* configuration index used */
int vend_idx; /* index in hfcsusb_idtab */
int packet_size;
int iso_packet_size;
struct usb_fifo fifos[HFCUSB_NUM_FIFOS];
/* control pipe background handling */
struct ctrl_buf ctrl_buff[HFC_CTRL_BUFSIZE];
int ctrl_in_idx, ctrl_out_idx, ctrl_cnt;
struct urb *ctrl_urb;
struct usb_ctrlrequest ctrl_write;
struct usb_ctrlrequest ctrl_read;
int ctrl_paksize;
int ctrl_in_pipe, ctrl_out_pipe;
spinlock_t ctrl_lock; /* lock for ctrl */
spinlock_t lock;
__u8 threshold_mask;
__u8 led_state;
__u8 protocol;
int nt_timer;
int open;
__u8 timers;
__u8 initdone;
char name[MISDN_MAX_IDLEN];
};
/* private vendor specific data */
struct hfcsusb_vdata {
__u8 led_scheme; /* led display scheme */
signed short led_bits[8]; /* array of 8 possible LED bitmask */
char *vend_name; /* device name */
};
#define HFC_MAX_TE_LAYER1_STATE 8
#define HFC_MAX_NT_LAYER1_STATE 4
static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
"TE F0 - Reset",
"TE F1 - Reset",
"TE F2 - Sensing",
"TE F3 - Deactivated",
"TE F4 - Awaiting signal",
"TE F5 - Identifying input",
"TE F6 - Synchronized",
"TE F7 - Activated",
"TE F8 - Lost framing",
};
static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
"NT G0 - Reset",
"NT G1 - Deactive",
"NT G2 - Pending activation",
"NT G3 - Active",
"NT G4 - Pending deactivation",
};
/* supported devices */
static struct usb_device_id hfcsusb_idtab[] = {
{
USB_DEVICE(0x0959, 0x2bd0),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_OFF, {4, 0, 2, 1},
"ISDN USB TA (Cologne Chip HFC-S USB based)"}),
},
{
USB_DEVICE(0x0675, 0x1688),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {1, 2, 0, 0},
"DrayTek miniVigor 128 USB ISDN TA"}),
},
{
USB_DEVICE(0x07b0, 0x0007),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Billion tiny USB ISDN TA 128"}),
},
{
USB_DEVICE(0x0742, 0x2008),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"Stollmann USB TA"}),
},
{
USB_DEVICE(0x0742, 0x2009),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"Aceex USB ISDN TA"}),
},
{
USB_DEVICE(0x0742, 0x200A),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"OEM USB ISDN TA"}),
},
{
USB_DEVICE(0x08e3, 0x0301),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {2, 0, 1, 4},
"Olitec USB RNIS"}),
},
{
USB_DEVICE(0x07fa, 0x0846),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Bewan Modem RNIS USB"}),
},
{
USB_DEVICE(0x07fa, 0x0847),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Djinn Numeris USB"}),
},
{
USB_DEVICE(0x07b0, 0x0006),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Twister ISDN TA"}),
},
{
USB_DEVICE(0x071d, 0x1005),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {0x02, 0, 0x01, 0x04},
"Eicon DIVA USB 4.0"}),
},
{
USB_DEVICE(0x0586, 0x0102),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {0x88, -64, -32, -16},
"ZyXEL OMNI.NET USB II"}),
},
{
USB_DEVICE(0x1ae7, 0x0525),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)
{LED_SCHEME1, {0x88, -64, -32, -16},
"X-Tensions USB ISDN TA XC-525"}),
},
{ }
};
MODULE_DEVICE_TABLE(usb, hfcsusb_idtab);
#endif /* __HFCSUSB_H__ */

View file

@ -0,0 +1,109 @@
/*
* iohelper.h
* helper for define functions to access ISDN hardware
* supported are memory mapped IO
* indirect port IO (one port for address, one for data)
*
* Author Karsten Keil <keil@isdn4linux.de>
*
* Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _IOHELPER_H
#define _IOHELPER_H
typedef u8 (read_reg_func)(void *hwp, u8 offset);
typedef void (write_reg_func)(void *hwp, u8 offset, u8 value);
typedef void (fifo_func)(void *hwp, u8 offset, u8 *datap, int size);
struct _ioport {
u32 port;
u32 ale;
};
#define IOFUNC_IO(name, hws, ap) \
static u8 Read##name##_IO(void *p, u8 off) { \
struct hws *hw = p; \
return inb(hw->ap.port + off); \
} \
static void Write##name##_IO(void *p, u8 off, u8 val) { \
struct hws *hw = p; \
outb(val, hw->ap.port + off); \
} \
static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
struct hws *hw = p; \
insb(hw->ap.port + off, dp, size); \
} \
static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
struct hws *hw = p; \
outsb(hw->ap.port + off, dp, size); \
}
#define IOFUNC_IND(name, hws, ap) \
static u8 Read##name##_IND(void *p, u8 off) { \
struct hws *hw = p; \
outb(off, hw->ap.ale); \
return inb(hw->ap.port); \
} \
static void Write##name##_IND(void *p, u8 off, u8 val) { \
struct hws *hw = p; \
outb(off, hw->ap.ale); \
outb(val, hw->ap.port); \
} \
static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
struct hws *hw = p; \
outb(off, hw->ap.ale); \
insb(hw->ap.port, dp, size); \
} \
static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
struct hws *hw = p; \
outb(off, hw->ap.ale); \
outsb(hw->ap.port, dp, size); \
}
#define IOFUNC_MEMIO(name, hws, typ, adr) \
static u8 Read##name##_MIO(void *p, u8 off) { \
struct hws *hw = p; \
return readb(((typ *)hw->adr) + off); \
} \
static void Write##name##_MIO(void *p, u8 off, u8 val) { \
struct hws *hw = p; \
writeb(val, ((typ *)hw->adr) + off); \
} \
static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
struct hws *hw = p; \
while (size--) \
*dp++ = readb(((typ *)hw->adr) + off); \
} \
static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
struct hws *hw = p; \
while (size--) \
writeb(*dp++, ((typ *)hw->adr) + off); \
}
#define ASSIGN_FUNC(typ, name, dest) do { \
dest.read_reg = &Read##name##_##typ; \
dest.write_reg = &Write##name##_##typ; \
dest.read_fifo = &ReadFiFo##name##_##typ; \
dest.write_fifo = &WriteFiFo##name##_##typ; \
} while (0)
#define ASSIGN_FUNC_IPAC(typ, target) do { \
ASSIGN_FUNC(typ, ISAC, target.isac); \
ASSIGN_FUNC(typ, IPAC, target); \
} while (0)
#endif

View file

@ -0,0 +1,405 @@
/*
*
* ipac.h Defines for the Infineon (former Siemens) ISDN
* chip series
*
* Author Karsten Keil <keil@isdn4linux.de>
*
* Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "iohelper.h"
struct isac_hw {
struct dchannel dch;
u32 type;
u32 off; /* offset to isac regs */
char *name;
spinlock_t *hwlock; /* lock HW access */
read_reg_func *read_reg;
write_reg_func *write_reg;
fifo_func *read_fifo;
fifo_func *write_fifo;
int (*monitor)(void *, u32, u8 *, int);
void (*release)(struct isac_hw *);
int (*init)(struct isac_hw *);
int (*ctrl)(struct isac_hw *, u32, u_long);
int (*open)(struct isac_hw *, struct channel_req *);
u8 *mon_tx;
u8 *mon_rx;
int mon_txp;
int mon_txc;
int mon_rxp;
struct arcofi_msg *arcofi_list;
struct timer_list arcofitimer;
wait_queue_head_t arcofi_wait;
u8 arcofi_bc;
u8 arcofi_state;
u8 mocr;
u8 adf2;
u8 state;
};
struct ipac_hw;
struct hscx_hw {
struct bchannel bch;
struct ipac_hw *ip;
u8 fifo_size;
u8 off; /* offset to ICA or ICB */
u8 slot;
char log[64];
};
struct ipac_hw {
struct isac_hw isac;
struct hscx_hw hscx[2];
char *name;
void *hw;
spinlock_t *hwlock; /* lock HW access */
struct module *owner;
u32 type;
read_reg_func *read_reg;
write_reg_func *write_reg;
fifo_func *read_fifo;
fifo_func *write_fifo;
void (*release)(struct ipac_hw *);
int (*init)(struct ipac_hw *);
int (*ctrl)(struct ipac_hw *, u32, u_long);
u8 conf;
};
#define IPAC_TYPE_ISAC 0x0010
#define IPAC_TYPE_IPAC 0x0020
#define IPAC_TYPE_ISACX 0x0040
#define IPAC_TYPE_IPACX 0x0080
#define IPAC_TYPE_HSCX 0x0100
#define ISAC_USE_ARCOFI 0x1000
/* Monitor functions */
#define MONITOR_RX_0 0x1000
#define MONITOR_RX_1 0x1001
#define MONITOR_TX_0 0x2000
#define MONITOR_TX_1 0x2001
/* All registers original Siemens Spec */
/* IPAC/ISAC registers */
#define ISAC_MASK 0x20
#define ISAC_ISTA 0x20
#define ISAC_STAR 0x21
#define ISAC_CMDR 0x21
#define ISAC_EXIR 0x24
#define ISAC_ADF2 0x39
#define ISAC_SPCR 0x30
#define ISAC_ADF1 0x38
#define ISAC_CIR0 0x31
#define ISAC_CIX0 0x31
#define ISAC_CIR1 0x33
#define ISAC_CIX1 0x33
#define ISAC_STCR 0x37
#define ISAC_MODE 0x22
#define ISAC_RSTA 0x27
#define ISAC_RBCL 0x25
#define ISAC_RBCH 0x2A
#define ISAC_TIMR 0x23
#define ISAC_SQXR 0x3b
#define ISAC_SQRR 0x3b
#define ISAC_MOSR 0x3a
#define ISAC_MOCR 0x3a
#define ISAC_MOR0 0x32
#define ISAC_MOX0 0x32
#define ISAC_MOR1 0x34
#define ISAC_MOX1 0x34
#define ISAC_RBCH_XAC 0x80
#define IPAC_D_TIN2 0x01
/* IPAC/HSCX */
#define IPAC_ISTAB 0x20 /* RD */
#define IPAC_MASKB 0x20 /* WR */
#define IPAC_STARB 0x21 /* RD */
#define IPAC_CMDRB 0x21 /* WR */
#define IPAC_MODEB 0x22 /* R/W */
#define IPAC_EXIRB 0x24 /* RD */
#define IPAC_RBCLB 0x25 /* RD */
#define IPAC_RAH1 0x26 /* WR */
#define IPAC_RAH2 0x27 /* WR */
#define IPAC_RSTAB 0x27 /* RD */
#define IPAC_RAL1 0x28 /* R/W */
#define IPAC_RAL2 0x29 /* WR */
#define IPAC_RHCRB 0x29 /* RD */
#define IPAC_XBCL 0x2A /* WR */
#define IPAC_CCR2 0x2C /* R/W */
#define IPAC_RBCHB 0x2D /* RD */
#define IPAC_XBCH 0x2D /* WR */
#define HSCX_VSTR 0x2E /* RD */
#define IPAC_RLCR 0x2E /* WR */
#define IPAC_CCR1 0x2F /* R/W */
#define IPAC_TSAX 0x30 /* WR */
#define IPAC_TSAR 0x31 /* WR */
#define IPAC_XCCR 0x32 /* WR */
#define IPAC_RCCR 0x33 /* WR */
/* IPAC_ISTAB/IPAC_MASKB bits */
#define IPAC_B_XPR 0x10
#define IPAC_B_RPF 0x40
#define IPAC_B_RME 0x80
#define IPAC_B_ON 0x2F
/* IPAC_EXIRB bits */
#define IPAC_B_RFS 0x04
#define IPAC_B_RFO 0x10
#define IPAC_B_XDU 0x40
#define IPAC_B_XMR 0x80
/* IPAC special registers */
#define IPAC_CONF 0xC0 /* R/W */
#define IPAC_ISTA 0xC1 /* RD */
#define IPAC_MASK 0xC1 /* WR */
#define IPAC_ID 0xC2 /* RD */
#define IPAC_ACFG 0xC3 /* R/W */
#define IPAC_AOE 0xC4 /* R/W */
#define IPAC_ARX 0xC5 /* RD */
#define IPAC_ATX 0xC5 /* WR */
#define IPAC_PITA1 0xC6 /* R/W */
#define IPAC_PITA2 0xC7 /* R/W */
#define IPAC_POTA1 0xC8 /* R/W */
#define IPAC_POTA2 0xC9 /* R/W */
#define IPAC_PCFG 0xCA /* R/W */
#define IPAC_SCFG 0xCB /* R/W */
#define IPAC_TIMR2 0xCC /* R/W */
/* IPAC_ISTA/_MASK bits */
#define IPAC__EXB 0x01
#define IPAC__ICB 0x02
#define IPAC__EXA 0x04
#define IPAC__ICA 0x08
#define IPAC__EXD 0x10
#define IPAC__ICD 0x20
#define IPAC__INT0 0x40
#define IPAC__INT1 0x80
#define IPAC__ON 0xC0
/* HSCX ISTA/MASK bits */
#define HSCX__EXB 0x01
#define HSCX__EXA 0x02
#define HSCX__ICA 0x04
/* ISAC/ISACX/IPAC/IPACX L1 commands */
#define ISAC_CMD_TIM 0x0
#define ISAC_CMD_RS 0x1
#define ISAC_CMD_SCZ 0x4
#define ISAC_CMD_SSZ 0x2
#define ISAC_CMD_AR8 0x8
#define ISAC_CMD_AR10 0x9
#define ISAC_CMD_ARL 0xA
#define ISAC_CMD_DUI 0xF
/* ISAC/ISACX/IPAC/IPACX L1 indications */
#define ISAC_IND_RS 0x1
#define ISAC_IND_PU 0x7
#define ISAC_IND_DR 0x0
#define ISAC_IND_SD 0x2
#define ISAC_IND_DIS 0x3
#define ISAC_IND_EI 0x6
#define ISAC_IND_RSY 0x4
#define ISAC_IND_ARD 0x8
#define ISAC_IND_TI 0xA
#define ISAC_IND_ATI 0xB
#define ISAC_IND_AI8 0xC
#define ISAC_IND_AI10 0xD
#define ISAC_IND_DID 0xF
/* the new ISACX / IPACX */
/* D-channel registers */
#define ISACX_RFIFOD 0x00 /* RD */
#define ISACX_XFIFOD 0x00 /* WR */
#define ISACX_ISTAD 0x20 /* RD */
#define ISACX_MASKD 0x20 /* WR */
#define ISACX_STARD 0x21 /* RD */
#define ISACX_CMDRD 0x21 /* WR */
#define ISACX_MODED 0x22 /* R/W */
#define ISACX_EXMD1 0x23 /* R/W */
#define ISACX_TIMR1 0x24 /* R/W */
#define ISACX_SAP1 0x25 /* WR */
#define ISACX_SAP2 0x26 /* WR */
#define ISACX_RBCLD 0x26 /* RD */
#define ISACX_RBCHD 0x27 /* RD */
#define ISACX_TEI1 0x27 /* WR */
#define ISACX_TEI2 0x28 /* WR */
#define ISACX_RSTAD 0x28 /* RD */
#define ISACX_TMD 0x29 /* R/W */
#define ISACX_CIR0 0x2E /* RD */
#define ISACX_CIX0 0x2E /* WR */
#define ISACX_CIR1 0x2F /* RD */
#define ISACX_CIX1 0x2F /* WR */
/* Transceiver registers */
#define ISACX_TR_CONF0 0x30 /* R/W */
#define ISACX_TR_CONF1 0x31 /* R/W */
#define ISACX_TR_CONF2 0x32 /* R/W */
#define ISACX_TR_STA 0x33 /* RD */
#define ISACX_TR_CMD 0x34 /* R/W */
#define ISACX_SQRR1 0x35 /* RD */
#define ISACX_SQXR1 0x35 /* WR */
#define ISACX_SQRR2 0x36 /* RD */
#define ISACX_SQXR2 0x36 /* WR */
#define ISACX_SQRR3 0x37 /* RD */
#define ISACX_SQXR3 0x37 /* WR */
#define ISACX_ISTATR 0x38 /* RD */
#define ISACX_MASKTR 0x39 /* R/W */
#define ISACX_TR_MODE 0x3A /* R/W */
#define ISACX_ACFG1 0x3C /* R/W */
#define ISACX_ACFG2 0x3D /* R/W */
#define ISACX_AOE 0x3E /* R/W */
#define ISACX_ARX 0x3F /* RD */
#define ISACX_ATX 0x3F /* WR */
/* IOM: Timeslot, DPS, CDA */
#define ISACX_CDA10 0x40 /* R/W */
#define ISACX_CDA11 0x41 /* R/W */
#define ISACX_CDA20 0x42 /* R/W */
#define ISACX_CDA21 0x43 /* R/W */
#define ISACX_CDA_TSDP10 0x44 /* R/W */
#define ISACX_CDA_TSDP11 0x45 /* R/W */
#define ISACX_CDA_TSDP20 0x46 /* R/W */
#define ISACX_CDA_TSDP21 0x47 /* R/W */
#define ISACX_BCHA_TSDP_BC1 0x48 /* R/W */
#define ISACX_BCHA_TSDP_BC2 0x49 /* R/W */
#define ISACX_BCHB_TSDP_BC1 0x4A /* R/W */
#define ISACX_BCHB_TSDP_BC2 0x4B /* R/W */
#define ISACX_TR_TSDP_BC1 0x4C /* R/W */
#define ISACX_TR_TSDP_BC2 0x4D /* R/W */
#define ISACX_CDA1_CR 0x4E /* R/W */
#define ISACX_CDA2_CR 0x4F /* R/W */
/* IOM: Contol, Sync transfer, Monitor */
#define ISACX_TR_CR 0x50 /* R/W */
#define ISACX_TRC_CR 0x50 /* R/W */
#define ISACX_BCHA_CR 0x51 /* R/W */
#define ISACX_BCHB_CR 0x52 /* R/W */
#define ISACX_DCI_CR 0x53 /* R/W */
#define ISACX_DCIC_CR 0x53 /* R/W */
#define ISACX_MON_CR 0x54 /* R/W */
#define ISACX_SDS1_CR 0x55 /* R/W */
#define ISACX_SDS2_CR 0x56 /* R/W */
#define ISACX_IOM_CR 0x57 /* R/W */
#define ISACX_STI 0x58 /* RD */
#define ISACX_ASTI 0x58 /* WR */
#define ISACX_MSTI 0x59 /* R/W */
#define ISACX_SDS_CONF 0x5A /* R/W */
#define ISACX_MCDA 0x5B /* RD */
#define ISACX_MOR 0x5C /* RD */
#define ISACX_MOX 0x5C /* WR */
#define ISACX_MOSR 0x5D /* RD */
#define ISACX_MOCR 0x5E /* R/W */
#define ISACX_MSTA 0x5F /* RD */
#define ISACX_MCONF 0x5F /* WR */
/* Interrupt and general registers */
#define ISACX_ISTA 0x60 /* RD */
#define ISACX_MASK 0x60 /* WR */
#define ISACX_AUXI 0x61 /* RD */
#define ISACX_AUXM 0x61 /* WR */
#define ISACX_MODE1 0x62 /* R/W */
#define ISACX_MODE2 0x63 /* R/W */
#define ISACX_ID 0x64 /* RD */
#define ISACX_SRES 0x64 /* WR */
#define ISACX_TIMR2 0x65 /* R/W */
/* Register Bits */
/* ISACX/IPACX _ISTAD (R) and _MASKD (W) */
#define ISACX_D_XDU 0x04
#define ISACX_D_XMR 0x08
#define ISACX_D_XPR 0x10
#define ISACX_D_RFO 0x20
#define ISACX_D_RPF 0x40
#define ISACX_D_RME 0x80
/* ISACX/IPACX _ISTA (R) and _MASK (W) */
#define ISACX__ICD 0x01
#define ISACX__MOS 0x02
#define ISACX__TRAN 0x04
#define ISACX__AUX 0x08
#define ISACX__CIC 0x10
#define ISACX__ST 0x20
#define IPACX__ICB 0x40
#define IPACX__ICA 0x80
#define IPACX__ON 0x2C
/* ISACX/IPACX _CMDRD (W) */
#define ISACX_CMDRD_XRES 0x01
#define ISACX_CMDRD_XME 0x02
#define ISACX_CMDRD_XTF 0x08
#define ISACX_CMDRD_STI 0x10
#define ISACX_CMDRD_RRES 0x40
#define ISACX_CMDRD_RMC 0x80
/* ISACX/IPACX _RSTAD (R) */
#define ISACX_RSTAD_TA 0x01
#define ISACX_RSTAD_CR 0x02
#define ISACX_RSTAD_SA0 0x04
#define ISACX_RSTAD_SA1 0x08
#define ISACX_RSTAD_RAB 0x10
#define ISACX_RSTAD_CRC 0x20
#define ISACX_RSTAD_RDO 0x40
#define ISACX_RSTAD_VFR 0x80
/* ISACX/IPACX _CIR0 (R) */
#define ISACX_CIR0_BAS 0x01
#define ISACX_CIR0_SG 0x08
#define ISACX_CIR0_CIC1 0x08
#define ISACX_CIR0_CIC0 0x08
/* B-channel registers */
#define IPACX_OFF_ICA 0x70
#define IPACX_OFF_ICB 0x80
/* ICA: IPACX_OFF_ICA + Reg ICB: IPACX_OFF_ICB + Reg */
#define IPACX_ISTAB 0x00 /* RD */
#define IPACX_MASKB 0x00 /* WR */
#define IPACX_STARB 0x01 /* RD */
#define IPACX_CMDRB 0x01 /* WR */
#define IPACX_MODEB 0x02 /* R/W */
#define IPACX_EXMB 0x03 /* R/W */
#define IPACX_RAH1 0x05 /* WR */
#define IPACX_RAH2 0x06 /* WR */
#define IPACX_RBCLB 0x06 /* RD */
#define IPACX_RBCHB 0x07 /* RD */
#define IPACX_RAL1 0x07 /* WR */
#define IPACX_RAL2 0x08 /* WR */
#define IPACX_RSTAB 0x08 /* RD */
#define IPACX_TMB 0x09 /* R/W */
#define IPACX_RFIFOB 0x0A /* RD */
#define IPACX_XFIFOB 0x0A /* WR */
/* IPACX_ISTAB / IPACX_MASKB bits */
#define IPACX_B_XDU 0x04
#define IPACX_B_XPR 0x10
#define IPACX_B_RFO 0x20
#define IPACX_B_RPF 0x40
#define IPACX_B_RME 0x80
#define IPACX_B_ON 0x0B
extern int mISDNisac_init(struct isac_hw *, void *);
extern irqreturn_t mISDNisac_irq(struct isac_hw *, u8);
extern u32 mISDNipac_init(struct ipac_hw *, void *);
extern irqreturn_t mISDNipac_irq(struct ipac_hw *, int);

View file

@ -0,0 +1,269 @@
/*
*
* isar.h ISAR (Siemens PSB 7110) specific defines
*
* Author Karsten Keil (keil@isdn4linux.de)
*
* Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "iohelper.h"
struct isar_hw;
struct isar_ch {
struct bchannel bch;
struct isar_hw *is;
struct timer_list ftimer;
u8 nr;
u8 dpath;
u8 mml;
u8 state;
u8 cmd;
u8 mod;
u8 newcmd;
u8 newmod;
u8 try_mod;
u8 conmsg[16];
};
struct isar_hw {
struct isar_ch ch[2];
void *hw;
spinlock_t *hwlock; /* lock HW access */
char *name;
struct module *owner;
read_reg_func *read_reg;
write_reg_func *write_reg;
fifo_func *read_fifo;
fifo_func *write_fifo;
int (*ctrl)(void *, u32, u_long);
void (*release)(struct isar_hw *);
int (*init)(struct isar_hw *);
int (*open)(struct isar_hw *, struct channel_req *);
int (*firmware)(struct isar_hw *, const u8 *, int);
unsigned long Flags;
int version;
u8 bstat;
u8 iis;
u8 cmsb;
u8 clsb;
u8 buf[256];
u8 log[256];
};
#define ISAR_IRQMSK 0x04
#define ISAR_IRQSTA 0x04
#define ISAR_IRQBIT 0x75
#define ISAR_CTRL_H 0x61
#define ISAR_CTRL_L 0x60
#define ISAR_IIS 0x58
#define ISAR_IIA 0x58
#define ISAR_HIS 0x50
#define ISAR_HIA 0x50
#define ISAR_MBOX 0x4c
#define ISAR_WADR 0x4a
#define ISAR_RADR 0x48
#define ISAR_HIS_VNR 0x14
#define ISAR_HIS_DKEY 0x02
#define ISAR_HIS_FIRM 0x1e
#define ISAR_HIS_STDSP 0x08
#define ISAR_HIS_DIAG 0x05
#define ISAR_HIS_P0CFG 0x3c
#define ISAR_HIS_P12CFG 0x24
#define ISAR_HIS_SARTCFG 0x25
#define ISAR_HIS_PUMPCFG 0x26
#define ISAR_HIS_PUMPCTRL 0x2a
#define ISAR_HIS_IOM2CFG 0x27
#define ISAR_HIS_IOM2REQ 0x07
#define ISAR_HIS_IOM2CTRL 0x2b
#define ISAR_HIS_BSTREQ 0x0c
#define ISAR_HIS_PSTREQ 0x0e
#define ISAR_HIS_SDATA 0x20
#define ISAR_HIS_DPS1 0x40
#define ISAR_HIS_DPS2 0x80
#define SET_DPS(x) ((x << 6) & 0xc0)
#define ISAR_IIS_MSCMSD 0x3f
#define ISAR_IIS_VNR 0x15
#define ISAR_IIS_DKEY 0x03
#define ISAR_IIS_FIRM 0x1f
#define ISAR_IIS_STDSP 0x09
#define ISAR_IIS_DIAG 0x25
#define ISAR_IIS_GSTEV 0x00
#define ISAR_IIS_BSTEV 0x28
#define ISAR_IIS_BSTRSP 0x2c
#define ISAR_IIS_PSTRSP 0x2e
#define ISAR_IIS_PSTEV 0x2a
#define ISAR_IIS_IOM2RSP 0x27
#define ISAR_IIS_RDATA 0x20
#define ISAR_IIS_INVMSG 0x3f
#define ISAR_CTRL_SWVER 0x10
#define ISAR_CTRL_STST 0x40
#define ISAR_MSG_HWVER 0x20
#define ISAR_DP1_USE 1
#define ISAR_DP2_USE 2
#define ISAR_RATE_REQ 3
#define PMOD_DISABLE 0
#define PMOD_FAX 1
#define PMOD_DATAMODEM 2
#define PMOD_HALFDUPLEX 3
#define PMOD_V110 4
#define PMOD_DTMF 5
#define PMOD_DTMF_TRANS 6
#define PMOD_BYPASS 7
#define PCTRL_ORIG 0x80
#define PV32P2_V23R 0x40
#define PV32P2_V22A 0x20
#define PV32P2_V22B 0x10
#define PV32P2_V22C 0x08
#define PV32P2_V21 0x02
#define PV32P2_BEL 0x01
/* LSB MSB in ISAR doc wrong !!! Arghhh */
#define PV32P3_AMOD 0x80
#define PV32P3_V32B 0x02
#define PV32P3_V23B 0x01
#define PV32P4_48 0x11
#define PV32P5_48 0x05
#define PV32P4_UT48 0x11
#define PV32P5_UT48 0x0d
#define PV32P4_96 0x11
#define PV32P5_96 0x03
#define PV32P4_UT96 0x11
#define PV32P5_UT96 0x0f
#define PV32P4_B96 0x91
#define PV32P5_B96 0x0b
#define PV32P4_UTB96 0xd1
#define PV32P5_UTB96 0x0f
#define PV32P4_120 0xb1
#define PV32P5_120 0x09
#define PV32P4_UT120 0xf1
#define PV32P5_UT120 0x0f
#define PV32P4_144 0x99
#define PV32P5_144 0x09
#define PV32P4_UT144 0xf9
#define PV32P5_UT144 0x0f
#define PV32P6_CTN 0x01
#define PV32P6_ATN 0x02
#define PFAXP2_CTN 0x01
#define PFAXP2_ATN 0x04
#define PSEV_10MS_TIMER 0x02
#define PSEV_CON_ON 0x18
#define PSEV_CON_OFF 0x19
#define PSEV_V24_OFF 0x20
#define PSEV_CTS_ON 0x21
#define PSEV_CTS_OFF 0x22
#define PSEV_DCD_ON 0x23
#define PSEV_DCD_OFF 0x24
#define PSEV_DSR_ON 0x25
#define PSEV_DSR_OFF 0x26
#define PSEV_REM_RET 0xcc
#define PSEV_REM_REN 0xcd
#define PSEV_GSTN_CLR 0xd4
#define PSEV_RSP_READY 0xbc
#define PSEV_LINE_TX_H 0xb3
#define PSEV_LINE_TX_B 0xb2
#define PSEV_LINE_RX_H 0xb1
#define PSEV_LINE_RX_B 0xb0
#define PSEV_RSP_CONN 0xb5
#define PSEV_RSP_DISC 0xb7
#define PSEV_RSP_FCERR 0xb9
#define PSEV_RSP_SILDET 0xbe
#define PSEV_RSP_SILOFF 0xab
#define PSEV_FLAGS_DET 0xba
#define PCTRL_CMD_TDTMF 0x5a
#define PCTRL_CMD_FTH 0xa7
#define PCTRL_CMD_FRH 0xa5
#define PCTRL_CMD_FTM 0xa8
#define PCTRL_CMD_FRM 0xa6
#define PCTRL_CMD_SILON 0xac
#define PCTRL_CMD_CONT 0xa2
#define PCTRL_CMD_ESC 0xa4
#define PCTRL_CMD_SILOFF 0xab
#define PCTRL_CMD_HALT 0xa9
#define PCTRL_LOC_RET 0xcf
#define PCTRL_LOC_REN 0xce
#define SMODE_DISABLE 0
#define SMODE_V14 2
#define SMODE_HDLC 3
#define SMODE_BINARY 4
#define SMODE_FSK_V14 5
#define SCTRL_HDMC_BOTH 0x00
#define SCTRL_HDMC_DTX 0x80
#define SCTRL_HDMC_DRX 0x40
#define S_P1_OVSP 0x40
#define S_P1_SNP 0x20
#define S_P1_EOP 0x10
#define S_P1_EDP 0x08
#define S_P1_NSB 0x04
#define S_P1_CHS_8 0x03
#define S_P1_CHS_7 0x02
#define S_P1_CHS_6 0x01
#define S_P1_CHS_5 0x00
#define S_P2_BFT_DEF 0x10
#define IOM_CTRL_ENA 0x80
#define IOM_CTRL_NOPCM 0x00
#define IOM_CTRL_ALAW 0x02
#define IOM_CTRL_ULAW 0x04
#define IOM_CTRL_RCV 0x01
#define IOM_P1_TXD 0x10
#define HDLC_FED 0x40
#define HDLC_FSD 0x20
#define HDLC_FST 0x20
#define HDLC_ERROR 0x1c
#define HDLC_ERR_FAD 0x10
#define HDLC_ERR_RER 0x08
#define HDLC_ERR_CER 0x04
#define SART_NMD 0x01
#define BSTAT_RDM0 0x1
#define BSTAT_RDM1 0x2
#define BSTAT_RDM2 0x4
#define BSTAT_RDM3 0x8
#define BSTEV_TBO 0x1f
#define BSTEV_RBO 0x2f
/* FAX State Machine */
#define STFAX_NULL 0
#define STFAX_READY 1
#define STFAX_LINE 2
#define STFAX_CONT 3
#define STFAX_ACTIV 4
#define STFAX_ESCAPE 5
#define STFAX_SILDET 6
extern u32 mISDNisar_init(struct isar_hw *, void *);
extern void mISDNisar_irq(struct isar_hw *);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,57 @@
/*
* NETjet common header file
*
* Author Karsten Keil
* based on work of Matt Henderson and Daniel Potts,
* Traverse Technologies P/L www.traverse.com.au
*
* Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#define NJ_CTRL 0x00
#define NJ_DMACTRL 0x01
#define NJ_AUXCTRL 0x02
#define NJ_AUXDATA 0x03
#define NJ_IRQMASK0 0x04
#define NJ_IRQMASK1 0x05
#define NJ_IRQSTAT0 0x06
#define NJ_IRQSTAT1 0x07
#define NJ_DMA_READ_START 0x08
#define NJ_DMA_READ_IRQ 0x0c
#define NJ_DMA_READ_END 0x10
#define NJ_DMA_READ_ADR 0x14
#define NJ_DMA_WRITE_START 0x18
#define NJ_DMA_WRITE_IRQ 0x1c
#define NJ_DMA_WRITE_END 0x20
#define NJ_DMA_WRITE_ADR 0x24
#define NJ_PULSE_CNT 0x28
#define NJ_ISAC_OFF 0xc0
#define NJ_ISACIRQ 0x10
#define NJ_IRQM0_RD_MASK 0x03
#define NJ_IRQM0_RD_IRQ 0x01
#define NJ_IRQM0_RD_END 0x02
#define NJ_IRQM0_WR_MASK 0x0c
#define NJ_IRQM0_WR_IRQ 0x04
#define NJ_IRQM0_WR_END 0x08
/* one page here is no need to be smaller */
#define NJ_DMA_SIZE 4096
/* 2 * 64 byte is a compromise between IRQ count and latency */
#define NJ_DMA_RXSIZE 128 /* 2 * 64 */
#define NJ_DMA_TXSIZE 128 /* 2 * 64 */

View file

@ -0,0 +1,532 @@
/*
* speedfax.c low level stuff for Sedlbauer Speedfax+ cards
* based on the ISAR DSP
* Thanks to Sedlbauer AG for informations and HW
*
* Author Karsten Keil <keil@isdn4linux.de>
*
* Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
#include <linux/firmware.h>
#include "ipac.h"
#include "isar.h"
#define SPEEDFAX_REV "2.0"
#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51
#define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54
#define PCI_SUB_ID_SEDLBAUER 0x01
#define SFAX_PCI_ADDR 0xc8
#define SFAX_PCI_ISAC 0xd0
#define SFAX_PCI_ISAR 0xe0
/* TIGER 100 Registers */
#define TIGER_RESET_ADDR 0x00
#define TIGER_EXTERN_RESET_ON 0x01
#define TIGER_EXTERN_RESET_OFF 0x00
#define TIGER_AUX_CTRL 0x02
#define TIGER_AUX_DATA 0x03
#define TIGER_AUX_IRQMASK 0x05
#define TIGER_AUX_STATUS 0x07
/* Tiger AUX BITs */
#define SFAX_AUX_IOMASK 0xdd /* 1 and 5 are inputs */
#define SFAX_ISAR_RESET_BIT_OFF 0x00
#define SFAX_ISAR_RESET_BIT_ON 0x01
#define SFAX_TIGER_IRQ_BIT 0x02
#define SFAX_LED1_BIT 0x08
#define SFAX_LED2_BIT 0x10
#define SFAX_PCI_RESET_ON (SFAX_ISAR_RESET_BIT_ON)
#define SFAX_PCI_RESET_OFF (SFAX_LED1_BIT | SFAX_LED2_BIT)
static int sfax_cnt;
static u32 debug;
static u32 irqloops = 4;
struct sfax_hw {
struct list_head list;
struct pci_dev *pdev;
char name[MISDN_MAX_IDLEN];
u32 irq;
u32 irqcnt;
u32 cfg;
struct _ioport p_isac;
struct _ioport p_isar;
u8 aux_data;
spinlock_t lock; /* HW access lock */
struct isac_hw isac;
struct isar_hw isar;
};
static LIST_HEAD(Cards);
static DEFINE_RWLOCK(card_lock); /* protect Cards */
static void
_set_debug(struct sfax_hw *card)
{
card->isac.dch.debug = debug;
card->isar.ch[0].bch.debug = debug;
card->isar.ch[1].bch.debug = debug;
}
static int
set_debug(const char *val, struct kernel_param *kp)
{
int ret;
struct sfax_hw *card;
ret = param_set_uint(val, kp);
if (!ret) {
read_lock(&card_lock);
list_for_each_entry(card, &Cards, list)
_set_debug(card);
read_unlock(&card_lock);
}
return ret;
}
MODULE_AUTHOR("Karsten Keil");
MODULE_LICENSE("GPL v2");
MODULE_VERSION(SPEEDFAX_REV);
MODULE_FIRMWARE("isdn/ISAR.BIN");
module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Speedfax debug mask");
module_param(irqloops, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
IOFUNC_IND(ISAC, sfax_hw, p_isac)
IOFUNC_IND(ISAR, sfax_hw, p_isar)
static irqreturn_t
speedfax_irq(int intno, void *dev_id)
{
struct sfax_hw *sf = dev_id;
u8 val;
int cnt = irqloops;
spin_lock(&sf->lock);
val = inb(sf->cfg + TIGER_AUX_STATUS);
if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
spin_unlock(&sf->lock);
return IRQ_NONE; /* shared */
}
sf->irqcnt++;
val = ReadISAR_IND(sf, ISAR_IRQBIT);
Start_ISAR:
if (val & ISAR_IRQSTA)
mISDNisar_irq(&sf->isar);
val = ReadISAC_IND(sf, ISAC_ISTA);
if (val)
mISDNisac_irq(&sf->isac, val);
val = ReadISAR_IND(sf, ISAR_IRQBIT);
if ((val & ISAR_IRQSTA) && cnt--)
goto Start_ISAR;
if (cnt < irqloops)
pr_debug("%s: %d irqloops cpu%d\n", sf->name,
irqloops - cnt, smp_processor_id());
if (irqloops && !cnt)
pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
irqloops, smp_processor_id());
spin_unlock(&sf->lock);
return IRQ_HANDLED;
}
static void
enable_hwirq(struct sfax_hw *sf)
{
WriteISAC_IND(sf, ISAC_MASK, 0);
WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
}
static void
disable_hwirq(struct sfax_hw *sf)
{
WriteISAC_IND(sf, ISAC_MASK, 0xFF);
WriteISAR_IND(sf, ISAR_IRQBIT, 0);
outb(0, sf->cfg + TIGER_AUX_IRQMASK);
}
static void
reset_speedfax(struct sfax_hw *sf)
{
pr_debug("%s: resetting card\n", sf->name);
outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
mdelay(1);
outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
sf->aux_data = SFAX_PCI_RESET_OFF;
outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
mdelay(1);
}
static int
sfax_ctrl(struct sfax_hw *sf, u32 cmd, u_long arg)
{
int ret = 0;
switch (cmd) {
case HW_RESET_REQ:
reset_speedfax(sf);
break;
case HW_ACTIVATE_IND:
if (arg & 1)
sf->aux_data &= ~SFAX_LED1_BIT;
if (arg & 2)
sf->aux_data &= ~SFAX_LED2_BIT;
outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
break;
case HW_DEACT_IND:
if (arg & 1)
sf->aux_data |= SFAX_LED1_BIT;
if (arg & 2)
sf->aux_data |= SFAX_LED2_BIT;
outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
break;
default:
pr_info("%s: %s unknown command %x %lx\n",
sf->name, __func__, cmd, arg);
ret = -EINVAL;
break;
}
return ret;
}
static int
channel_ctrl(struct sfax_hw *sf, struct mISDN_ctrl_req *cq)
{
int ret = 0;
switch (cq->op) {
case MISDN_CTRL_GETOP:
cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
break;
case MISDN_CTRL_LOOP:
/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
if (cq->channel < 0 || cq->channel > 3) {
ret = -EINVAL;
break;
}
ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
break;
case MISDN_CTRL_L1_TIMER3:
ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1);
break;
default:
pr_info("%s: unknown Op %x\n", sf->name, cq->op);
ret = -EINVAL;
break;
}
return ret;
}
static int
sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
{
struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
struct dchannel *dch = container_of(dev, struct dchannel, dev);
struct sfax_hw *sf = dch->hw;
struct channel_req *rq;
int err = 0;
pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
switch (cmd) {
case OPEN_CHANNEL:
rq = arg;
if (rq->protocol == ISDN_P_TE_S0)
err = sf->isac.open(&sf->isac, rq);
else
err = sf->isar.open(&sf->isar, rq);
if (err)
break;
if (!try_module_get(THIS_MODULE))
pr_info("%s: cannot get module\n", sf->name);
break;
case CLOSE_CHANNEL:
pr_debug("%s: dev(%d) close from %p\n", sf->name,
dch->dev.id, __builtin_return_address(0));
module_put(THIS_MODULE);
break;
case CONTROL_CHANNEL:
err = channel_ctrl(sf, arg);
break;
default:
pr_debug("%s: unknown command %x\n", sf->name, cmd);
return -EINVAL;
}
return err;
}
static int
init_card(struct sfax_hw *sf)
{
int ret, cnt = 3;
u_long flags;
ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
if (ret) {
pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
return ret;
}
while (cnt--) {
spin_lock_irqsave(&sf->lock, flags);
ret = sf->isac.init(&sf->isac);
if (ret) {
spin_unlock_irqrestore(&sf->lock, flags);
pr_info("%s: ISAC init failed with %d\n",
sf->name, ret);
break;
}
enable_hwirq(sf);
/* RESET Receiver and Transmitter */
WriteISAC_IND(sf, ISAC_CMDR, 0x41);
spin_unlock_irqrestore(&sf->lock, flags);
msleep_interruptible(10);
if (debug & DEBUG_HW)
pr_notice("%s: IRQ %d count %d\n", sf->name,
sf->irq, sf->irqcnt);
if (!sf->irqcnt) {
pr_info("%s: IRQ(%d) got no requests during init %d\n",
sf->name, sf->irq, 3 - cnt);
} else
return 0;
}
free_irq(sf->irq, sf);
return -EIO;
}
static int
setup_speedfax(struct sfax_hw *sf)
{
u_long flags;
if (!request_region(sf->cfg, 256, sf->name)) {
pr_info("mISDN: %s config port %x-%x already in use\n",
sf->name, sf->cfg, sf->cfg + 255);
return -EIO;
}
outb(0xff, sf->cfg);
outb(0, sf->cfg);
outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
outb(0, sf->cfg + TIGER_AUX_IRQMASK);
sf->isac.type = IPAC_TYPE_ISAC;
sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
ASSIGN_FUNC(IND, ISAC, sf->isac);
ASSIGN_FUNC(IND, ISAR, sf->isar);
spin_lock_irqsave(&sf->lock, flags);
reset_speedfax(sf);
disable_hwirq(sf);
spin_unlock_irqrestore(&sf->lock, flags);
return 0;
}
static void
release_card(struct sfax_hw *card) {
u_long flags;
spin_lock_irqsave(&card->lock, flags);
disable_hwirq(card);
spin_unlock_irqrestore(&card->lock, flags);
card->isac.release(&card->isac);
free_irq(card->irq, card);
card->isar.release(&card->isar);
mISDN_unregister_device(&card->isac.dch.dev);
release_region(card->cfg, 256);
pci_disable_device(card->pdev);
pci_set_drvdata(card->pdev, NULL);
write_lock_irqsave(&card_lock, flags);
list_del(&card->list);
write_unlock_irqrestore(&card_lock, flags);
kfree(card);
sfax_cnt--;
}
static int
setup_instance(struct sfax_hw *card)
{
const struct firmware *firmware;
int i, err;
u_long flags;
snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
write_lock_irqsave(&card_lock, flags);
list_add_tail(&card->list, &Cards);
write_unlock_irqrestore(&card_lock, flags);
_set_debug(card);
spin_lock_init(&card->lock);
card->isac.hwlock = &card->lock;
card->isar.hwlock = &card->lock;
card->isar.ctrl = (void *)&sfax_ctrl;
card->isac.name = card->name;
card->isar.name = card->name;
card->isar.owner = THIS_MODULE;
err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
if (err < 0) {
pr_info("%s: firmware request failed %d\n",
card->name, err);
goto error_fw;
}
if (debug & DEBUG_HW)
pr_notice("%s: got firmware %zu bytes\n",
card->name, firmware->size);
mISDNisac_init(&card->isac, card);
card->isac.dch.dev.D.ctrl = sfax_dctrl;
card->isac.dch.dev.Bprotocols =
mISDNisar_init(&card->isar, card);
for (i = 0; i < 2; i++) {
set_channelmap(i + 1, card->isac.dch.dev.channelmap);
list_add(&card->isar.ch[i].bch.ch.list,
&card->isac.dch.dev.bchannels);
}
err = setup_speedfax(card);
if (err)
goto error_setup;
err = card->isar.init(&card->isar);
if (err)
goto error;
err = mISDN_register_device(&card->isac.dch.dev,
&card->pdev->dev, card->name);
if (err)
goto error;
err = init_card(card);
if (err)
goto error_init;
err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
if (!err) {
release_firmware(firmware);
sfax_cnt++;
pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
return 0;
}
disable_hwirq(card);
free_irq(card->irq, card);
error_init:
mISDN_unregister_device(&card->isac.dch.dev);
error:
release_region(card->cfg, 256);
error_setup:
card->isac.release(&card->isac);
card->isar.release(&card->isar);
release_firmware(firmware);
error_fw:
pci_disable_device(card->pdev);
write_lock_irqsave(&card_lock, flags);
list_del(&card->list);
write_unlock_irqrestore(&card_lock, flags);
kfree(card);
return err;
}
static int
sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err = -ENOMEM;
struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL);
if (!card) {
pr_info("No memory for Speedfax+ PCI\n");
return err;
}
card->pdev = pdev;
err = pci_enable_device(pdev);
if (err) {
kfree(card);
return err;
}
pr_notice("mISDN: Speedfax found adapter %s at %s\n",
(char *)ent->driver_data, pci_name(pdev));
card->cfg = pci_resource_start(pdev, 0);
card->irq = pdev->irq;
pci_set_drvdata(pdev, card);
err = setup_instance(card);
if (err)
pci_set_drvdata(pdev, NULL);
return err;
}
static void
sfax_remove_pci(struct pci_dev *pdev)
{
struct sfax_hw *card = pci_get_drvdata(pdev);
if (card)
release_card(card);
else
pr_debug("%s: drvdata already removed\n", __func__);
}
static struct pci_device_id sfaxpci_ids[] = {
{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
0, 0, (unsigned long) "Pyramid Speedfax + PCI"
},
{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
},
{ }
};
MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
static struct pci_driver sfaxpci_driver = {
.name = "speedfax+ pci",
.probe = sfaxpci_probe,
.remove = sfax_remove_pci,
.id_table = sfaxpci_ids,
};
static int __init
Speedfax_init(void)
{
int err;
pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
SPEEDFAX_REV);
err = pci_register_driver(&sfaxpci_driver);
return err;
}
static void __exit
Speedfax_cleanup(void)
{
pci_unregister_driver(&sfaxpci_driver);
}
module_init(Speedfax_init);
module_exit(Speedfax_cleanup);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,190 @@
/*
* Winbond W6692 specific defines
*
* Author Karsten Keil <keil@isdn4linux.de>
* based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
*
* Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* Specifications of W6692 registers */
#define W_D_RFIFO 0x00 /* R */
#define W_D_XFIFO 0x04 /* W */
#define W_D_CMDR 0x08 /* W */
#define W_D_MODE 0x0c /* R/W */
#define W_D_TIMR 0x10 /* R/W */
#define W_ISTA 0x14 /* R_clr */
#define W_IMASK 0x18 /* R/W */
#define W_D_EXIR 0x1c /* R_clr */
#define W_D_EXIM 0x20 /* R/W */
#define W_D_STAR 0x24 /* R */
#define W_D_RSTA 0x28 /* R */
#define W_D_SAM 0x2c /* R/W */
#define W_D_SAP1 0x30 /* R/W */
#define W_D_SAP2 0x34 /* R/W */
#define W_D_TAM 0x38 /* R/W */
#define W_D_TEI1 0x3c /* R/W */
#define W_D_TEI2 0x40 /* R/W */
#define W_D_RBCH 0x44 /* R */
#define W_D_RBCL 0x48 /* R */
#define W_TIMR2 0x4c /* W */
#define W_L1_RC 0x50 /* R/W */
#define W_D_CTL 0x54 /* R/W */
#define W_CIR 0x58 /* R */
#define W_CIX 0x5c /* W */
#define W_SQR 0x60 /* R */
#define W_SQX 0x64 /* W */
#define W_PCTL 0x68 /* R/W */
#define W_MOR 0x6c /* R */
#define W_MOX 0x70 /* R/W */
#define W_MOSR 0x74 /* R_clr */
#define W_MOCR 0x78 /* R/W */
#define W_GCR 0x7c /* R/W */
#define W_B_RFIFO 0x80 /* R */
#define W_B_XFIFO 0x84 /* W */
#define W_B_CMDR 0x88 /* W */
#define W_B_MODE 0x8c /* R/W */
#define W_B_EXIR 0x90 /* R_clr */
#define W_B_EXIM 0x94 /* R/W */
#define W_B_STAR 0x98 /* R */
#define W_B_ADM1 0x9c /* R/W */
#define W_B_ADM2 0xa0 /* R/W */
#define W_B_ADR1 0xa4 /* R/W */
#define W_B_ADR2 0xa8 /* R/W */
#define W_B_RBCL 0xac /* R */
#define W_B_RBCH 0xb0 /* R */
#define W_XADDR 0xf4 /* R/W */
#define W_XDATA 0xf8 /* R/W */
#define W_EPCTL 0xfc /* W */
/* W6692 register bits */
#define W_D_CMDR_XRST 0x01
#define W_D_CMDR_XME 0x02
#define W_D_CMDR_XMS 0x08
#define W_D_CMDR_STT 0x10
#define W_D_CMDR_RRST 0x40
#define W_D_CMDR_RACK 0x80
#define W_D_MODE_RLP 0x01
#define W_D_MODE_DLP 0x02
#define W_D_MODE_MFD 0x04
#define W_D_MODE_TEE 0x08
#define W_D_MODE_TMS 0x10
#define W_D_MODE_RACT 0x40
#define W_D_MODE_MMS 0x80
#define W_INT_B2_EXI 0x01
#define W_INT_B1_EXI 0x02
#define W_INT_D_EXI 0x04
#define W_INT_XINT0 0x08
#define W_INT_XINT1 0x10
#define W_INT_D_XFR 0x20
#define W_INT_D_RME 0x40
#define W_INT_D_RMR 0x80
#define W_D_EXI_WEXP 0x01
#define W_D_EXI_TEXP 0x02
#define W_D_EXI_ISC 0x04
#define W_D_EXI_MOC 0x08
#define W_D_EXI_TIN2 0x10
#define W_D_EXI_XCOL 0x20
#define W_D_EXI_XDUN 0x40
#define W_D_EXI_RDOV 0x80
#define W_D_STAR_DRDY 0x10
#define W_D_STAR_XBZ 0x20
#define W_D_STAR_XDOW 0x80
#define W_D_RSTA_RMB 0x10
#define W_D_RSTA_CRCE 0x20
#define W_D_RSTA_RDOV 0x40
#define W_D_CTL_SRST 0x20
#define W_CIR_SCC 0x80
#define W_CIR_ICC 0x40
#define W_CIR_COD_MASK 0x0f
#define W_PCTL_PCX 0x01
#define W_PCTL_XMODE 0x02
#define W_PCTL_OE0 0x04
#define W_PCTL_OE1 0x08
#define W_PCTL_OE2 0x10
#define W_PCTL_OE3 0x20
#define W_PCTL_OE4 0x40
#define W_PCTL_OE5 0x80
#define W_B_CMDR_XRST 0x01
#define W_B_CMDR_XME 0x02
#define W_B_CMDR_XMS 0x04
#define W_B_CMDR_RACT 0x20
#define W_B_CMDR_RRST 0x40
#define W_B_CMDR_RACK 0x80
#define W_B_MODE_FTS0 0x01
#define W_B_MODE_FTS1 0x02
#define W_B_MODE_SW56 0x04
#define W_B_MODE_BSW0 0x08
#define W_B_MODE_BSW1 0x10
#define W_B_MODE_EPCM 0x20
#define W_B_MODE_ITF 0x40
#define W_B_MODE_MMS 0x80
#define W_B_EXI_XDUN 0x01
#define W_B_EXI_XFR 0x02
#define W_B_EXI_RDOV 0x10
#define W_B_EXI_RME 0x20
#define W_B_EXI_RMR 0x40
#define W_B_STAR_XBZ 0x01
#define W_B_STAR_XDOW 0x04
#define W_B_STAR_RMB 0x10
#define W_B_STAR_CRCE 0x20
#define W_B_STAR_RDOV 0x40
#define W_B_RBCH_LOV 0x20
/* W6692 Layer1 commands */
#define W_L1CMD_ECK 0x00
#define W_L1CMD_RST 0x01
#define W_L1CMD_SCP 0x04
#define W_L1CMD_SSP 0x02
#define W_L1CMD_AR8 0x08
#define W_L1CMD_AR10 0x09
#define W_L1CMD_EAL 0x0a
#define W_L1CMD_DRC 0x0f
/* W6692 Layer1 indications */
#define W_L1IND_CE 0x07
#define W_L1IND_DRD 0x00
#define W_L1IND_LD 0x04
#define W_L1IND_ARD 0x08
#define W_L1IND_TI 0x0a
#define W_L1IND_ATI 0x0b
#define W_L1IND_AI8 0x0c
#define W_L1IND_AI10 0x0d
#define W_L1IND_CD 0x0f
/* FIFO thresholds */
#define W_D_FIFO_THRESH 64
#define W_B_FIFO_THRESH 64