summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-08-28 22:00:09 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-08-28 22:00:09 +0000
commit1a1d77dd589de5a567fa95e36aa6999c704ceca4 (patch)
tree141e31f89f18b9fe0831f31852e0435ceaccafc5 /drivers/char
parentfb9c690a18b3d66925a65b17441c37fa14d4370b (diff)
Merge with 2.4.0-test7.
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Config.in105
-rw-r--r--drivers/char/Makefile65
-rw-r--r--drivers/char/agp/agp.h7
-rw-r--r--drivers/char/agp/agpgart_be.c38
-rw-r--r--drivers/char/audiochip.h60
-rw-r--r--drivers/char/bt848.h355
-rw-r--r--drivers/char/bttv-cards.c835
-rw-r--r--drivers/char/bttv-driver.c3272
-rw-r--r--drivers/char/bttv-if.c337
-rw-r--r--drivers/char/bttv.h425
-rw-r--r--drivers/char/buz.c3479
-rw-r--r--drivers/char/buz.h319
-rw-r--r--drivers/char/bw-qcam.c1066
-rw-r--r--drivers/char/bw-qcam.h68
-rw-r--r--drivers/char/c-qcam.c901
-rw-r--r--drivers/char/cpia.c3324
-rw-r--r--drivers/char/cpia.h421
-rw-r--r--drivers/char/cpia_pp.c745
-rw-r--r--drivers/char/cpia_usb.c626
-rw-r--r--drivers/char/cs8420.h50
-rw-r--r--drivers/char/drm/agpsupport.c6
-rw-r--r--drivers/char/drm/auth.c4
-rw-r--r--drivers/char/drm/drmP.h9
-rw-r--r--drivers/char/drm/ffb_drv.c43
-rw-r--r--drivers/char/drm/lists.c41
-rw-r--r--drivers/char/drm/lock.c32
-rw-r--r--drivers/char/drm/mga_dma.c2
-rw-r--r--drivers/char/drm/r128_drv.c10
-rw-r--r--drivers/char/drm/vm.c5
-rw-r--r--drivers/char/ds1620.c1
-rw-r--r--drivers/char/efirtc.c3
-rw-r--r--drivers/char/generic_serial.c129
-rw-r--r--drivers/char/i2c-old.c458
-rw-r--r--drivers/char/i2c-parport.c147
-rw-r--r--drivers/char/i810-tco.c326
-rw-r--r--drivers/char/i810-tco.h45
-rw-r--r--drivers/char/ibmmpeg2.h94
-rw-r--r--drivers/char/joystick/Config.in60
-rw-r--r--drivers/char/joystick/Makefile16
-rw-r--r--drivers/char/joystick/amijoy.c21
-rw-r--r--drivers/char/joystick/db9.c104
-rw-r--r--drivers/char/joystick/gamecon.c28
-rw-r--r--drivers/char/joystick/iforce.c342
-rw-r--r--drivers/char/joystick/ns558.c38
-rw-r--r--drivers/char/joystick/sidewinder.c6
-rw-r--r--drivers/char/joystick/spaceball.c47
-rw-r--r--drivers/char/msp3400.c1454
-rw-r--r--drivers/char/nwbutton.c2
-rw-r--r--drivers/char/nwflash.c1
-rw-r--r--drivers/char/pcxx.c122
-rw-r--r--drivers/char/pcxx.h1
-rw-r--r--drivers/char/planb.c2341
-rw-r--r--drivers/char/planb.h232
-rw-r--r--drivers/char/pms.c1074
-rw-r--r--drivers/char/radio-aimslab.c390
-rw-r--r--drivers/char/radio-aztech.c330
-rw-r--r--drivers/char/radio-cadet.c603
-rw-r--r--drivers/char/radio-gemtek.c319
-rw-r--r--drivers/char/radio-miropcm20.c239
-rw-r--r--drivers/char/radio-rtrack2.c280
-rw-r--r--drivers/char/radio-sf16fmi.c339
-rw-r--r--drivers/char/radio-terratec.c358
-rw-r--r--drivers/char/radio-trust.c350
-rw-r--r--drivers/char/radio-typhoon.c402
-rw-r--r--drivers/char/radio-zoltrix.c412
-rw-r--r--drivers/char/rio/linux_compat.h4
-rw-r--r--drivers/char/rio/rio_linux.c46
-rw-r--r--drivers/char/rio/rio_linux.h23
-rw-r--r--drivers/char/rio/rioboot.c186
-rw-r--r--drivers/char/rio/riocmd.c248
-rw-r--r--drivers/char/rio/rioctrl.c430
-rw-r--r--drivers/char/rio/rioinit.c252
-rw-r--r--drivers/char/rio/riointr.c142
-rw-r--r--drivers/char/rio/rioparam.c174
-rw-r--r--drivers/char/rio/rioroute.c148
-rw-r--r--drivers/char/rio/riotable.c168
-rw-r--r--drivers/char/rio/riotty.c222
-rw-r--r--drivers/char/saa5249.c683
-rw-r--r--drivers/char/saa7110.c429
-rw-r--r--drivers/char/saa7111.c418
-rw-r--r--drivers/char/saa7121.h132
-rw-r--r--drivers/char/saa7146.h117
-rw-r--r--drivers/char/saa7146reg.h283
-rw-r--r--drivers/char/saa7185.c377
-rw-r--r--drivers/char/saa7196.h117
-rw-r--r--drivers/char/scan_keyb.c24
-rw-r--r--drivers/char/serial.c289
-rw-r--r--drivers/char/serial_21285.c511
-rw-r--r--drivers/char/stallion.c5329
-rw-r--r--drivers/char/stradis.c2287
-rw-r--r--drivers/char/sx.c10
-rw-r--r--drivers/char/tda7432.c505
-rw-r--r--drivers/char/tda8425.c324
-rw-r--r--drivers/char/tda985x.c536
-rw-r--r--drivers/char/tda9875.c403
-rw-r--r--drivers/char/tea6300.c344
-rw-r--r--drivers/char/tea6420.c268
-rw-r--r--drivers/char/tty_io.c8
-rw-r--r--drivers/char/tuner-3036.c227
-rw-r--r--drivers/char/tuner.c451
-rw-r--r--drivers/char/tuner.h57
-rw-r--r--drivers/char/tvmixer.c353
-rw-r--r--drivers/char/videodev.c581
-rw-r--r--drivers/char/vino.c275
-rw-r--r--drivers/char/vino.h118
-rw-r--r--drivers/char/wdt285.c2
-rw-r--r--drivers/char/zr36057.h168
-rw-r--r--drivers/char/zr36060.h35
-rw-r--r--drivers/char/zr36120.c2086
-rw-r--r--drivers/char/zr36120.h279
-rw-r--r--drivers/char/zr36120_i2c.c133
-rw-r--r--drivers/char/zr36120_mem.c77
-rw-r--r--drivers/char/zr36120_mem.h3
113 files changed, 2971 insertions, 45075 deletions
diff --git a/drivers/char/Config.in b/drivers/char/Config.in
index 08b50aaa1..7872a6f00 100644
--- a/drivers/char/Config.in
+++ b/drivers/char/Config.in
@@ -8,7 +8,7 @@ bool 'Virtual terminal' CONFIG_VT
if [ "$CONFIG_VT" = "y" ]; then
bool ' Support for console on virtual terminal' CONFIG_VT_CONSOLE
fi
-tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
+tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL
if [ "$CONFIG_SERIAL" = "y" ]; then
bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
@@ -60,6 +60,15 @@ if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then
tristate ' Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION
fi
fi
+if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
+ bool 'DC21285 serial port support' CONFIG_SERIAL_21285
+ if [ "$CONFIG_SERIAL_21285" = "y" ]; then
+ if [ "$CONFIG_OBSOLETE" = "y" ]; then
+ bool ' Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD
+ fi
+ bool ' Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE
+ fi
+fi
bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
@@ -124,8 +133,9 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG
tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
- tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
+ tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD
+ tristate ' Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO
if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG
if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then
@@ -154,98 +164,7 @@ if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then
bool 'Tadpole ANA H8 Support' CONFIG_H8
fi
-mainmenu_option next_comment
-comment 'Video For Linux'
-
-tristate 'Video For Linux' CONFIG_VIDEO_DEV
-if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
- bool ' V4L information in proc filesystem' CONFIG_VIDEO_PROC_FS Y
- dep_tristate ' I2C on parallel port' CONFIG_I2C_PARPORT $CONFIG_PARPORT $CONFIG_I2C
- comment 'Radio Adapters'
- dep_tristate ' ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV
- dep_tristate ' AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then
- hex ' RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f
- fi
- dep_tristate ' AIMSlab RadioTrack II support' CONFIG_RADIO_RTRACK2 $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_RTRACK2" = "y" ]; then
- hex ' RadioTrack II i/o port (0x20c or 0x30c)' CONFIG_RADIO_RTRACK2_PORT 30c
- fi
- dep_tristate ' Aztech/Packard Bell Radio' CONFIG_RADIO_AZTECH $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then
- hex ' Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350
- fi
- dep_tristate ' GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
- hex ' GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c
- fi
- dep_tristate ' Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
- dep_tristate ' SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then
- hex ' SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284
- fi
- dep_tristate ' TerraTec ActiveRadio ISA Standalone' CONFIG_RADIO_TERRATEC $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_TERRATEC" = "y" ]; then
- hex ' Terratec i/o port (normally 0x590)' CONFIG_RADIO_TERRATEC_PORT 590
- fi
- dep_tristate ' Trust FM radio card' CONFIG_RADIO_TRUST $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_TRUST" = "y" ]; then
- hex ' Trust i/o port (usually 0x350 or 0x358)' CONFIG_RADIO_TRUST_PORT 350
- fi
- dep_tristate ' Typhoon Radio (a.k.a. EcoRadio)' CONFIG_RADIO_TYPHOON $CONFIG_VIDEO_DEV
- if [ "$CONFIG_PROC_FS" = "y" ]; then
- if [ "$CONFIG_RADIO_TYPHOON" != "n" ]; then
- bool ' Support for /proc/radio-typhoon' CONFIG_RADIO_TYPHOON_PROC_FS
- fi
- fi
- if [ "$CONFIG_RADIO_TYPHOON" = "y" ]; then
- hex ' Typhoon I/O port (0x316 or 0x336)' CONFIG_RADIO_TYPHOON_PORT 316
- int ' Typhoon frequency set when muting the device (kHz)' CONFIG_RADIO_TYPHOON_MUTEFREQ 87500
- fi
- dep_tristate ' Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV
- if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then
- hex ' ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
- fi
- comment 'Video Adapters'
- if [ "$CONFIG_I2C_ALGOBIT" = "y" -o "$CONFIG_I2C_ALGOBIT" = "m" ]; then
- dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT
- fi
- dep_tristate ' Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV
- if [ "$CONFIG_ALL_PPC" = "y" ]; then
- dep_tristate ' PlanB Video-In on PowerMac' CONFIG_VIDEO_PLANB $CONFIG_VIDEO_DEV
- fi
- if [ "$CONFIG_PARPORT" != "n" ]; then
- dep_tristate ' Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- dep_tristate ' QuickCam Colour Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_CQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT
- fi
- fi
- dep_tristate ' CPiA Video For Linux' CONFIG_VIDEO_CPIA $CONFIG_VIDEO_DEV
- if [ "$CONFIG_VIDEO_CPIA" != "n" ]; then
- if [ "CONFIG_PARPORT_1284" != "n" ]; then
- dep_tristate ' CPiA Parallel Port Lowlevel Support' CONFIG_VIDEO_CPIA_PP $CONFIG_VIDEO_CPIA $CONFIG_PARPORT
- fi
- if [ "$CONFIG_USB" != "n" ]; then
- dep_tristate ' CPiA USB Lowlevel Support' CONFIG_VIDEO_CPIA_USB $CONFIG_VIDEO_CPIA $CONFIG_USB
- fi
- fi
- dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV $CONFIG_I2C
- dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV $CONFIG_I2C
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- if [ "$CONFIG_SGI" = "y" ]; then
- dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_SGI
- fi
- dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV $CONFIG_PCI
- fi
- dep_tristate ' Zoran ZR36057/36060 Video For Linux' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI
- dep_tristate ' Include support for Iomega Buz' CONFIG_VIDEO_BUZ $CONFIG_VIDEO_ZORAN
- dep_tristate ' Zoran ZR36120/36125 Video For Linux' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
-fi
-
-endmenu
-
tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
-
tristate 'Siemens R3964 line discipline' CONFIG_R3964
tristate 'Applicom intelligent fieldbus card support' CONFIG_APPLICOM
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index a83719fb7..b7a71c0f5 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -36,12 +36,11 @@ obj-y += tty_io.o n_tty.o tty_ioctl.o mem.o raw.o pty.o misc.o random.o
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-export-objs := busmouse.o console.o i2c-old.o keyboard.o sysrq.o \
- misc.o pty.o random.o selection.o serial.o videodev.o \
- tty_io.o bttv-if.o cpia.o
+export-objs := busmouse.o console.o keyboard.o sysrq.o \
+ misc.o pty.o random.o selection.o serial.o \
+ tty_io.o
-list-multi := bttv.o
-bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o
+list-multi :=
KEYMAP =defkeymap.o
KEYBD =pc_keyb.o
@@ -65,11 +64,12 @@ ifeq ($(ARCH),m68k)
endif
ifeq ($(ARCH),arm)
-# we actually need to be able to select various different keymaps
-# and keyboards dependent on which actual machine we're going to
-# run on.
- KEYMAP =
- KEYBD =
+ ifneq ($(CONFIG_PC_KEYMAP),y)
+ KEYMAP =
+ endif
+ ifneq ($(CONFIG_PC_KEYB),y)
+ KEYBD =
+ endif
endif
ifeq ($(ARCH),sh)
@@ -142,12 +142,12 @@ obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o
obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o
obj-$(CONFIG_PRINTER) += lp.o
-ifeq ($(CONFIG_JOYSTICK),y)
+ifeq ($(CONFIG_INPUT),y)
obj-y += joystick/js.o
SUB_DIRS += joystick
MOD_SUB_DIRS += joystick
else
- ifeq ($(CONFIG_JOYSTICK),m)
+ ifeq ($(CONFIG_INPUT),m)
MOD_SUB_DIRS += joystick
endif
endif
@@ -175,44 +175,12 @@ ifeq ($(CONFIG_PPC),)
obj-$(CONFIG_NVRAM) += nvram.o
endif
-obj-$(CONFIG_VIDEO_DEV) += videodev.o
-
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
+obj-$(CONFIG_I810_TCO) += i810-tco.o
obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_INTEL_RNG) += i810_rng.o
-obj-$(CONFIG_BUS_I2C) += i2c-old.o
-obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o \
- tda7432.o tda8425.o tda985x.o tda9875.o tea6300.o tea6420.o tuner.o
-obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
-
-obj-$(CONFIG_VIDEO_ZR36120) += zoran.o i2c-old.o tuner.o saa7110.o saa7111.o saa7185.o
-obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o i2c-old.o
-obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o i2c-old.o
-obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
-obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
-obj-$(CONFIG_VIDEO_ZORAN) += buz.o i2c-old.o saa7110.o saa7111.o saa7185.o
-obj-$(CONFIG_VIDEO_LML33) += bt856.o bt819.o
-obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_PLANB) += planb.o
-obj-$(CONFIG_VIDEO_VINO) += vino.o
-obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
-obj-$(CONFIG_VIDEO_CPIA) += cpia.o
-obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
-obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
-obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
-obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
-obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o
-obj-$(CONFIG_RADIO_CADET) += radio-cadet.o
-obj-$(CONFIG_RADIO_TYPHOON) += radio-typhoon.o
-obj-$(CONFIG_RADIO_TERRATEC) += radio-terratec.o
-obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
-obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
-obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
-obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
-obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
-obj-$(CONFIG_TUNER_3036) += tuner-3036.o
obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
ifeq ($(CONFIG_FTAPE),y)
@@ -300,10 +268,3 @@ consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h
defkeymap.c: defkeymap.map
loadkeys --mktable defkeymap.map > defkeymap.c
-
-zoran.o: zr36120.o zr36120_i2c.o zr36120_mem.o
- $(LD) $(LD_RFLAG) -r -o $@ zr36120.o zr36120_i2c.o zr36120_mem.o
-
-bttv.o: $(bttv-objs)
- $(LD) $(LD_RFLAG) -r -o $@ $(bttv-objs)
-
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index af32ba284..acad5947a 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -154,8 +154,11 @@ struct agp_bridge_data {
#ifndef PCI_DEVICE_ID_VIA_82C691_0
#define PCI_DEVICE_ID_VIA_82C691_0 0x0691
#endif
-#ifndef PCI_DEVICE_ID_VIA_82C691_1
-#define PCI_DEVICE_ID_VIA_82C691_1 0x8691
+#ifndef PCI_DEVICE_ID_VIA_8371_0
+#define PCI_DEVICE_ID_VIA_8371_0 0x0391
+#endif
+#ifndef PCI_DEVICE_ID_VIA_8363_0
+#define PCI_DEVICE_ID_VIA_8363_0 0x0305
#endif
#ifndef PCI_DEVICE_ID_INTEL_810_0
#define PCI_DEVICE_ID_INTEL_810_0 0x7120
diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
index e5fbba8b5..44bd3bfb4 100644
--- a/drivers/char/agp/agpgart_be.c
+++ b/drivers/char/agp/agpgart_be.c
@@ -67,14 +67,16 @@ static inline void flush_cache(void)
{
#if defined(__i386__)
asm volatile ("wbinvd":::"memory");
-#elif defined(__alpha__)
+#elif defined(__alpha__) || defined(__ia64__)
/* ??? I wonder if we'll really need to flush caches, or if the
core logic can manage to keep the system coherent. The ARM
speaks only of using `cflush' to get things in memory in
preparation for power failure.
If we do need to call `cflush', we'll need a target page,
- as we can only flush one page at a time. */
+ as we can only flush one page at a time.
+
+ Ditto for IA-64. --davidm 00/08/07 */
mb();
#else
#error "Please define flush_cache."
@@ -412,10 +414,9 @@ int agp_unbind_memory(agp_memory * curr)
/*
* Driver routines - start
- * Currently this module supports the
- * i810, 440lx, 440bx, 440gx, via vp3, via mvp3,
- * amd irongate, ALi M1541 and generic support for the
- * SiS chipsets.
+ * Currently this module supports the following chipsets:
+ * i810, 440lx, 440bx, 440gx, via vp3, via mvp3, via kx133, via kt133,
+ * amd irongate, ALi M1541, and generic support for the SiS chipsets.
*/
/* Generic Agp routines - Start */
@@ -637,7 +638,7 @@ static int agp_generic_create_gatt_table(void)
}
table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
- for (page = virt_to_page(table); page < virt_to_page(table_end); page++)
+ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
set_bit(PG_reserved, &page->flags);
agp_bridge.gatt_table_real = (unsigned long *) table;
@@ -647,7 +648,7 @@ static int agp_generic_create_gatt_table(void)
CACHE_FLUSH();
if (agp_bridge.gatt_table == NULL) {
- for (page = virt_to_page(table); page < virt_to_page(table_end); page++)
+ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
clear_bit(PG_reserved, &page->flags);
free_pages((unsigned long) table, page_order);
@@ -704,7 +705,7 @@ static int agp_generic_free_gatt_table(void)
table = (char *) agp_bridge.gatt_table_real;
table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
- for (page = virt_to_page(table); page < virt_to_page(table_end); page++)
+ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
clear_bit(PG_reserved, &page->flags);
free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
@@ -976,6 +977,7 @@ static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
agp_bridge.scratch_page);
}
+ CACHE_FLUSH();
agp_bridge.tlb_flush(mem);
return 0;
}
@@ -2127,12 +2129,6 @@ static struct {
#endif /* CONFIG_AGP_SIS */
#ifdef CONFIG_AGP_VIA
- { PCI_DEVICE_ID_VIA_8371_0,
- PCI_VENDOR_ID_VIA,
- VIA_APOLLO_SUPER,
- "Via",
- "Apollo Super",
- via_generic_setup },
{ PCI_DEVICE_ID_VIA_8501_0,
PCI_VENDOR_ID_VIA,
VIA_MVP4,
@@ -2157,6 +2153,18 @@ static struct {
"Via",
"Apollo Pro",
via_generic_setup },
+ { PCI_DEVICE_ID_VIA_8371_0,
+ PCI_VENDOR_ID_VIA,
+ VIA_APOLLO_KX133,
+ "Via",
+ "Apollo Pro KX133",
+ via_generic_setup },
+ { PCI_DEVICE_ID_VIA_8363_0,
+ PCI_VENDOR_ID_VIA,
+ VIA_APOLLO_KT133,
+ "Via",
+ "Apollo Pro KT133",
+ via_generic_setup },
{ 0,
PCI_VENDOR_ID_VIA,
VIA_GENERIC,
diff --git a/drivers/char/audiochip.h b/drivers/char/audiochip.h
deleted file mode 100644
index 23d1b1259..000000000
--- a/drivers/char/audiochip.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef AUDIOCHIP_H
-#define AUDIOCHIP_H
-
-/* ---------------------------------------------------------------------- */
-
-#define MIN(a,b) (((a)>(b))?(b):(a))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-/* v4l device was opened in Radio mode */
-#define AUDC_SET_RADIO _IO('m',2)
-/* select from TV,radio,extern,MUTE */
-#define AUDC_SET_INPUT _IOW('m',17,int)
-
-/* all the stuff below is obsolete and just here for reference. I'll
- * remove it once the driver is tested and works fine.
- *
- * Instead creating alot of tiny API's for all kinds of different
- * chips, we'll just pass throuth the v4l ioctl structs (v4l2 not
- * yet...). It is a bit less flexible, but most/all used i2c chips
- * make sense in v4l context only. So I think that's acceptable...
- */
-
-#if 0
-
-/* TODO (if it is ever [to be] accessible in the V4L[2] spec):
- * maybe fade? (back/front)
- * notes:
- * NEWCHANNEL and SWITCH_MUTE are here because the MSP3400 has a special
- * routine to go through when it tunes in to a new channel before turning
- * back on the sound.
- * Either SET_RADIO, NEWCHANNEL, and SWITCH_MUTE or SET_INPUT need to be
- * implemented (MSP3400 uses SET_RADIO to select inputs, and SWITCH_MUTE for
- * channel-change mute -- TEA6300 et al use SET_AUDIO to select input [TV,
- * radio, external, or MUTE]). If both methods are implemented, you get a
- * cookie for doing such a good job! :)
- */
-
-#define AUDC_SET_TVNORM _IOW('m',1,int) /* TV mode + PAL/SECAM/NTSC */
-#define AUDC_NEWCHANNEL _IO('m',3) /* indicate new chan - off mute */
-
-#define AUDC_GET_VOLUME_LEFT _IOR('m',4,__u16)
-#define AUDC_GET_VOLUME_RIGHT _IOR('m',5,__u16)
-#define AUDC_SET_VOLUME_LEFT _IOW('m',6,__u16)
-#define AUDC_SET_VOLUME_RIGHT _IOW('m',7,__u16)
-
-#define AUDC_GET_STEREO _IOR('m',8,__u16)
-#define AUDC_SET_STEREO _IOW('m',9,__u16)
-
-#define AUDC_GET_DC _IOR('m',10,__u16)/* ??? */
-
-#define AUDC_GET_BASS _IOR('m',11,__u16)
-#define AUDC_SET_BASS _IOW('m',12,__u16)
-#define AUDC_GET_TREBLE _IOR('m',13,__u16)
-#define AUDC_SET_TREBLE _IOW('m',14,__u16)
-
-#define AUDC_GET_UNIT _IOR('m',15,int) /* ??? - unimplemented in MSP3400 */
-#define AUDC_SWITCH_MUTE _IO('m',16) /* turn on mute */
-#endif
-
-#endif /* AUDIOCHIP_H */
diff --git a/drivers/char/bt848.h b/drivers/char/bt848.h
deleted file mode 100644
index 340accf31..000000000
--- a/drivers/char/bt848.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- bt848.h - Bt848 register offsets
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.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 of the License, 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.
-*/
-
-#ifndef _BT848_H_
-#define _BT848_H_
-
-#ifndef PCI_VENDOR_ID_BROOKTREE
-#define PCI_VENDOR_ID_BROOKTREE 0x109e
-#endif
-#ifndef PCI_DEVICE_ID_BT848
-#define PCI_DEVICE_ID_BT848 0x350
-#endif
-#ifndef PCI_DEVICE_ID_BT849
-#define PCI_DEVICE_ID_BT849 0x351
-#endif
-#ifndef PCI_DEVICE_ID_BT878
-#define PCI_DEVICE_ID_BT878 0x36e
-#endif
-#ifndef PCI_DEVICE_ID_BT879
-#define PCI_DEVICE_ID_BT879 0x36f
-#endif
-
-
-/* Brooktree 848 registers */
-
-#define BT848_DSTATUS 0x000
-#define BT848_DSTATUS_PRES (1<<7)
-#define BT848_DSTATUS_HLOC (1<<6)
-#define BT848_DSTATUS_FIELD (1<<5)
-#define BT848_DSTATUS_NUML (1<<4)
-#define BT848_DSTATUS_CSEL (1<<3)
-#define BT848_DSTATUS_PLOCK (1<<2)
-#define BT848_DSTATUS_LOF (1<<1)
-#define BT848_DSTATUS_COF (1<<0)
-
-#define BT848_IFORM 0x004
-#define BT848_IFORM_HACTIVE (1<<7)
-#define BT848_IFORM_MUXSEL (3<<5)
-#define BT848_IFORM_MUX0 (2<<5)
-#define BT848_IFORM_MUX1 (3<<5)
-#define BT848_IFORM_MUX2 (1<<5)
-#define BT848_IFORM_XTSEL (3<<3)
-#define BT848_IFORM_XT0 (1<<3)
-#define BT848_IFORM_XT1 (2<<3)
-#define BT848_IFORM_XTAUTO (3<<3)
-#define BT848_IFORM_XTBOTH (3<<3)
-#define BT848_IFORM_NTSC 1
-#define BT848_IFORM_NTSC_J 2
-#define BT848_IFORM_PAL_BDGHI 3
-#define BT848_IFORM_PAL_M 4
-#define BT848_IFORM_PAL_N 5
-#define BT848_IFORM_SECAM 6
-#define BT848_IFORM_PAL_NC 7
-#define BT848_IFORM_AUTO 0
-#define BT848_IFORM_NORM 7
-
-#define BT848_TDEC 0x008
-#define BT848_TDEC_DEC_FIELD (1<<7)
-#define BT848_TDEC_FLDALIGN (1<<6)
-#define BT848_TDEC_DEC_RAT (0x1f)
-
-#define BT848_E_CROP 0x00C
-#define BT848_O_CROP 0x08C
-
-#define BT848_E_VDELAY_LO 0x010
-#define BT848_O_VDELAY_LO 0x090
-
-#define BT848_E_VACTIVE_LO 0x014
-#define BT848_O_VACTIVE_LO 0x094
-
-#define BT848_E_HDELAY_LO 0x018
-#define BT848_O_HDELAY_LO 0x098
-
-#define BT848_E_HACTIVE_LO 0x01C
-#define BT848_O_HACTIVE_LO 0x09C
-
-#define BT848_E_HSCALE_HI 0x020
-#define BT848_O_HSCALE_HI 0x0A0
-
-#define BT848_E_HSCALE_LO 0x024
-#define BT848_O_HSCALE_LO 0x0A4
-
-#define BT848_BRIGHT 0x028
-
-#define BT848_E_CONTROL 0x02C
-#define BT848_O_CONTROL 0x0AC
-#define BT848_CONTROL_LNOTCH (1<<7)
-#define BT848_CONTROL_COMP (1<<6)
-#define BT848_CONTROL_LDEC (1<<5)
-#define BT848_CONTROL_CBSENSE (1<<4)
-#define BT848_CONTROL_CON_MSB (1<<2)
-#define BT848_CONTROL_SAT_U_MSB (1<<1)
-#define BT848_CONTROL_SAT_V_MSB (1<<0)
-
-#define BT848_CONTRAST_LO 0x030
-#define BT848_SAT_U_LO 0x034
-#define BT848_SAT_V_LO 0x038
-#define BT848_HUE 0x03C
-
-#define BT848_E_SCLOOP 0x040
-#define BT848_O_SCLOOP 0x0C0
-#define BT848_SCLOOP_CAGC (1<<6)
-#define BT848_SCLOOP_CKILL (1<<5)
-#define BT848_SCLOOP_HFILT_AUTO (0<<3)
-#define BT848_SCLOOP_HFILT_CIF (1<<3)
-#define BT848_SCLOOP_HFILT_QCIF (2<<3)
-#define BT848_SCLOOP_HFILT_ICON (3<<3)
-
-#define BT848_SCLOOP_PEAK (1<<7)
-#define BT848_SCLOOP_HFILT_MINP (1<<3)
-#define BT848_SCLOOP_HFILT_MEDP (2<<3)
-#define BT848_SCLOOP_HFILT_MAXP (3<<3)
-
-
-#define BT848_OFORM 0x048
-#define BT848_OFORM_RANGE (1<<7)
-#define BT848_OFORM_CORE0 (0<<5)
-#define BT848_OFORM_CORE8 (1<<5)
-#define BT848_OFORM_CORE16 (2<<5)
-#define BT848_OFORM_CORE32 (3<<5)
-
-#define BT848_E_VSCALE_HI 0x04C
-#define BT848_O_VSCALE_HI 0x0CC
-#define BT848_VSCALE_YCOMB (1<<7)
-#define BT848_VSCALE_COMB (1<<6)
-#define BT848_VSCALE_INT (1<<5)
-#define BT848_VSCALE_HI 15
-
-#define BT848_E_VSCALE_LO 0x050
-#define BT848_O_VSCALE_LO 0x0D0
-#define BT848_TEST 0x054
-#define BT848_ADELAY 0x060
-#define BT848_BDELAY 0x064
-
-#define BT848_ADC 0x068
-#define BT848_ADC_RESERVED (2<<6)
-#define BT848_ADC_SYNC_T (1<<5)
-#define BT848_ADC_AGC_EN (1<<4)
-#define BT848_ADC_CLK_SLEEP (1<<3)
-#define BT848_ADC_Y_SLEEP (1<<2)
-#define BT848_ADC_C_SLEEP (1<<1)
-#define BT848_ADC_CRUSH (1<<0)
-
-#define BT848_E_VTC 0x06C
-#define BT848_O_VTC 0x0EC
-#define BT848_VTC_HSFMT (1<<7)
-#define BT848_VTC_VFILT_2TAP 0
-#define BT848_VTC_VFILT_3TAP 1
-#define BT848_VTC_VFILT_4TAP 2
-#define BT848_VTC_VFILT_5TAP 3
-
-#define BT848_SRESET 0x07C
-
-#define BT848_COLOR_FMT 0x0D4
-#define BT848_COLOR_FMT_O_RGB32 (0<<4)
-#define BT848_COLOR_FMT_O_RGB24 (1<<4)
-#define BT848_COLOR_FMT_O_RGB16 (2<<4)
-#define BT848_COLOR_FMT_O_RGB15 (3<<4)
-#define BT848_COLOR_FMT_O_YUY2 (4<<4)
-#define BT848_COLOR_FMT_O_BtYUV (5<<4)
-#define BT848_COLOR_FMT_O_Y8 (6<<4)
-#define BT848_COLOR_FMT_O_RGB8 (7<<4)
-#define BT848_COLOR_FMT_O_YCrCb422 (8<<4)
-#define BT848_COLOR_FMT_O_YCrCb411 (9<<4)
-#define BT848_COLOR_FMT_O_RAW (14<<4)
-#define BT848_COLOR_FMT_E_RGB32 0
-#define BT848_COLOR_FMT_E_RGB24 1
-#define BT848_COLOR_FMT_E_RGB16 2
-#define BT848_COLOR_FMT_E_RGB15 3
-#define BT848_COLOR_FMT_E_YUY2 4
-#define BT848_COLOR_FMT_E_BtYUV 5
-#define BT848_COLOR_FMT_E_Y8 6
-#define BT848_COLOR_FMT_E_RGB8 7
-#define BT848_COLOR_FMT_E_YCrCb422 8
-#define BT848_COLOR_FMT_E_YCrCb411 9
-#define BT848_COLOR_FMT_E_RAW 14
-
-#define BT848_COLOR_FMT_RGB32 0x00
-#define BT848_COLOR_FMT_RGB24 0x11
-#define BT848_COLOR_FMT_RGB16 0x22
-#define BT848_COLOR_FMT_RGB15 0x33
-#define BT848_COLOR_FMT_YUY2 0x44
-#define BT848_COLOR_FMT_BtYUV 0x55
-#define BT848_COLOR_FMT_Y8 0x66
-#define BT848_COLOR_FMT_RGB8 0x77
-#define BT848_COLOR_FMT_YCrCb422 0x88
-#define BT848_COLOR_FMT_YCrCb411 0x99
-#define BT848_COLOR_FMT_RAW 0xee
-
-#define BT848_COLOR_CTL 0x0D8
-#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7)
-#define BT848_COLOR_CTL_COLOR_BARS (1<<6)
-#define BT848_COLOR_CTL_RGB_DED (1<<5)
-#define BT848_COLOR_CTL_GAMMA (1<<4)
-#define BT848_COLOR_CTL_WSWAP_ODD (1<<3)
-#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2)
-#define BT848_COLOR_CTL_BSWAP_ODD (1<<1)
-#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0)
-
-#define BT848_CAP_CTL 0x0DC
-#define BT848_CAP_CTL_DITH_FRAME (1<<4)
-#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
-#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
-#define BT848_CAP_CTL_CAPTURE_ODD (1<<1)
-#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0)
-
-#define BT848_VBI_PACK_SIZE 0x0E0
-
-#define BT848_VBI_PACK_DEL 0x0E4
-#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc
-#define BT848_VBI_PACK_DEL_EXT_FRAME 2
-#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1
-
-
-#define BT848_INT_STAT 0x100
-#define BT848_INT_MASK 0x104
-
-#define BT848_INT_ETBF (1<<23)
-
-#define BT848_INT_RISCS (0xf<<28)
-#define BT848_INT_RISC_EN (1<<27)
-#define BT848_INT_RACK (1<<25)
-#define BT848_INT_FIELD (1<<24)
-#define BT848_INT_SCERR (1<<19)
-#define BT848_INT_OCERR (1<<18)
-#define BT848_INT_PABORT (1<<17)
-#define BT848_INT_RIPERR (1<<16)
-#define BT848_INT_PPERR (1<<15)
-#define BT848_INT_FDSR (1<<14)
-#define BT848_INT_FTRGT (1<<13)
-#define BT848_INT_FBUS (1<<12)
-#define BT848_INT_RISCI (1<<11)
-#define BT848_INT_GPINT (1<<9)
-#define BT848_INT_I2CDONE (1<<8)
-#define BT848_INT_VPRES (1<<5)
-#define BT848_INT_HLOCK (1<<4)
-#define BT848_INT_OFLOW (1<<3)
-#define BT848_INT_HSYNC (1<<2)
-#define BT848_INT_VSYNC (1<<1)
-#define BT848_INT_FMTCHG (1<<0)
-
-
-#define BT848_GPIO_DMA_CTL 0x10C
-#define BT848_GPIO_DMA_CTL_GPINTC (1<<15)
-#define BT848_GPIO_DMA_CTL_GPINTI (1<<14)
-#define BT848_GPIO_DMA_CTL_GPWEC (1<<13)
-#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11)
-#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10)
-#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6)
-#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6)
-#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6)
-#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6)
-#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4)
-#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4)
-#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4)
-#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4)
-#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2)
-#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2)
-#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2)
-#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2)
-#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1)
-#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0)
-
-#define BT848_I2C 0x110
-#define BT848_I2C_DIV (0xf<<4)
-#define BT848_I2C_SYNC (1<<3)
-#define BT848_I2C_W3B (1<<2)
-#define BT848_I2C_SCL (1<<1)
-#define BT848_I2C_SDA (1<<0)
-
-
-#define BT848_RISC_STRT_ADD 0x114
-#define BT848_GPIO_OUT_EN 0x118
-#define BT848_GPIO_REG_INP 0x11C
-#define BT848_RISC_COUNT 0x120
-#define BT848_GPIO_DATA 0x200
-
-
-/* Bt848 RISC commands */
-
-/* only for the SYNC RISC command */
-#define BT848_FIFO_STATUS_FM1 0x06
-#define BT848_FIFO_STATUS_FM3 0x0e
-#define BT848_FIFO_STATUS_SOL 0x02
-#define BT848_FIFO_STATUS_EOL4 0x01
-#define BT848_FIFO_STATUS_EOL3 0x0d
-#define BT848_FIFO_STATUS_EOL2 0x09
-#define BT848_FIFO_STATUS_EOL1 0x05
-#define BT848_FIFO_STATUS_VRE 0x04
-#define BT848_FIFO_STATUS_VRO 0x0c
-#define BT848_FIFO_STATUS_PXV 0x00
-
-#define BT848_RISC_RESYNC (1<<15)
-
-/* WRITE and SKIP */
-/* disable which bytes of each DWORD */
-#define BT848_RISC_BYTE0 (1<<12)
-#define BT848_RISC_BYTE1 (1<<13)
-#define BT848_RISC_BYTE2 (1<<14)
-#define BT848_RISC_BYTE3 (1<<15)
-#define BT848_RISC_BYTE_ALL (0x0f<<12)
-#define BT848_RISC_BYTE_NONE 0
-/* cause RISCI */
-#define BT848_RISC_IRQ (1<<24)
-/* RISC command is last one in this line */
-#define BT848_RISC_EOL (1<<26)
-/* RISC command is first one in this line */
-#define BT848_RISC_SOL (1<<27)
-
-#define BT848_RISC_WRITE (0x01<<28)
-#define BT848_RISC_SKIP (0x02<<28)
-#define BT848_RISC_WRITEC (0x05<<28)
-#define BT848_RISC_JUMP (0x07<<28)
-#define BT848_RISC_SYNC (0x08<<28)
-
-#define BT848_RISC_WRITE123 (0x09<<28)
-#define BT848_RISC_SKIP123 (0x0a<<28)
-#define BT848_RISC_WRITE1S23 (0x0b<<28)
-
-
-
-/* Bt848A and higher only !! */
-#define BT848_TGLB 0x080
-#define BT848_TGCTRL 0x084
-#define BT848_FCAP 0x0E8
-#define BT848_PLL_F_LO 0x0F0
-#define BT848_PLL_F_HI 0x0F4
-
-#define BT848_PLL_XCI 0x0F8
-#define BT848_PLL_X (1<<7)
-#define BT848_PLL_C (1<<6)
-
-/* Bt878 register */
-
-#define BT878_DEVCTRL 0x40
-#define BT878_EN_TBFX 0x02
-
-#endif
diff --git a/drivers/char/bttv-cards.c b/drivers/char/bttv-cards.c
deleted file mode 100644
index b2c26e35b..000000000
--- a/drivers/char/bttv-cards.c
+++ /dev/null
@@ -1,835 +0,0 @@
-/*
- bttv-cards.c -- this file has card-specific stuff
-
-
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.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 of the License, 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.
-
-*/
-
-#define __NO_VERSION__ 1
-
-#include <linux/version.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-#include "bttv.h"
-#include "tuner.h"
-
-/* fwd decl */
-static void hauppauge_eeprom(struct bttv *btv);
-static void hauppauge_boot_msp34xx(struct bttv *btv);
-static void init_PXC200(struct bttv *btv);
-static void init_tea5757(struct bttv *btv);
-
-MODULE_PARM(card,"1-4i");
-MODULE_PARM(pll,"1-4i");
-MODULE_PARM(autoload,"i");
-
-static unsigned int card[4] = { -1, -1, -1, -1 };
-static unsigned int pll[4] = { -1, -1, -1, -1 };
-#ifdef MODULE
-static unsigned int autoload = 1;
-#else
-static unsigned int autoload = 0;
-#endif
-
-/* ----------------------------------------------------------------------- */
-/* list of card IDs for bt878+ cards */
-
-static struct CARD {
- unsigned id;
- int cardnr;
- char *name;
-} cards[] __devinitdata = {
- { 0x00011002, BTTV_HAUPPAUGE878, "ATI TV Wonder" },
- { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
- { 0x00021461, BTTV_AVERMEDIA98, "Avermedia TVCapture 98" },
- { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
- { 0x00041461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
- { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" },
- { 0x1118153b, BTTV_TERRATVALUE, "Terratec TV Value" },
- { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV/Radio+" },
- { 0x1200bd11, BTTV_PINNACLERAVE, "Pinnacle PCTV Rave" },
- { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" },
- { 0x18501851, BTTV_CHRONOS_VS2, "Chronos Video Shuttle II" },
- { 0x18521852, BTTV_TYPHOON_TVIEW, "Typhoon TView TV/FM Tuner" },
- { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0x263610b4, BTTV_STB2, "STB TV PCI FM, P/N 6000704" },
- { 0x3000144f, BTTV_MAGICTVIEW063, "TView 99 (CPH063)" },
- { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" },
- { 0x3002144f, BTTV_MAGICTVIEW061, "Askey Magic TView" },
- { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master" },
- { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
- { 0x402010fc, 0 /* no tvcards entry yet */, "I-O Data Co. GV-BCV3/PCI" },
-#if 0 /* probably wrong */
- { 0x14610002, BTTV_AVERMEDIA98, "Avermedia TVCapture 98" },
- { 0x6606217d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
-#endif
- { 0, -1, NULL }
-};
-
-/* ----------------------------------------------------------------------- */
-/* array with description for bt848 / bt878 tv/grabber cards */
-
-struct tvcard bttv_tvcards[] =
-{
- /* 0x00 */
- { " *** UNKNOWN *** ",
- 3, 1, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "MIRO PCTV",
- 4, 1, 0, 2,15, { 2, 3, 1, 1}, { 2, 0, 0, 0,10},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Hauppauge old",
- 4, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4},0,
- 1,1,0,1,0,0,0,1, PLL_NONE, -1 },
- { "STB",
- 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 4, 0, 2, 3, 1},0,
- 0,1,1,1,1,0,0,1, PLL_NONE, -1 },
-
- { "Intel",
- 3, 1, 0, -1, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Diamond DTV2000",
- 3, 1, 0, 2, 3, { 2, 3, 1, 1}, { 0, 1, 0, 1, 3},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "AVerMedia TVPhone",
- 3, 1, 0, 3,15, { 2, 3, 1, 1}, {12, 4,11,11, 0},0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
- { "MATRIX-Vision MV-Delta",
- 5, 1, -1, 3, 0, { 2, 3, 1, 0, 0},{0 }, 0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
-
- /* 0x08 */
- { "Fly Video II",
- 3, 1, 0, 2, 0xc00, { 2, 3, 1, 1},
- { 0, 0xc00, 0x800, 0x400, 0xc00, 0},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "TurboTV",
- 3, 1, 0, 2, 3, { 2, 3, 1, 1}, { 1, 1, 2, 3, 0},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Hauppauge new (bt878)",
- 4, 1, 0, 2, 7, { 2, 0, 1, 1}, { 0, 1, 2, 3, 4},0,
- 1,1,0,1,0,0,0,1, PLL_28, -1 },
- { "MIRO PCTV pro",
- 3, 1, 0, 2, 65551, { 2, 3, 1, 1}, {1,65537, 0, 0,10},0,
- /* 3, 1, 0, 2, 0x3004F, { 2, 3, 1, 1}, {1, 0x10011, 5, 0,10}, 0x3004F, */
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
-
- { "ADS Technologies Channel Surfer TV",
- 3, 1, 2, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "AVerMedia TVCapture 98",
- 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0},0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
- { "Aimslab VHX",
- 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Zoltrix TV-Max",
- 3, 1, 0, 2,15, { 2, 3, 1, 1}, {0 , 0, 1 , 0, 10},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
-
- /* 0x10 */
- { "Pixelview PlayTV (bt878)",
- 3, 1, 0, 2, 0x01fe00, { 2, 3, 1, 1},
- { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
- { "Leadtek WinView 601",
- 3, 1, 0, 2, 0x8300f8, { 2, 3, 1, 1,0},
- { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "AVEC Intercapture",
- 3, 2, 0, 2, 0, {2, 3, 1, 1}, {1, 0, 0, 0, 0},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "LifeView FlyKit w/o Tuner",
- 3, 1, -1, -1, 0x8dff00, { 2, 3, 1, 1}, { 0 },0,
- 0,0,0,0,0,0,0,1, PLL_NONE, -1 },
-
- { "CEI Raffles Card",
- 3, 3, 0, 2, 0, {2, 3, 1, 1}, {0, 0, 0, 0 ,0},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Lucky Star Image World ConferenceTV",
- 3, 1, 0, 2, 0x00fffe07, { 2, 3, 1, 1}, { 131072, 1, 1638400, 3, 4},0,
- 1,1,1,1,0,0,0,1, PLL_28, TUNER_PHILIPS_PAL_I },
- { "Phoebe Tv Master + FM",
- 3, 1, 0, 2, 0xc00, { 2, 3, 1, 1},{0, 1, 0x800, 0x400, 0xc00, 0},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Modular Technology MM205 PCTV, bt878",
- 2, 1, 0, -1, 7, { 2, 3 }, { 0, 0, 0, 0, 0 },0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
-
- /* 0x18 */
- { "Askey/Typhoon/Anubis Magic TView CPH051/061 (bt878)",
- 3, 1, 0, 2, 0xe00, { 2, 3, 1, 1}, {0x400, 0x400, 0x400, 0x400, 0},0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
- { "Terratec/Vobis TV-Boostar",
- 3, 1, 0, 2, 16777215 , { 2, 3, 1, 1}, { 131072, 1, 1638400, 3,4},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Newer Hauppauge WinCam (bt878)",
- 4, 1, 0, 3, 7, { 2, 0, 1, 1}, { 0, 1, 2, 3, 4},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "MAXI TV Video PCI2",
- 3, 1, 0, 2, 0xffff, { 2, 3, 1, 1}, { 0, 1, 2, 3, 0xc00},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, TUNER_PHILIPS_SECAM },
-
- { "Terratec TerraTV+",
- 3, 1, 0, 2, 0x70000, { 2, 3, 1, 1},
- { 0x20000, 0x30000, 0x00000, 0x10000, 0x40000},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Imagenation PXC200",
- 5, 1, -1, 4, 0, { 2, 3, 1, 0, 0}, { 0 }, 0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "FlyVideo 98",
- 3, 1, 0, 2, 0x8dff00, {2, 3, 1, 1},
- { 0, 0x8dff00, 0x8df700, 0x8de700, 0x8dff00, 0 },0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "iProTV",
- 3, 1, 0, 2, 1, { 2, 3, 1, 1}, { 1, 0, 0, 0, 0 },0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
-
- /* 0x20 */
- { "Intel Create and Share PCI",
- 4, 1, 0, 2, 7, { 2, 3, 1, 1}, { 4, 4, 4, 4, 4},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Terratec TerraTValue",
- 3, 1, 0, 2, 0xffff00, { 2, 3, 1, 1},
- { 0x500, 0, 0x300, 0x900, 0x900},0,
- 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
- { "Leadtek WinFast 2000",
- 3, 1, 0, 2, 0xfff000, { 2, 3, 1, 1,0},
- { 0x621000,0x6ddf07,0x621100,0x620000,0xE210000,0x620000},0,
- 1,1,1,1,1,0,0,1, PLL_28, -1 },
- { "Chronos Video Shuttle II",
- 3, 3, 0, 2, 0x1800, { 2, 3, 1, 1}, { 0, 0, 0x1000, 0x1000, 0x0800},0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
-
- { "Typhoon TView TV/FM Tuner",
- 3, 3, 0, 2, 0x1800, { 2, 3, 1, 1}, { 0, 0x800, 0, 0, 0x1800, 0 },0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
- { "PixelView PlayTV pro",
- 3, 1, 0, 2, 0xff, { 2, 3, 1, 1 },
- { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, 0,
- 0,0,0,0,0,0,0,1, PLL_28, -1 },
- { "TView99 CPH063",
- 3, 1, 0, 2, 0x551e00, { 2, 3, 1, 1},
- { 0x551400, 0x551200, 0, 0, 0, 0x551200 }, 0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
- { "Pinnacle PCTV Rave",
- 3, 1, 0, 2, 0x03000F, { 2, 3, 1, 1}, { 2, 0, 0, 0, 1},0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
-
- /* 0x28 */
- { "STB2",
- 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 4, 0, 2, 3, 1},0,
- 0,1,1,1,0,1,1,1, PLL_NONE, -1 },
- { "AVerMedia TVPhone 98",
- 3, 4, 0, 2, 4, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0},0,
- 1,1,1,1,0,0,0,1, PLL_28, 5 },
- { "ProVideo PV951", /* pic16c54 */
- 3, 1, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0},0,
- 0,0,0,0,0,0,0,0, PLL_28, 1 },
- { "Little OnAir TV",
- 3, 1, 0, 2, 0xe00b, {2, 3, 1, 1},
- {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},0,
- 0,0,0,0,0,0,0,0, PLL_NONE, -1 },
-
- { "Sigma TVII-FM",
- 2, 1, 0, -1, 3, {2, 3, 1, 1}, {1, 1, 0, 2, 3},0,
- 0,0,0,0,0,0,0,0, PLL_NONE, -1 },
- { "MATRIX-Vision MV-Delta 2",
- 5, 1, -1, 3, 0, { 2, 3, 1, 0, 0},{0 }, 0,
- 0,0,0,0,0,0,0,0, PLL_28, -1 },
- { "Zoltrix Genie TV",
- 3, 1, 0, 2, 0xbcf03f, { 2, 3, 1, 1},
- { 0xbc803f, 0, 0xbcb03f, 0, 0xbcb03f}, 0,
- 0,0,0,0,0,0,0,0, PLL_28, 5 },
- { "Terratec TV/Radio+", /* Radio ?? */
- 3, 1, 0, 2, 0x1f0000, { 2, 3, 1, 1},
- { 0xe2ffff, 0xebffff, 0, 0, 0xe0ffff, 0xe2ffff },0,
- 0,0,0,0,0,0,0,0, PLL_35, 1 },
-
- /* 0x30 */
- { "Dynalink Magic TView ",
- 3, 1, 0, 2, 15, { 2, 3, 1, 1}, {2,0,0,0,1},0,
- 1,1,1,1,0,0,0,1, PLL_28, -1 },
-};
-const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard));
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned char eeprom_data[256];
-
-static void __devinit bttv_dump_eeprom(struct bttv *btv,int addr)
-{
- int i;
-
- if (bttv_verbose < 2)
- return;
- /* for debugging: dump eeprom to syslog */
- printk(KERN_DEBUG "bttv%d: dump eeprom @ 0x%02x\n",btv->nr,addr);
- for (i = 0; i < 256;) {
- printk(KERN_DEBUG " %02x:",i);
- do {
- printk(" %02x",eeprom_data[i++]);
- } while (i % 16);
- printk("\n");
- }
-}
-
-static int __devinit bttv_idcard_eeprom(struct bttv *btv)
-{
- unsigned id;
- int i,n;
-
- id = (eeprom_data[252] << 24) |
- (eeprom_data[253] << 16) |
- (eeprom_data[254] << 8) |
- (eeprom_data[255]);
- if (id == 0 || id == 0xffffffff)
- return -1;
-
- /* look for the card */
- btv->cardid = id;
- for (n = -1, i = 0; cards[i].id != 0; i++)
- if (cards[i].id == id)
- n = i;
-
- if (n != -1) {
- /* found it */
- printk(KERN_INFO "bttv%d: card id: %s (0x%08x) => card=%d\n",
- btv->nr,cards[n].name,id,cards[n].cardnr);
- return cards[n].cardnr;
- } else {
- /* 404 */
- printk(KERN_INFO "bttv%d: id: unknown (0x%08x)\n",
- btv->nr, id);
- printk(KERN_INFO "please mail id, board name and "
- "the correct card= insmod option to "
- "kraxel@goldbach.in-berlin.de\n");
- return -1;
- }
-}
-
-#ifndef HAVE_TVAUDIO
-/* can tda9855.c handle this too maybe? */
-static void __devinit init_tda9840(struct bttv *btv)
-{
- /* Horrible Hack */
- bttv_I2CWrite(btv, I2C_TDA9840, TDA9840_SW, 0x2a, 1); /* sound mode switching */
- /* 00 - mute
- 10 - mono / averaged stereo
- 2a - stereo
- 12 - dual A
- 1a - dual AB
- 16 - dual BA
- 1e - dual B
- 7a - external */
-}
-#endif
-
-void __devinit bttv_idcard(struct bttv *btv)
-{
- int type,eeprom = 0;
-
- btwrite(0, BT848_GPIO_OUT_EN);
-
- /* try to autodetect the card */
- /* many bt878 cards have a eeprom @ 0xa0 => read ID
- and try to identify it */
- if (bttv_I2CRead(btv, I2C_HAUPEE, "eeprom") >= 0) {
- eeprom = 0xa0;
- bttv_readee(btv,eeprom_data,0xa0);
- bttv_dump_eeprom(btv,0xa0); /* DEBUG */
- type = bttv_idcard_eeprom(btv);
- if (-1 != type) {
- btv->type = type;
- } else if (btv->id <= 849) {
- /* for unknown bt848, assume old Hauppauge */
- btv->type=BTTV_HAUPPAUGE;
- }
-
- /* STB cards have a eeprom @ 0xae (old bt848) */
- } else if (bttv_I2CRead(btv, I2C_STBEE, "eeprom")>=0) {
- btv->type=BTTV_STB;
- }
-
- /* let the user override the autodetected type */
- if (card[btv->nr] >= 0 && card[btv->nr] < bttv_num_tvcards)
- btv->type=card[btv->nr];
-
- /* print which card config we are using */
- sprintf(btv->video_dev.name,"BT%d%s(%.23s)",
- btv->id,
- (btv->id==848 && btv->revision==0x12) ? "A" : "",
- bttv_tvcards[btv->type].name);
- printk(KERN_INFO "bttv%d: model: %s [%s]\n",btv->nr,btv->video_dev.name,
- (card[btv->nr] >= 0 && card[btv->nr] < bttv_num_tvcards) ?
- "insmod option" : "autodetected");
-
- /* board specific initialisations */
- if (btv->type == BTTV_MIRO || btv->type == BTTV_MIROPRO) {
- /* auto detect tuner for MIRO cards */
- btv->tuner_type=((btread(BT848_GPIO_DATA)>>10)-1)&7;
-#if 0
- if (btv->type == BTTV_MIROPRO) {
- if (bttv_verbose)
- printk(KERN_INFO "Initializing TEA5757...\n");
- init_tea5757(btv);
- }
-#endif
- }
- if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878) {
- /* pick up some config infos from the eeprom */
- if (0xa0 != eeprom) {
- eeprom = 0xa0;
- bttv_readee(btv,eeprom_data,0xa0);
- }
- hauppauge_eeprom(btv);
- hauppauge_boot_msp34xx(btv);
- }
- if (btv->type == BTTV_PXC200)
- init_PXC200(btv);
-
- /* pll configuration */
- if (!(btv->id==848 && btv->revision==0x11)) {
- /* defaults from card list */
- if (PLL_28 == bttv_tvcards[btv->type].pll) {
- btv->pll.pll_ifreq=28636363;
- btv->pll.pll_crystal=BT848_IFORM_XT0;
- }
- /* insmod options can override */
- switch (pll[btv->nr]) {
- case 0: /* none */
- btv->pll.pll_crystal = 0;
- btv->pll.pll_ifreq = 0;
- btv->pll.pll_ofreq = 0;
- break;
- case 1: /* 28 MHz */
- btv->pll.pll_ifreq = 28636363;
- btv->pll.pll_ofreq = 0;
- btv->pll.pll_crystal=BT848_IFORM_XT0;
- break;
- case 2: /* 35 MHz */
- btv->pll.pll_ifreq = 35468950;
- btv->pll.pll_ofreq = 0;
- btv->pll.pll_crystal=BT848_IFORM_XT1;
- break;
- }
- }
-
-
- /* tuner configuration */
- if (-1 != bttv_tvcards[btv->type].tuner_type)
- btv->tuner_type = bttv_tvcards[btv->type].tuner_type;
- if (btv->tuner_type != -1)
- bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
-
- /* try to detect audio/fader chips */
- if (bttv_tvcards[btv->type].msp34xx &&
- bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) {
- if (autoload)
- request_module("msp3400");
- }
-
-#ifndef HAVE_TVAUDIO
- if (bttv_tvcards[btv->type].tda8425 &&
- bttv_I2CRead(btv, I2C_TDA8425, "TDA8425") >=0) {
- if (autoload)
- request_module("tda8425");
- }
-
- if (bttv_tvcards[btv->type].tda9840 &&
- bttv_I2CRead(btv, I2C_TDA9840, "TDA9840") >=0) {
- init_tda9840(btv);
- btv->audio_chip = TDA9840;
- /* move this to a module too? */
- init_tda9840(btv);
- }
-
- if (bttv_tvcards[btv->type].tda985x &&
- bttv_I2CRead(btv, I2C_TDA9850, "TDA985x") >=0) {
- if (autoload)
- request_module("tda985x");
- }
- if (bttv_tvcards[btv->type].tea63xx) {
- if (autoload)
- request_module("tea6300");
- }
-#else
- if (bttv_tvcards[btv->type].tda8425 ||
- bttv_tvcards[btv->type].tda9840 ||
- bttv_tvcards[btv->type].tda985x ||
- bttv_tvcards[btv->type].tea63xx) {
- if (autoload)
- request_module("tvaudio");
- }
-#endif
-
- if (bttv_tvcards[btv->type].tda9875 &&
- bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) {
- if (autoload)
- request_module("tda9875");
- }
-
- if (bttv_tvcards[btv->type].tda7432 &&
- bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) {
- if (autoload)
- request_module("tda7432");
- }
-
-
- if (bttv_tvcards[btv->type].tea64xx) {
- if (autoload)
- request_module("tea6420");
- }
-
- if (bttv_tvcards[btv->type].tuner != -1) {
- if (autoload)
- request_module("tuner");
- }
-}
-
-
-/* ----------------------------------------------------------------------- */
-/* some hauppauge specific stuff */
-
-static struct HAUPPAUGE_TUNER
-{
- int id;
- char *name;
-}
-hauppauge_tuner[] __devinitdata =
-{
- { TUNER_ABSENT, "" },
- { TUNER_ABSENT, "External" },
- { TUNER_ABSENT, "Unspecified" },
- { TUNER_ABSENT, "Philips FI1216" },
- { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
- { TUNER_PHILIPS_NTSC, "Philips FI1236" },
- { TUNER_ABSENT, "Philips FI1246" },
- { TUNER_ABSENT, "Philips FI1256" },
- { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" },
- { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
- { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" },
- { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
- { TUNER_ABSENT, "Philips FI1256 MK2" },
- { TUNER_ABSENT, "Temic 4032FY5" },
- { TUNER_TEMIC_PAL, "Temic 4002FH5" },
- { TUNER_TEMIC_PAL_I, "Temic 4062FY5" },
- { TUNER_ABSENT, "Philips FR1216 MK2" },
- { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
- { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" },
- { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
- { TUNER_ABSENT, "Philips FR1256 MK2" },
- { TUNER_PHILIPS_PAL, "Philips FM1216" },
- { TUNER_ABSENT, "Philips FM1216MF" },
- { TUNER_PHILIPS_NTSC, "Philips FM1236" },
- { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
- { TUNER_ABSENT, "Philips FM1256" },
- { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
- { TUNER_ABSENT, "Samsung TCPN9082D" },
- { TUNER_ABSENT, "Samsung TCPM9092P" },
- { TUNER_TEMIC_PAL, "Temic 4006FH5" },
- { TUNER_ABSENT, "Samsung TCPN9085D" },
- { TUNER_ABSENT, "Samsung TCPB9085P" },
- { TUNER_ABSENT, "Samsung TCPL9091P" },
- { TUNER_ABSENT, "Temic 4039FR5" },
- { TUNER_ABSENT, "Philips FQ1216 ME" },
- { TUNER_TEMIC_PAL_I, "Temic 4066FY5" },
- { TUNER_ABSENT, "Philips TD1536" },
- { TUNER_ABSENT, "Philips TD1536D" },
- { TUNER_ABSENT, "Philips FMR1236" },
- { TUNER_ABSENT, "Philips FI1256MP" },
- { TUNER_ABSENT, "Samsung TCPQ9091P" },
- { TUNER_ABSENT, "Temic 4006FN5" },
- { TUNER_ABSENT, "Temic 4009FR5" },
- { TUNER_ABSENT, "Temic 4046FM5" },
-};
-
-static void __devinit hauppauge_eeprom(struct bttv *btv)
-{
- if (eeprom_data[9] < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER))
- {
- btv->tuner_type = hauppauge_tuner[eeprom_data[9]].id;
- if (bttv_verbose)
- printk("bttv%d: Hauppauge eeprom: tuner=%s (%d)\n",btv->nr,
- hauppauge_tuner[eeprom_data[9]].name,btv->tuner_type);
- }
-}
-
-static void __devinit hauppauge_boot_msp34xx(struct bttv *btv)
-{
- int i;
-
- /* reset/enable the MSP on some Hauppauge cards */
- /* Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! */
- btaor(32, ~32, BT848_GPIO_OUT_EN);
- btaor(0, ~32, BT848_GPIO_DATA);
- udelay(2500);
- btaor(32, ~32, BT848_GPIO_DATA);
-
- if (bttv_verbose)
- printk("bttv%d: Hauppauge msp34xx: reset line init\n",btv->nr);
-
- /* look if the msp3400 driver is already registered */
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- if (btv->i2c_clients[i] != NULL &&
- btv->i2c_clients[i]->driver->id == I2C_DRIVERID_MSP3400) {
- return;
- }
- }
-
- /* if not: look for the chip ... */
- if (bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx")) {
- /* ... if found re-register to trigger a i2c bus rescan, */
- /* this time with the msp34xx chip activated */
- i2c_bit_del_bus(&btv->i2c_adap);
- i2c_bit_add_bus(&btv->i2c_adap);
- }
-}
-
-
-/* ----------------------------------------------------------------------- */
-/* Imagenation L-Model PXC200 Framegrabber */
-/* This is basically the same procedure as
- * used by Alessandro Rubini in his pxc200
- * driver, but using BTTV functions */
-
-static void __devinit init_PXC200(struct bttv *btv)
-{
- static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x00 };
- int i,tmp;
-
- /* Initialise GPIO-connevted stuff */
- btwrite(1<<13,BT848_GPIO_OUT_EN); /* Reset pin only */
- btwrite(0,BT848_GPIO_DATA);
- udelay(3);
- btwrite(1<<13,BT848_GPIO_DATA);
- /* GPIO inputs are pulled up, so no need to drive
- * reset pin any longer */
- btwrite(0,BT848_GPIO_OUT_EN);
-
- /* we could/should try and reset/control the AD pots? but
- right now we simply turned off the crushing. Without
- this the AGC drifts drifts
- remember the EN is reverse logic -->
- setting BT848_ADC_AGC_EN disable the AGC
- tboult@eecs.lehigh.edu
- */
- btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC);
-
- /* Initialise MAX517 DAC */
- printk(KERN_INFO "Setting DAC reference voltage level ...\n");
- bttv_I2CWrite(btv,0x5E,0,0x80,1);
-
- /* Initialise 12C508 PIC */
- /* The I2CWrite and I2CRead commmands are actually to the
- * same chips - but the R/W bit is included in the address
- * argument so the numbers are different */
-
- printk(KERN_INFO "Initialising 12C508 PIC chip ...\n");
-
- for (i = 0; i < sizeof(vals)/sizeof(int); i++) {
- tmp=bttv_I2CWrite(btv,0x1E,vals[i],0,1);
- printk(KERN_INFO "I2C Write(0x08) = %i\nI2C Read () = %x\n\n",
- tmp,bttv_I2CRead(btv,0x1F,NULL));
- }
- printk(KERN_INFO "PXC200 Initialised.\n");
-}
-
-/* ----------------------------------------------------------------------- */
-/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
-/*
- * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu>
- * This code is placed under the terms of the GNU General Public License
- *
- * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
- */
-
-/* bus bits on the GPIO port */
-#define TEA_WE 6
-#define TEA_DATA 9
-#define TEA_CLK 8
-#define TEA_MOST 7
-
-#define BUS_LOW(bit) btand(~(1<<TEA_##bit), BT848_GPIO_DATA)
-#define BUS_HIGH(bit) btor((1<<TEA_##bit), BT848_GPIO_DATA)
-#define BUS_IN(bit) ((btread(BT848_GPIO_DATA) >> TEA_##bit) & 1)
-
-/* TEA5757 register bits */
-#define TEA_FREQ 0:14
-#define TEA_BUFFER 15:15
-
-#define TEA_SIGNAL_STRENGTH 16:17
-
-#define TEA_PORT1 18:18
-#define TEA_PORT0 19:19
-
-#define TEA_BAND 20:21
-#define TEA_BAND_FM 0
-#define TEA_BAND_MW 1
-#define TEA_BAND_LW 2
-#define TEA_BAND_SW 3
-
-#define TEA_MONO 22:22
-#define TEA_ALLOW_STEREO 0
-#define TEA_FORCE_MONO 1
-
-#define TEA_SEARCH_DIRECTION 23:23
-#define TEA_SEARCH_DOWN 0
-#define TEA_SEARCH_UP 1
-
-#define TEA_STATUS 24:24
-#define TEA_STATUS_TUNED 0
-#define TEA_STATUS_SEARCHING 1
-
-/* Low-level stuff */
-static int tea_read(struct bttv *btv)
-{
- int value = 0;
- long timeout;
- int i;
-
- /* better safe than sorry */
- btaor((1<<TEA_CLK) | (1<<TEA_WE), ~((1<<TEA_CLK) | (1<<TEA_DATA) | (1<<TEA_WE) | (1<<TEA_MOST)), BT848_GPIO_OUT_EN);
-
- BUS_LOW(WE);
- BUS_LOW(CLK);
-
- udelay(10);
- for(timeout = jiffies + 10 * HZ;
- BUS_IN(DATA) == 1 && time_before(jiffies, timeout);
- schedule()); /* 10 s */
- if (BUS_IN(DATA) == 1) {
- printk("tea5757: read timeout\n");
- return -1;
- }
- for(timeout = jiffies + HZ/5;
- BUS_IN(MOST) == 1 && time_before(jiffies, timeout);
- schedule()); /* 0.2 s */
- if (bttv_debug) printk("tea5757:");
- for(i = 0; i < 24; i++)
- {
- udelay(10);
- BUS_HIGH(CLK);
- udelay(10);
- if (bttv_debug) printk("%c", (BUS_IN(MOST) == 0)?'T':'-');
- BUS_LOW(CLK);
- value <<= 1;
- value |= (BUS_IN(DATA) == 0)?0:1; /* MSB first */
- if (bttv_debug) printk("%c", (BUS_IN(MOST) == 0)?'S':'M');
- }
- if (bttv_debug) printk("\ntea5757: read 0x%X\n", value);
- return value;
-}
-
-static int tea_write(struct bttv *btv, int value)
-{
- int i;
- int reg = value;
-
- btaor((1<<TEA_CLK) | (1<<TEA_WE) | (1<<TEA_DATA), ~((1<<TEA_CLK) | (1<<TEA_DATA) | (1<<TEA_WE) | (1<<TEA_MOST)), BT848_GPIO_OUT_EN);
- if (bttv_debug) printk("tea5757: write 0x%X\n", value);
- BUS_LOW(CLK);
- BUS_HIGH(WE);
- for(i = 0; i < 25; i++)
- {
- if (reg & 0x1000000)
- BUS_HIGH(DATA);
- else
- BUS_LOW(DATA);
- reg <<= 1;
- BUS_HIGH(CLK);
- udelay(10);
- BUS_LOW(CLK);
- udelay(10);
- }
- BUS_LOW(WE); /* unmute !!! */
- return 0;
-}
-
-void tea5757_set_freq(struct bttv *btv, unsigned short freq)
-{
- tea_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
- if (bttv_debug) tea_read(btv);
-}
-
-void init_tea5757(struct bttv *btv)
-{
- BUS_LOW(CLK);
- BUS_LOW(WE); /* just to be on the safe side... */
-
- /* software CLK (unused) */
- btaor(0, BT848_GPIO_DMA_CTL_GPCLKMODE, BT848_GPIO_DMA_CTL);
- /* normal mode for GPIO */
- btaor(0, BT848_GPIO_DMA_CTL_GPIOMODE, BT848_GPIO_DMA_CTL);
-}
-
-/* ----------------------------------------------------------------------- */
-/* winview */
-
-void winview_setvol(struct bttv *btv, struct video_audio *v)
-{
- /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
- int bits_out, loops, vol, data;
-
- /* 32 levels logarithmic */
- vol = 32 - ((v->volume>>11));
- /* units */
- bits_out = (PT2254_DBS_IN_2>>(vol%5));
- /* tens */
- bits_out |= (PT2254_DBS_IN_10>>(vol/5));
- bits_out |= PT2254_L_CHANEL | PT2254_R_CHANEL;
- data = btread(BT848_GPIO_DATA);
- data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
- WINVIEW_PT2254_STROBE);
- for (loops = 17; loops >= 0 ; loops--) {
- if (bits_out & (1<<loops))
- data |= WINVIEW_PT2254_DATA;
- else
- data &= ~WINVIEW_PT2254_DATA;
- btwrite(data, BT848_GPIO_DATA);
- udelay(5);
- data |= WINVIEW_PT2254_CLK;
- btwrite(data, BT848_GPIO_DATA);
- udelay(5);
- data &= ~WINVIEW_PT2254_CLK;
- btwrite(data, BT848_GPIO_DATA);
- }
- data |= WINVIEW_PT2254_STROBE;
- data &= ~WINVIEW_PT2254_DATA;
- btwrite(data, BT848_GPIO_DATA);
- udelay(10);
- data &= ~WINVIEW_PT2254_STROBE;
- btwrite(data, BT848_GPIO_DATA);
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/bttv-driver.c b/drivers/char/bttv-driver.c
deleted file mode 100644
index 6c88a757e..000000000
--- a/drivers/char/bttv-driver.c
+++ /dev/null
@@ -1,3272 +0,0 @@
-/*
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.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 of the License, 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.
-*/
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <linux/ioport.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <asm/segment.h>
-#include <linux/types.h>
-#include <linux/wrapper.h>
-#include <linux/interrupt.h>
-#include <linux/kmod.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#ifdef HACKING
-# include <linux/iobuf.h>
-#endif
-
-#include "bttv.h"
-#include "tuner.h"
-
-#define DEBUG(x) /* Debug driver */
-#define IDEBUG(x) /* Debug interrupt handler */
-#define MIN(a,b) (((a)>(b))?(b):(a))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-
-static void bt848_set_risc_jmps(struct bttv *btv, int state);
-
-int bttv_num; /* number of Bt848s in use */
-struct bttv bttvs[BTTV_MAX];
-
-
-/* insmod args */
-MODULE_PARM(triton1,"i");
-MODULE_PARM(radio,"1-4i");
-MODULE_PARM(bigendian,"i");
-MODULE_PARM(fieldnr,"i");
-MODULE_PARM(bttv_verbose,"i");
-MODULE_PARM(bttv_debug,"i");
-MODULE_PARM(gbuffers,"i");
-MODULE_PARM(gbufsize,"i");
-
-MODULE_DESCRIPTION("bttv - v4l driver module for bt848/878 based cards");
-MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
-
-#if defined(__sparc__) || defined(__powerpc__)
-static unsigned int bigendian=1;
-#else
-static unsigned int bigendian=0;
-#endif
-static int triton1=0;
-static unsigned int radio[BTTV_MAX];
-static unsigned int fieldnr = 0;
-static unsigned int gbuffers = 2;
-static unsigned int gbufsize = BTTV_MAX_FBUF;
-unsigned int bttv_debug = 0;
-unsigned int bttv_verbose = 1;
-
-#define I2C_TIMING (0x7<<4)
-#define I2C_DELAY 10
-
-#define I2C_SET(CTRL,DATA) \
- { btwrite((CTRL<<1)|(DATA), BT848_I2C); udelay(I2C_DELAY); }
-#define I2C_GET() (btread(BT848_I2C)&1)
-
-#define BURSTOFFSET 76
-#define BTTV_ERRORS 5
-
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-#define MDEBUG(x) do { } while(0) /* Debug memory management */
-
-/* [DaveM] I've recoded most of this so that:
- * 1) It's easier to tell what is happening
- * 2) It's more portable, especially for translating things
- * out of vmalloc mapped areas in the kernel.
- * 3) Less unnecessary translations happen.
- *
- * The code used to assume that the kernel vmalloc mappings
- * existed in the page tables of every process, this is simply
- * not guarenteed. We now use pgd_offset_k which is the
- * defined way to get at the kernel page tables.
- */
-
-/* Given PGD from the address space's page table, return the kernel
- * virtual mapping of the physical memory mapped at ADR.
- */
-static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
-{
- unsigned long ret = 0UL;
- pmd_t *pmd;
- pte_t *ptep, pte;
-
- if (!pgd_none(*pgd)) {
- pmd = pmd_offset(pgd, adr);
- if (!pmd_none(*pmd)) {
- ptep = pte_offset(pmd, adr);
- pte = *ptep;
- if(pte_present(pte)) {
- ret = (unsigned long) page_address(pte_page(pte));
- ret |= (adr & (PAGE_SIZE - 1));
- }
- }
- }
- MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
- return ret;
-}
-
-static inline unsigned long uvirt_to_bus(unsigned long adr)
-{
- unsigned long kva, ret;
-
- kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
- ret = virt_to_bus((void *)kva);
- MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
- return ret;
-}
-
-static inline unsigned long kvirt_to_bus(unsigned long adr)
-{
- unsigned long va, kva, ret;
-
- va = VMALLOC_VMADDR(adr);
- kva = uvirt_to_kva(pgd_offset_k(va), va);
- ret = virt_to_bus((void *)kva);
- MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
- return ret;
-}
-
-/* Here we want the physical address of the memory.
- * This is used when initializing the contents of the
- * area and marking the pages as reserved.
- */
-static inline unsigned long kvirt_to_pa(unsigned long adr)
-{
- unsigned long va, kva, ret;
-
- va = VMALLOC_VMADDR(adr);
- kva = uvirt_to_kva(pgd_offset_k(va), va);
- ret = __pa(kva);
- MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
- return ret;
-}
-
-static void * rvmalloc(signed long size)
-{
- void * mem;
- unsigned long adr, page;
-
- mem=vmalloc_32(size);
- if (mem)
- {
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
- adr=(unsigned long) mem;
- while (size > 0)
- {
- page = kvirt_to_pa(adr);
- mem_map_reserve(virt_to_page(__va(page)));
- adr+=PAGE_SIZE;
- size-=PAGE_SIZE;
- }
- }
- return mem;
-}
-
-static void rvfree(void * mem, signed long size)
-{
- unsigned long adr, page;
-
- if (mem)
- {
- adr=(unsigned long) mem;
- while (size > 0)
- {
- page = kvirt_to_pa(adr);
- mem_map_unreserve(virt_to_page(__va(page)));
- adr+=PAGE_SIZE;
- size-=PAGE_SIZE;
- }
- vfree(mem);
- }
-}
-
-
-
-/*
- * Create the giant waste of buffer space we need for now
- * until we get DMA to user space sorted out (probably 2.3.x)
- *
- * We only create this as and when someone uses mmap
- */
-
-static int fbuffer_alloc(struct bttv *btv)
-{
- if(!btv->fbuffer)
- btv->fbuffer=(unsigned char *) rvmalloc(gbuffers*gbufsize);
- else
- printk(KERN_ERR "bttv%d: Double alloc of fbuffer!\n",
- btv->nr);
- if(!btv->fbuffer)
- return -ENOBUFS;
- return 0;
-}
-
-
-static int __devinit init_bttv_i2c(struct bttv *btv)
-{
- /* i2c bit_adapter */
- memcpy(&btv->i2c_adap, &bttv_i2c_adap_template, sizeof(struct i2c_adapter));
- memcpy(&btv->i2c_algo, &bttv_i2c_algo_template, sizeof(struct i2c_algo_bit_data));
- memcpy(&btv->i2c_client, &bttv_i2c_client_template, sizeof(struct i2c_client));
-
- sprintf(btv->i2c_adap.name+strlen(btv->i2c_adap.name),
- " #%d", btv->nr);
- btv->i2c_algo.data = btv;
- btv->i2c_adap.data = btv;
- btv->i2c_adap.algo_data = &btv->i2c_algo;
- btv->i2c_client.adapter = &btv->i2c_adap;
-
- bttv_bit_setscl(btv,1);
- bttv_bit_setsda(btv,1);
-
- btv->i2c_ok = i2c_bit_add_bus(&btv->i2c_adap);
- return btv->i2c_ok;
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-static void audio(struct bttv *btv, int mode, int no_irq_context)
-{
- btaor(bttv_tvcards[btv->type].gpiomask, ~bttv_tvcards[btv->type].gpiomask,
- BT848_GPIO_OUT_EN);
-
- switch (mode)
- {
- case AUDIO_MUTE:
- btv->audio|=AUDIO_MUTE;
- break;
- case AUDIO_UNMUTE:
- btv->audio&=~AUDIO_MUTE;
- mode=btv->audio;
- break;
- case AUDIO_OFF:
- mode=AUDIO_OFF;
- break;
- case AUDIO_ON:
- mode=btv->audio;
- break;
- default:
- btv->audio&=AUDIO_MUTE;
- btv->audio|=mode;
- break;
- }
- /* if audio mute or not in H-lock, turn audio off */
- if ((btv->audio&AUDIO_MUTE))
- mode=AUDIO_OFF;
- if ((mode == AUDIO_TUNER) && (btv->radio))
- mode = AUDIO_RADIO;
- btaor(bttv_tvcards[btv->type].audiomux[mode],
- ~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
- if (no_irq_context)
- bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(mode));
-}
-
-
-extern inline void bt848_dma(struct bttv *btv, uint state)
-{
- if (state)
- btor(3, BT848_GPIO_DMA_CTL);
- else
- btand(~3, BT848_GPIO_DMA_CTL);
-}
-
-
-/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC*/
-
-/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C
- PLL_X = Reference pre-divider (0=1, 1=2)
- PLL_C = Post divider (0=6, 1=4)
- PLL_I = Integer input
- PLL_F = Fractional input
-
- F_input = 28.636363 MHz:
- PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
-*/
-
-static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
-{
- unsigned char fl, fh, fi;
-
- /* prevent overflows */
- fin/=4;
- fout/=4;
-
- fout*=12;
- fi=fout/fin;
-
- fout=(fout%fin)*256;
- fh=fout/fin;
-
- fout=(fout%fin)*256;
- fl=fout/fin;
-
- /*printk("0x%02x 0x%02x 0x%02x\n", fi, fh, fl);*/
- btwrite(fl, BT848_PLL_F_LO);
- btwrite(fh, BT848_PLL_F_HI);
- btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
-}
-
-static int set_pll(struct bttv *btv)
-{
- int i;
- unsigned long tv;
-
- if (!btv->pll.pll_crystal)
- return 0;
-
- if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
- /* no PLL needed */
- if (btv->pll.pll_current == 0) {
- /* printk ("bttv%d: PLL: is off\n",btv->nr); */
- return 0;
- }
- printk ("bttv%d: PLL: switching off\n",btv->nr);
- btwrite(0x00,BT848_TGCTRL);
- btwrite(0x00,BT848_PLL_XCI);
- btv->pll.pll_current = 0;
- return 0;
- }
-
- if (btv->pll.pll_ofreq == btv->pll.pll_current) {
- /* printk("bttv%d: PLL: no change required\n",btv->nr); */
- return 1;
- }
-
- if (bttv_verbose)
- printk("bttv%d: PLL: %d => %d ... ",btv->nr,
- btv->pll.pll_ifreq, btv->pll.pll_ofreq);
-
- set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
-
- /* Let other people run while the PLL stabilizes */
- tv=jiffies+HZ/10; /* .1 seconds */
- do
- {
- schedule();
- }
- while(time_before(jiffies,tv));
-
- for (i=0; i<100; i++)
- {
- if ((btread(BT848_DSTATUS)&BT848_DSTATUS_PLOCK))
- btwrite(0,BT848_DSTATUS);
- else
- {
- btwrite(0x08,BT848_TGCTRL);
- btv->pll.pll_current = btv->pll.pll_ofreq;
- if (bttv_verbose)
- printk("ok\n");
- return 1;
- }
- mdelay(10);
- }
- btv->pll.pll_current = 0;
- if (bttv_verbose)
- printk("oops\n");
- return -1;
-}
-
-static void bt848_muxsel(struct bttv *btv, unsigned int input)
-{
- btaor(bttv_tvcards[btv->type].gpiomask2,~bttv_tvcards[btv->type].gpiomask2,
- BT848_GPIO_OUT_EN);
-
- /* This seems to get rid of some synchronization problems */
- btand(~(3<<5), BT848_IFORM);
- mdelay(10);
-
-
- input %= bttv_tvcards[btv->type].video_inputs;
- if (input==bttv_tvcards[btv->type].svhs)
- {
- btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
- btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
- }
- else
- {
- btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
- btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
- }
- btaor((bttv_tvcards[btv->type].muxsel[input&7]&3)<<5, ~(3<<5), BT848_IFORM);
- audio(btv, (input!=bttv_tvcards[btv->type].tuner) ?
- AUDIO_EXTERN : AUDIO_TUNER, 1);
- btaor(bttv_tvcards[btv->type].muxsel[input]>>4,
- ~bttv_tvcards[btv->type].gpiomask2, BT848_GPIO_DATA);
-}
-
-
-struct tvnorm
-{
- u32 Fsc;
- u16 swidth, sheight; /* scaled standard width, height */
- u16 totalwidth;
- u8 adelay, bdelay, iform;
- u32 scaledtwidth;
- u16 hdelayx1, hactivex1;
- u16 vdelay;
- u8 vbipack;
-};
-
-static struct tvnorm tvnorms[] = {
- /* PAL-BDGHI */
- /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
- /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
- { 35468950,
- 924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
- 1135, 186, 924, 0x20, 255},
-
- /* NTSC */
- { 28636363,
- 768, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
- 910, 128, 910, 0x1a, 144},
-#if 0
- /* SECAM EAST */
- { 35468950,
- 768, 576, 1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
- 944, 186, 922, 0x20, 255},
-#else
- /* SECAM L */
- { 35468950,
- 924, 576, 1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
- 1135, 186, 922, 0x20, 255},
-#endif
- /* PAL-NC */
- { 28636363,
- 640, 576, 910, 0x68, 0x5d, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
- 780, 130, 734, 0x1a, 144},
- /* PAL-M */
- { 28636363,
- 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
- 780, 135, 754, 0x1a, 144},
- /* PAL-N */
- { 35468950,
- 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
- 944, 186, 922, 0x20, 144},
- /* NTSC-Japan */
- { 28636363,
- 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
- 780, 135, 754, 0x16, 144},
-};
-#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
-#define VBI_SPL 2044
-
-/* RISC command to write one VBI data line */
-#define VBI_RISC BT848_RISC_WRITE|VBI_SPL|BT848_RISC_EOL|BT848_RISC_SOL
-
-static void make_vbitab(struct bttv *btv)
-{
- int i;
- unsigned int *po=(unsigned int *) btv->vbi_odd;
- unsigned int *pe=(unsigned int *) btv->vbi_even;
-
- if (bttv_debug > 1)
- printk("bttv%d: vbi1: po=%08lx pe=%08lx\n",
- btv->nr,virt_to_bus(po), virt_to_bus(pe));
-
- *(po++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(po++)=0;
- for (i=0; i<16; i++)
- {
- *(po++)=cpu_to_le32(VBI_RISC);
- *(po++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
- }
- *(po++)=cpu_to_le32(BT848_RISC_JUMP);
- *(po++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
-
- *(pe++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(pe++)=0;
- for (i=16; i<32; i++)
- {
- *(pe++)=cpu_to_le32(VBI_RISC);
- *(pe++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
- }
- *(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16));
- *(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
-
- if (bttv_debug > 1)
- printk("bttv%d: vbi2: po=%08lx pe=%08lx\n",
- btv->nr,virt_to_bus(po), virt_to_bus(pe));
-}
-
-static int fmtbppx2[16] = {
- 8, 6, 4, 4, 4, 3, 2, 2, 4, 3, 0, 0, 0, 0, 2, 0
-};
-
-static int palette2fmt[] = {
- 0,
- BT848_COLOR_FMT_Y8,
- BT848_COLOR_FMT_RGB8,
- BT848_COLOR_FMT_RGB16,
- BT848_COLOR_FMT_RGB24,
- BT848_COLOR_FMT_RGB32,
- BT848_COLOR_FMT_RGB15,
- BT848_COLOR_FMT_YUY2,
- BT848_COLOR_FMT_BtYUV,
- -1,
- -1,
- -1,
- BT848_COLOR_FMT_RAW,
- BT848_COLOR_FMT_YCrCb422,
- BT848_COLOR_FMT_YCrCb411,
- BT848_COLOR_FMT_YCrCb422,
- BT848_COLOR_FMT_YCrCb411,
-};
-#define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))
-
-static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
- unsigned int *re, unsigned int *vbuf)
-{
- unsigned long line;
- unsigned long bpl=1024; /* bytes per line */
- unsigned long vadr=(unsigned long) vbuf;
-
- *(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(ro++)=cpu_to_le32(0);
- *(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(re++)=cpu_to_le32(0);
-
- /* In PAL 650 blocks of 256 DWORDs are sampled, but only if VDELAY
- is 2 and without separate VBI grabbing.
- We'll have to handle this inside the IRQ handler ... */
-
- for (line=0; line < 640; line++)
- {
- *(ro++)=cpu_to_le32(BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL);
- *(ro++)=cpu_to_le32(kvirt_to_bus(vadr));
- *(re++)=cpu_to_le32(BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL);
- *(re++)=cpu_to_le32(kvirt_to_bus(vadr+gbufsize/2));
- vadr+=bpl;
- }
-
- *(ro++)=cpu_to_le32(BT848_RISC_JUMP);
- *(ro++)=cpu_to_le32(btv->bus_vbi_even);
- *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
- *(re++)=cpu_to_le32(btv->bus_vbi_odd);
-
- return 0;
-}
-
-static int make_prisctab(struct bttv *btv, unsigned int *ro,
- unsigned int *re,
- unsigned int *vbuf, unsigned short width,
- unsigned short height, unsigned short fmt)
-{
- unsigned long line, lmask;
- unsigned long bl, blcr, blcb, rcmd;
- unsigned long todo;
- unsigned int **rp;
- int inter;
- unsigned long cbadr, cradr;
- unsigned long vadr=(unsigned long) vbuf;
- int shift, csize;
-
- if (bttv_debug > 1)
- printk("bttv%d: prisc1: ro=%08lx re=%08lx\n",
- btv->nr,virt_to_bus(ro), virt_to_bus(re));
-
- switch(fmt)
- {
- case VIDEO_PALETTE_YUV422P:
- csize=(width*height)>>1;
- shift=1;
- lmask=0;
- break;
-
- case VIDEO_PALETTE_YUV411P:
- csize=(width*height)>>2;
- shift=2;
- lmask=0;
- break;
-
- case VIDEO_PALETTE_YUV420P:
- csize=(width*height)>>2;
- shift=1;
- lmask=1;
- break;
-
- case VIDEO_PALETTE_YUV410P:
- csize=(width*height)>>4;
- shift=2;
- lmask=3;
- break;
-
- default:
- return -1;
- }
- cbadr=vadr+(width*height);
- cradr=cbadr+csize;
- inter = (height>tvnorms[btv->win.norm].sheight/2) ? 1 : 0;
-
- *(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
- *(ro++)=0;
- *(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
- *(re++)=0;
-
- for (line=0; line < (height<<(1^inter)); line++)
- {
- if(line==height)
- {
- vadr+=csize<<1;
- cbadr=vadr+(width*height);
- cradr=cbadr+csize;
- }
- if (inter)
- rp= (line&1) ? &re : &ro;
- else
- rp= (line>=height) ? &ro : &re;
-
-
- if(line&lmask)
- rcmd=BT848_RISC_WRITE1S23|BT848_RISC_SOL;
- else
- rcmd=BT848_RISC_WRITE123|BT848_RISC_SOL;
-
- todo=width;
- while(todo)
- {
- bl=PAGE_SIZE-((PAGE_SIZE-1)&vadr);
- blcr=(PAGE_SIZE-((PAGE_SIZE-1)&cradr))<<shift;
- blcb=(PAGE_SIZE-((PAGE_SIZE-1)&cbadr))<<shift;
- bl=(blcr<bl) ? blcr : bl;
- bl=(blcb<bl) ? blcb : bl;
- bl=(bl>todo) ? todo : bl;
- blcr=bl>>shift;
- blcb=blcr;
- /* bl now containts the longest row that can be written */
- todo-=bl;
- if(!todo) rcmd|=BT848_RISC_EOL; /* if this is the last EOL */
-
- *((*rp)++)=cpu_to_le32(rcmd|bl);
- *((*rp)++)=cpu_to_le32(blcb|(blcr<<16));
- *((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
- vadr+=bl;
- if((rcmd&(15<<28))==BT848_RISC_WRITE123)
- {
- *((*rp)++)=(kvirt_to_bus(cbadr));
- cbadr+=blcb;
- *((*rp)++)=cpu_to_le32(kvirt_to_bus(cradr));
- cradr+=blcr;
- }
-
- rcmd&=~BT848_RISC_SOL; /* only the first has SOL */
- }
- }
-
- *(ro++)=cpu_to_le32(BT848_RISC_JUMP);
- *(ro++)=cpu_to_le32(btv->bus_vbi_even);
- *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
- *(re++)=cpu_to_le32(btv->bus_vbi_odd);
-
- if (bttv_debug > 1)
- printk("bttv%d: prisc2: ro=%08lx re=%08lx\n",
- btv->nr,virt_to_bus(ro), virt_to_bus(re));
-
- return 0;
-}
-
-static int make_vrisctab(struct bttv *btv, unsigned int *ro,
- unsigned int *re,
- unsigned int *vbuf, unsigned short width,
- unsigned short height, unsigned short palette)
-{
- unsigned long line;
- unsigned long bpl; /* bytes per line */
- unsigned long bl;
- unsigned long todo;
- unsigned int **rp;
- int inter;
- unsigned long vadr=(unsigned long) vbuf;
-
- if (palette==VIDEO_PALETTE_RAW)
- return make_rawrisctab(btv, ro, re, vbuf);
- if (palette>=VIDEO_PALETTE_PLANAR)
- return make_prisctab(btv, ro, re, vbuf, width, height, palette);
-
- if (bttv_debug > 1)
- printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n",
- btv->nr,virt_to_bus(ro), virt_to_bus(re));
-
- inter = (height>tvnorms[btv->win.norm].sheight/2) ? 1 : 0;
- bpl=width*fmtbppx2[palette2fmt[palette]&0xf]/2;
-
- *(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(ro++)=cpu_to_le32(0);
- *(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(re++)=cpu_to_le32(0);
-
- for (line=0; line < (height<<(1^inter)); line++)
- {
- if (inter)
- rp= (line&1) ? &re : &ro;
- else
- rp= (line>=height) ? &ro : &re;
-
- bl=PAGE_SIZE-((PAGE_SIZE-1)&vadr);
- if (bpl<=bl)
- {
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
- BT848_RISC_EOL|bpl);
- *((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
- vadr+=bpl;
- }
- else
- {
- todo=bpl;
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|bl);
- *((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
- vadr+=bl;
- todo-=bl;
- while (todo>PAGE_SIZE)
- {
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|PAGE_SIZE);
- *((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
- vadr+=PAGE_SIZE;
- todo-=PAGE_SIZE;
- }
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|todo);
- *((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
- vadr+=todo;
- }
- }
-
- *(ro++)=cpu_to_le32(BT848_RISC_JUMP);
- *(ro++)=cpu_to_le32(btv->bus_vbi_even);
- *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
- *(re++)=cpu_to_le32(btv->bus_vbi_odd);
-
- if (bttv_debug > 1)
- printk("bttv%d: vrisc2: ro=%08lx re=%08lx\n",
- btv->nr,virt_to_bus(ro), virt_to_bus(re));
-
- return 0;
-}
-
-static unsigned char lmaskt[8] =
-{ 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
-static unsigned char rmaskt[8] =
-{ 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
-
-static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int h)
-{
- unsigned char lmask, rmask, *p;
- int W, l, r;
- int i;
-
- if (bttv_debug > 1)
- printk("bttv clip: %dx%d+%d+%d\n",w,h,x,y);
-
- /* bitmap is fixed width, 128 bytes (1024 pixels represented) */
- if (x<0)
- {
- w+=x;
- x=0;
- }
- if (y<0)
- {
- h+=y;
- y=0;
- }
- if (w < 0 || h < 0) /* catch bad clips */
- return;
- /* out of range data should just fall through */
- if (y+h>=625)
- h=625-y;
- if (x+w>=1024)
- w=1024-x;
-
- l=x>>3;
- r=(x+w-1)>>3;
- W=r-l-1;
- lmask=lmaskt[x&7];
- rmask=rmaskt[(x+w-1)&7];
- p=clipmap+128*y+l;
-
- if (W>0)
- {
- for (i=0; i<h; i++, p+=128)
- {
- *p|=lmask;
- memset(p+1, 0xff, W);
- p[W+1]|=rmask;
- }
- } else if (!W) {
- for (i=0; i<h; i++, p+=128)
- {
- p[0]|=lmask;
- p[1]|=rmask;
- }
- } else {
- for (i=0; i<h; i++, p+=128)
- p[0]|=lmask&rmask;
- }
-
-
-}
-
-static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
-{
- int i, line, x, y, bpl, width, height, inter, maxw;
- unsigned int bpp, dx, sx, **rp, *ro, *re, flags, len;
- unsigned long adr;
- unsigned char *clipmap, *clipline, cbit, lastbit, outofmem;
-
- /* take care: bpp != btv->win.bpp is allowed here */
- bpp = fmtbppx2[btv->win.color_fmt&0xf]/2;
- bpl=btv->win.bpl;
- adr=btv->win.vidadr + btv->win.x * btv->win.bpp + btv->win.y * bpl;
- inter=(btv->win.interlace&1)^1;
- width=btv->win.width;
- height=btv->win.height;
- if (bttv_debug > 1)
- printk("bttv%d: clip1: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
- btv->nr,btv->picture.palette,width,height,bpl,bpp);
- if(width > 1023)
- width = 1023; /* sanity check */
- if(height > 625)
- height = 625; /* sanity check */
- ro=btv->risc_scr_odd;
- re=btv->risc_scr_even;
-
- if (bttv_debug)
- printk("bttv%d: clip: ro=%08lx re=%08lx\n",
- btv->nr,virt_to_bus(ro), virt_to_bus(re));
-
- if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) {
- /* can't clip, don't generate any risc code */
- *(ro++)=cpu_to_le32(BT848_RISC_JUMP);
- *(ro++)=cpu_to_le32(btv->bus_vbi_even);
- *(re++)=cpu_to_le32(BT848_RISC_JUMP);
- *(re++)=cpu_to_le32(btv->bus_vbi_odd);
- }
- if (ncr < 0) { /* bitmap was pased */
- memcpy(clipmap, (unsigned char *)cr, VIDEO_CLIPMAP_SIZE);
- } else { /* convert rectangular clips to a bitmap */
- memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */
- for (i=0; i<ncr; i++)
- clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,
- cr[i].width, cr[i].height);
- }
- /* clip against viewing window AND screen
- so we do not have to rely on the user program
- */
- maxw = (bpl - btv->win.x * btv->win.bpp) / bpp;
- clip_draw_rectangle(clipmap, (width > maxw) ? maxw : width,
- 0, 1024, 768);
- clip_draw_rectangle(clipmap,0,(btv->win.y+height>btv->win.sheight) ?
- (btv->win.sheight-btv->win.y) : height,1024,768);
- if (btv->win.x<0)
- clip_draw_rectangle(clipmap, 0, 0, -(btv->win.x), 768);
- if (btv->win.y<0)
- clip_draw_rectangle(clipmap, 0, 0, 1024, -(btv->win.y));
-
- *(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(ro++)=cpu_to_le32(0);
- *(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(re++)=cpu_to_le32(0);
-
- /* translate bitmap to risc code */
- for (line=outofmem=0; line < (height<<inter) && !outofmem; line++)
- {
- y = line>>inter;
- rp= (line&1) ? &re : &ro;
- clipline = clipmap + (y<<7); /* running pointers ... */
- lastbit = *clipline & 1;
- for(x=dx=0,sx=0; x<=width && !outofmem;) {
- if (0 == (x&7)) {
- /* check bytes not bits if we can ... */
- if (lastbit) {
- while (0xff==*clipline && x<width-8) {
- x += 8;
- dx += 8;
- clipline++;
- }
- } else {
- while (0x00==*clipline && x<width-8) {
- x += 8;
- dx += 8;
- clipline++;
- }
- }
- }
- cbit = *clipline & (1<<(x&7));
- if (x < width && !lastbit == !cbit) {
- dx++;
- } else {
- /* generate the dma controller code */
- len = dx * bpp;
- flags = ((bpp==4) ? BT848_RISC_BYTE3 : 0);
- flags |= ((!sx) ? BT848_RISC_SOL : 0);
- flags |= ((sx + dx == width) ? BT848_RISC_EOL : 0);
- if (!lastbit) {
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|flags|len);
- *((*rp)++)=cpu_to_le32(adr + bpp * sx);
- } else {
- *((*rp)++)=cpu_to_le32(BT848_RISC_SKIP|flags|len);
- }
- lastbit=cbit;
- sx += dx;
- dx = 1;
- if (ro - btv->risc_scr_odd>RISCMEM_LEN/2 - 16)
- outofmem++;
- if (re - btv->risc_scr_even>RISCMEM_LEN/2 - 16)
- outofmem++;
- }
- x++;
- if (0 == (x&7))
- clipline++;
- }
- if ((!inter)||(line&1))
- adr+=bpl;
- }
-
- vfree(clipmap);
- /* outofmem flag relies on the following code to discard extra data */
- *(ro++)=cpu_to_le32(BT848_RISC_JUMP);
- *(ro++)=cpu_to_le32(btv->bus_vbi_even);
- *(re++)=cpu_to_le32(BT848_RISC_JUMP);
- *(re++)=cpu_to_le32(btv->bus_vbi_odd);
-
- if (bttv_debug > 1)
- printk("bttv%d: clip2: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
- btv->nr,btv->picture.palette,width,height,bpl,bpp);
-}
-
-/*
- * Set the registers for the size we have specified. Don't bother
- * trying to understand this without the BT848 manual in front of
- * you [AC].
- *
- * PS: The manual is free for download in .pdf format from
- * www.brooktree.com - nicely done those folks.
- */
-
-static inline void bt848_set_eogeo(struct bttv *btv, struct tvnorm *tvn,
- int odd, int width, int height)
-{
- u16 vscale, hscale;
- u32 xsf, sr;
- u16 hdelay;
- u8 crop, vtc;
- int inter = (height>tvn->sheight/2) ? 0 : 1;
- int off = odd ? 0x80 : 0x00;
-
- xsf = (width*tvn->scaledtwidth)/tvn->swidth;
- hscale = ((tvn->totalwidth*4096UL)/xsf-4096);
- hdelay = tvn->hdelayx1;
- hdelay = (hdelay*width)/tvn->swidth;
- hdelay &= 0x3fe;
- sr=((tvn->sheight>>inter)*512)/height-512;
- vscale=(0x10000UL-sr)&0x1fff;
- crop=((width>>8)&0x03)|((hdelay>>6)&0x0c)|
- ((tvn->sheight>>4)&0x30)|((tvn->vdelay>>2)&0xc0);
- vscale |= inter ? (BT848_VSCALE_INT<<8) : 0;
-
-#if 0
- /* Some people say interpolation looks bad ... */
- vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
- if (width < 767)
- btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
- else
- btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
-#else
- vtc = 0;
- btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
-#endif
-
- btwrite(vtc, BT848_E_VTC+off);
- btwrite(hscale>>8, BT848_E_HSCALE_HI+off);
- btwrite(hscale&0xff, BT848_E_HSCALE_LO+off);
- btaor((vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
- btwrite(vscale&0xff, BT848_E_VSCALE_LO+off);
- btwrite(width&0xff, BT848_E_HACTIVE_LO+off);
- btwrite(hdelay&0xff, BT848_E_HDELAY_LO+off);
- btwrite(tvn->sheight&0xff, BT848_E_VACTIVE_LO+off);
- btwrite(tvn->vdelay&0xff, BT848_E_VDELAY_LO+off);
- btwrite(crop, BT848_E_CROP+off);
-}
-
-
-static void bt848_set_geo(struct bttv *btv,
- int no_irq_context)
-{
- u16 ewidth, eheight, owidth, oheight;
- u16 format, bswap;
- struct tvnorm *tvn;
-
- tvn=&tvnorms[btv->win.norm];
-
- btwrite(tvn->adelay, BT848_ADELAY);
- btwrite(tvn->bdelay, BT848_BDELAY);
- btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
- btwrite(tvn->vbipack, BT848_VBI_PACK_SIZE);
- btwrite(1, BT848_VBI_PACK_DEL);
-
- btv->pll.pll_ofreq = tvn->Fsc;
- if (no_irq_context)
- set_pll(btv);
-
- btv->win.interlace = (btv->win.height>tvn->sheight/2) ? 1 : 0;
-
- if (0 == btv->risc_cap_odd &&
- 0 == btv->risc_cap_even) {
- /* overlay only */
- owidth = btv->win.width;
- oheight = btv->win.height;
- ewidth = btv->win.width;
- eheight = btv->win.height;
- format = btv->win.color_fmt;
- bswap = btv->fb_color_ctl;
- } else if (-1 != btv->gq_grab &&
- 0 == btv->risc_cap_odd &&
- !btv->win.interlace &&
- btv->scr_on) {
- /* odd field -> overlay, even field -> capture */
- owidth = btv->win.width;
- oheight = btv->win.height;
- ewidth = btv->gbuf[btv->gq_grab].width;
- eheight = btv->gbuf[btv->gq_grab].height;
- format = (btv->win.color_fmt & 0xf0) |
- (btv->gbuf[btv->gq_grab].fmt & 0x0f);
- bswap = btv->fb_color_ctl & 0x0a;
- } else {
- /* capture only */
- owidth = btv->gbuf[btv->gq_grab].width;
- oheight = btv->gbuf[btv->gq_grab].height;
- ewidth = btv->gbuf[btv->gq_grab].width;
- eheight = btv->gbuf[btv->gq_grab].height;
- format = btv->gbuf[btv->gq_grab].fmt;
- bswap = 0;
- }
-
- /* program odd + even fields */
- bt848_set_eogeo(btv, tvn, 1, owidth, oheight);
- bt848_set_eogeo(btv, tvn, 0, ewidth, eheight);
-
- btwrite(format, BT848_COLOR_FMT);
- btwrite(bswap | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
-}
-
-
-static int bpp2fmt[4] = {
- BT848_COLOR_FMT_RGB8, BT848_COLOR_FMT_RGB16,
- BT848_COLOR_FMT_RGB24, BT848_COLOR_FMT_RGB32
-};
-
-static void bt848_set_winsize(struct bttv *btv)
-{
- unsigned short format;
-
- if (btv->picture.palette > 0 && btv->picture.palette <= VIDEO_PALETTE_YUV422) {
- /* format set by VIDIOCSPICT */
- format = palette2fmt[btv->picture.palette];
- } else {
- /* use default for the given color depth */
- format = (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
- bpp2fmt[(btv->win.bpp-1)&3];
- }
- btv->win.color_fmt = format;
- if (bigendian &&
- format == BT848_COLOR_FMT_RGB32) {
- btv->fb_color_ctl =
- BT848_COLOR_CTL_WSWAP_ODD |
- BT848_COLOR_CTL_WSWAP_EVEN |
- BT848_COLOR_CTL_BSWAP_ODD |
- BT848_COLOR_CTL_BSWAP_EVEN;
- } else if (bigendian &&
- (format == BT848_COLOR_FMT_RGB16 ||
- format == BT848_COLOR_FMT_RGB15)) {
- btv->fb_color_ctl =
- BT848_COLOR_CTL_BSWAP_ODD |
- BT848_COLOR_CTL_BSWAP_EVEN;
- } else {
- btv->fb_color_ctl = 0;
- }
-
- /* RGB8 seems to be a 9x5x5 GRB color cube starting at
- * color 16. Why the h... can't they even mention this in the
- * data sheet? [AC - because it's a standard format so I guess
- * it never occurred to them]
- * Enable dithering in this mode.
- */
-
- if (format==BT848_COLOR_FMT_RGB8)
- btand(~BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
- else
- btor(BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
-
- bt848_set_geo(btv,1);
-}
-
-#ifdef HACKING
-/* playing with kiobufs and dma-to-userspace. 2.4.x only
- Yes, I know: cut+paste programming is ugly.
- will fix later, this is proof-of-concept right now. */
-static int make_vrisctab_kiobuf(struct bttv *btv, unsigned int *ro,
- unsigned int *re, struct kiobuf *iobuf,
- unsigned short width, unsigned short height,
- unsigned short palette)
-{
- unsigned long bpl; /* bytes per line */
- unsigned long bl;
- unsigned long todo;
- unsigned long pageaddr;
- unsigned int **rp;
- unsigned long line,inter,offset,page;
-
- inter = (height>tvnorms[btv->win.norm].sheight/2) ? 1 : 0;
- bpl=width*fmtbppx2[palette2fmt[palette]&0xf]/2;
-
- *(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(ro++)=cpu_to_le32(0);
- *(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(re++)=cpu_to_le32(0);
-
- offset = iobuf->offset;
- page = 0;
- pageaddr = virt_to_bus(page_address(iobuf->maplist[page]));
- for (line=0; line < (height<<(1^inter)); line++)
- {
- if (inter)
- rp= (line&1) ? &re : &ro;
- else
- rp= (line>=height) ? &ro : &re;
-
- bl = PAGE_SIZE - offset;
- if (bpl <= bl) {
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
- BT848_RISC_EOL|bpl);
- *((*rp)++)=cpu_to_le32(pageaddr+offset);
- offset+=bpl;
- } else {
- todo = bpl;
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|bl);
- *((*rp)++)=cpu_to_le32(pageaddr+offset);
- todo -= bl;
- offset = 0;
- page++;
- pageaddr = virt_to_bus(page_address(iobuf->maplist[page]));
- while (todo>PAGE_SIZE)
- {
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|PAGE_SIZE);
- *((*rp)++)=cpu_to_le32(pageaddr);
- page++;
- pageaddr = virt_to_bus(page_address(iobuf->maplist[page]));
- }
- *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|todo);
- *((*rp)++)=cpu_to_le32(pageaddr);
- offset += todo;
- }
- }
-
- *(ro++)=cpu_to_le32(BT848_RISC_JUMP);
- *(ro++)=cpu_to_le32(btv->bus_vbi_even);
- *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
- *(re++)=cpu_to_le32(btv->bus_vbi_odd);
-
- return 0;
-}
-
-static int vgrab_kiobuf(struct bttv *btv, struct bttv_just_hacking *mp,
- struct kiobuf *iobuf)
-{
- unsigned int *ro, *re;
- unsigned long flags;
-
- if(btv->gbuf[0].stat != GBUFFER_UNUSED)
- return -EBUSY;
-
- if(mp->height < 32 || mp->width < 32)
- return -EINVAL;
- if (mp->format >= 12 /* more is'nt yet ... PALETTEFMT_MAX */)
- return -EINVAL;
-
- if(-1 == palette2fmt[mp->format])
- return -EINVAL;
-
- /*
- * Ok load up the BT848
- */
-
- ro=btv->gbuf[0].risc;
- re=ro+2048;
- make_vrisctab_kiobuf(btv, ro, re, iobuf, mp->width, mp->height, mp->format);
-
- if (bttv_debug)
- printk("bttv%d: cap vgrab_kiobuf: queue %d (%d:%dx%d)\n",
- btv->nr,0,mp->format,mp->width,mp->height);
- spin_lock_irqsave(&btv->s_lock, flags);
- btv->gbuf[0].stat = GBUFFER_GRABBING;
- btv->gbuf[0].fmt = palette2fmt[mp->format];
- btv->gbuf[0].width = mp->width;
- btv->gbuf[0].height = mp->height;
- btv->gbuf[0].ro = virt_to_bus(ro);
- btv->gbuf[0].re = virt_to_bus(re);
-
-#if 1
- if (mp->height <= tvnorms[btv->win.norm].sheight/2 &&
- mp->format != VIDEO_PALETTE_RAW)
- btv->gbuf[0].ro = 0;
-#endif
-
- if (-1 == btv->gq_grab && btv->gq_in == btv->gq_out) {
- btv->gq_start = 1;
- btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ);
- }
- btv->gqueue[btv->gq_in++] = 0;
- btv->gq_in = btv->gq_in % MAX_GBUFFERS;
-
- btor(3, BT848_CAP_CTL);
- btor(3, BT848_GPIO_DMA_CTL);
- spin_unlock_irqrestore(&btv->s_lock, flags);
- return 0;
-}
-#endif
-
-/*
- * Grab into virtual memory.
- */
-
-static int vgrab(struct bttv *btv, struct video_mmap *mp)
-{
- unsigned int *ro, *re;
- unsigned int *vbuf;
- unsigned long flags;
-
- if(btv->fbuffer==NULL)
- {
- if(fbuffer_alloc(btv))
- return -ENOBUFS;
- }
-
- if(mp->frame >= gbuffers || mp->frame < 0)
- return -EINVAL;
- if(btv->gbuf[mp->frame].stat != GBUFFER_UNUSED)
- return -EBUSY;
-
- if(mp->height < 32 || mp->width < 32)
- return -EINVAL;
- if (mp->format >= PALETTEFMT_MAX)
- return -EINVAL;
-
- if (mp->height*mp->width*fmtbppx2[palette2fmt[mp->format]&0x0f]/2
- > gbufsize)
- return -EINVAL;
- if(-1 == palette2fmt[mp->format])
- return -EINVAL;
-
- /*
- * Ok load up the BT848
- */
-
- vbuf=(unsigned int *)(btv->fbuffer+gbufsize*mp->frame);
- ro=btv->gbuf[mp->frame].risc;
- re=ro+2048;
- make_vrisctab(btv, ro, re, vbuf, mp->width, mp->height, mp->format);
-
- if (bttv_debug)
- printk("bttv%d: cap vgrab: queue %d (%d:%dx%d)\n",
- btv->nr,mp->frame,mp->format,mp->width,mp->height);
- spin_lock_irqsave(&btv->s_lock, flags);
- btv->gbuf[mp->frame].stat = GBUFFER_GRABBING;
- btv->gbuf[mp->frame].fmt = palette2fmt[mp->format];
- btv->gbuf[mp->frame].width = mp->width;
- btv->gbuf[mp->frame].height = mp->height;
- btv->gbuf[mp->frame].ro = virt_to_bus(ro);
- btv->gbuf[mp->frame].re = virt_to_bus(re);
-
-#if 1
- if (mp->height <= tvnorms[btv->win.norm].sheight/2 &&
- mp->format != VIDEO_PALETTE_RAW)
- btv->gbuf[mp->frame].ro = 0;
-#endif
-
- if (-1 == btv->gq_grab && btv->gq_in == btv->gq_out) {
- btv->gq_start = 1;
- btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ);
- }
- btv->gqueue[btv->gq_in++] = mp->frame;
- btv->gq_in = btv->gq_in % MAX_GBUFFERS;
-
- btor(3, BT848_CAP_CTL);
- btor(3, BT848_GPIO_DMA_CTL);
- spin_unlock_irqrestore(&btv->s_lock, flags);
- return 0;
-}
-
-static long bttv_write(struct video_device *v, const char *buf, unsigned long count, int nonblock)
-{
- return -EINVAL;
-}
-
-static long bttv_read(struct video_device *v, char *buf, unsigned long count, int nonblock)
-{
- struct bttv *btv= (struct bttv *)v;
- int q,todo;
- DECLARE_WAITQUEUE(wait, current);
-
- /* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */
- todo=count;
- while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
- {
- if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
- return -EFAULT;
- todo-=q;
- buf+=q;
-
- add_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_INTERRUPTIBLE;
- if (todo && q==VBIBUF_SIZE-btv->vbip)
- {
- if(nonblock)
- {
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
- if(count==todo)
- return -EWOULDBLOCK;
- return count-todo;
- }
- schedule();
- if(signal_pending(current))
- {
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
-
- if(todo==count)
- return -EINTR;
- else
- return count-todo;
- }
- }
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
- }
- if (todo)
- {
- if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, todo))
- return -EFAULT;
- btv->vbip+=todo;
- }
- return count;
-}
-
-static inline void burst(int on)
-{
- tvnorms[0].scaledtwidth = 1135 - (on?BURSTOFFSET-2:0);
- tvnorms[0].hdelayx1 = 186 - (on?BURSTOFFSET :0);
- tvnorms[2].scaledtwidth = 1135 - (on?BURSTOFFSET-2:0);
- tvnorms[2].hdelayx1 = 186 - (on?BURSTOFFSET :0);
-}
-
-static void bt848_restart(struct bttv *btv)
-{
- unsigned long irq_flags;
-
- if (bttv_verbose)
- printk("bttv%d: resetting chip\n",btv->nr);
- btwrite(0xfffffUL, BT848_INT_STAT);
- btand(~15, BT848_GPIO_DMA_CTL);
- btwrite(0, BT848_SRESET);
- btwrite(virt_to_bus(btv->risc_jmp+2),
- BT848_RISC_STRT_ADD);
-
- /* enforce pll reprogramming */
- btv->pll.pll_current = 0;
- set_pll(btv);
-
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- btv->errors = 0;
- btv->needs_restart = 0;
- bt848_set_geo(btv,0);
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
-}
-
-/*
- * Open a bttv card. Right now the flags stuff is just playing
- */
-
-static int bttv_open(struct video_device *dev, int flags)
-{
- struct bttv *btv = (struct bttv *)dev;
- int i,ret;
-
- ret = -EBUSY;
-
- MOD_INC_USE_COUNT;
- down(&btv->lock);
- if (btv->user)
- goto out_unlock;
-
- btv->fbuffer=(unsigned char *) rvmalloc(gbuffers*gbufsize);
- ret = -ENOMEM;
- if (!btv->fbuffer)
- goto out_unlock;
-
- btv->gq_in = 0;
- btv->gq_out = 0;
- btv->gq_grab = -1;
- for (i = 0; i < gbuffers; i++)
- btv->gbuf[i].stat = GBUFFER_UNUSED;
-
- if (btv->needs_restart)
- bt848_restart(btv);
- burst(0);
- set_pll(btv);
- btv->user++;
- up(&btv->lock);
- return 0;
-
- out_unlock:
- up(&btv->lock);
- MOD_DEC_USE_COUNT;
- return ret;
-}
-
-static void bttv_close(struct video_device *dev)
-{
- struct bttv *btv=(struct bttv *)dev;
- unsigned long irq_flags;
-
- down(&btv->lock);
- btv->user--;
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- btv->scr_on = 0;
- btv->risc_cap_odd = 0;
- btv->risc_cap_even = 0;
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
-
- /*
- * A word of warning. At this point the chip
- * is still capturing because its FIFO hasn't emptied
- * and the DMA control operations are posted PCI
- * operations.
- */
-
- btread(BT848_I2C); /* This fixes the PCI posting delay */
-
- if (-1 != btv->gq_grab) {
- /*
- * This is sucky but right now I can't find a good way to
- * be sure its safe to free the buffer. We wait 5-6 fields
- * which is more than sufficient to be sure.
- */
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ/10); /* Wait 1/10th of a second */
- }
-
- /*
- * We have allowed it to drain.
- */
-
- if(btv->fbuffer)
- rvfree((void *) btv->fbuffer, gbuffers*gbufsize);
- btv->fbuffer=0;
- up(&btv->lock);
- MOD_DEC_USE_COUNT;
-}
-
-
-/***********************************/
-/* ioctls and supporting functions */
-/***********************************/
-
-extern inline void bt848_bright(struct bttv *btv, uint bright)
-{
- btwrite(bright&0xff, BT848_BRIGHT);
-}
-
-extern inline void bt848_hue(struct bttv *btv, uint hue)
-{
- btwrite(hue&0xff, BT848_HUE);
-}
-
-extern inline void bt848_contrast(struct bttv *btv, uint cont)
-{
- unsigned int conthi;
-
- conthi=(cont>>6)&4;
- btwrite(cont&0xff, BT848_CONTRAST_LO);
- btaor(conthi, ~4, BT848_E_CONTROL);
- btaor(conthi, ~4, BT848_O_CONTROL);
-}
-
-extern inline void bt848_sat_u(struct bttv *btv, unsigned long data)
-{
- u32 datahi;
-
- datahi=(data>>7)&2;
- btwrite(data&0xff, BT848_SAT_U_LO);
- btaor(datahi, ~2, BT848_E_CONTROL);
- btaor(datahi, ~2, BT848_O_CONTROL);
-}
-
-static inline void bt848_sat_v(struct bttv *btv, unsigned long data)
-{
- u32 datahi;
-
- datahi=(data>>8)&1;
- btwrite(data&0xff, BT848_SAT_V_LO);
- btaor(datahi, ~1, BT848_E_CONTROL);
- btaor(datahi, ~1, BT848_O_CONTROL);
-}
-
-/*
- * ioctl routine
- */
-
-
-static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct bttv *btv=(struct bttv *)dev;
- unsigned long irq_flags;
- int i,ret = 0;
-
- if (bttv_debug > 1)
- printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd);
-
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability b;
- strcpy(b.name,btv->video_dev.name);
- b.type = VID_TYPE_CAPTURE|
- ((bttv_tvcards[btv->type].tuner != -1) ? VID_TYPE_TUNER : 0) |
- VID_TYPE_OVERLAY|
- VID_TYPE_CLIPPING|
- VID_TYPE_FRAMERAM|
- VID_TYPE_SCALES;
- b.channels = bttv_tvcards[btv->type].video_inputs;
- b.audios = bttv_tvcards[btv->type].audio_inputs;
- b.maxwidth = tvnorms[btv->win.norm].swidth;
- b.maxheight = tvnorms[btv->win.norm].sheight;
- b.minwidth = 32;
- b.minheight = 32;
- if(copy_to_user(arg,&b,sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGCHAN:
- {
- struct video_channel v;
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- v.flags=VIDEO_VC_AUDIO;
- v.tuners=0;
- v.type=VIDEO_TYPE_CAMERA;
- v.norm = btv->win.norm;
- if (v.channel>=bttv_tvcards[btv->type].video_inputs)
- return -EINVAL;
- if(v.channel==bttv_tvcards[btv->type].tuner)
- {
- strcpy(v.name,"Television");
- v.flags|=VIDEO_VC_TUNER;
- v.type=VIDEO_TYPE_TV;
- v.tuners=1;
- }
- else if(v.channel==bttv_tvcards[btv->type].svhs)
- strcpy(v.name,"S-Video");
- else
- sprintf(v.name,"Composite%d",v.channel);
-
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- /*
- * Each channel has 1 tuner
- */
- case VIDIOCSCHAN:
- {
- struct video_channel v;
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
-
- if (v.channel>bttv_tvcards[btv->type].video_inputs)
- return -EINVAL;
- if (v.norm > (sizeof(tvnorms)/sizeof(*tvnorms)))
- return -EOPNOTSUPP;
-
- bttv_call_i2c_clients(btv,cmd,&v);
- down(&btv->lock);
- bt848_muxsel(btv, v.channel);
- btv->channel=v.channel;
- if (btv->win.norm != v.norm) {
- btv->win.norm = v.norm;
- make_vbitab(btv);
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_winsize(btv);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- }
- up(&btv->lock);
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v,arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner||btv->channel) /* Only tuner 0 */
- return -EINVAL;
- strcpy(v.name, "Television");
- v.rangelow=0;
- v.rangehigh=0xFFFFFFFF;
- v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
- v.mode = btv->win.norm;
- v.signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;
- bttv_call_i2c_clients(btv,cmd,&v);
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- /* We have but one tuner */
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- /* Only one channel has a tuner */
- if(v.tuner!=bttv_tvcards[btv->type].tuner)
- return -EINVAL;
-
- if(v.mode!=VIDEO_MODE_PAL&&v.mode!=VIDEO_MODE_NTSC
- &&v.mode!=VIDEO_MODE_SECAM)
- return -EOPNOTSUPP;
- bttv_call_i2c_clients(btv,cmd,&v);
- if (btv->win.norm != v.mode) {
- btv->win.norm = v.mode;
- down(&btv->lock);
- set_pll(btv);
- make_vbitab(btv);
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_winsize(btv);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- up(&btv->lock);
- }
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture p=btv->picture;
- if(copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture p;
- if(copy_from_user(&p, arg,sizeof(p)))
- return -EFAULT;
- if (p.palette > PALETTEFMT_MAX)
- return -EINVAL;
- down(&btv->lock);
- /* We want -128 to 127 we get 0-65535 */
- bt848_bright(btv, (p.brightness>>8)-128);
- /* 0-511 for the colour */
- bt848_sat_u(btv, p.colour>>7);
- bt848_sat_v(btv, ((p.colour>>7)*201L)/237);
- /* -128 to 127 */
- bt848_hue(btv, (p.hue>>8)-128);
- /* 0-511 */
- bt848_contrast(btv, p.contrast>>7);
- btv->picture = p;
- up(&btv->lock);
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- struct video_clip *vcp = NULL;
-
- if(copy_from_user(&vw,arg,sizeof(vw)))
- return -EFAULT;
-
- down(&btv->lock);
- if(vw.flags || vw.width < 16 || vw.height < 16)
- {
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- btv->scr_on = 0;
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- return -EINVAL;
- }
- if (btv->win.bpp < 4)
- { /* adjust and align writes */
- vw.x = (vw.x + 3) & ~3;
- vw.width &= ~3;
- }
- if (btv->needs_restart)
- bt848_restart(btv);
- btv->win.x=vw.x;
- btv->win.y=vw.y;
- btv->win.width=vw.width;
- btv->win.height=vw.height;
-
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_risc_jmps(btv,0);
- bt848_set_winsize(btv);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
-
- /*
- * Do any clips.
- */
- if(vw.clipcount<0) {
- if((vcp=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL)
- return -ENOMEM;
- if(copy_from_user(vcp, vw.clips,
- VIDEO_CLIPMAP_SIZE)) {
- vfree(vcp);
- return -EFAULT;
- }
- } else if (vw.clipcount) {
- if((vcp=vmalloc(sizeof(struct video_clip)*
- (vw.clipcount))) == NULL)
- return -ENOMEM;
- if(copy_from_user(vcp,vw.clips,
- sizeof(struct video_clip)*
- vw.clipcount)) {
- vfree(vcp);
- return -EFAULT;
- }
- }
- make_clip_tab(btv, vcp, vw.clipcount);
- if (vw.clipcount != 0)
- vfree(vcp);
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- up(&btv->lock);
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
- /* Oh for a COBOL move corresponding .. */
- vw.x=btv->win.x;
- vw.y=btv->win.y;
- vw.width=btv->win.width;
- vw.height=btv->win.height;
- vw.chromakey=0;
- vw.flags=0;
- if(btv->win.interlace)
- vw.flags|=VIDEO_WINDOW_INTERLACE;
- if(copy_to_user(arg,&vw,sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- {
- int v;
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- if(btv->win.vidadr == 0)
- return -EINVAL;
- if (btv->win.width==0 || btv->win.height==0)
- return -EINVAL;
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- if (v == 1 && btv->win.vidadr != 0)
- btv->scr_on = 1;
- if (v == 0)
- btv->scr_on = 0;
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- return 0;
- }
- case VIDIOCGFBUF:
- {
- struct video_buffer v;
- v.base=(void *)btv->win.vidadr;
- v.height=btv->win.sheight;
- v.width=btv->win.swidth;
- v.depth=btv->win.depth;
- v.bytesperline=btv->win.bpl;
- if(copy_to_user(arg, &v,sizeof(v)))
- return -EFAULT;
- return 0;
-
- }
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
- if(!capable(CAP_SYS_ADMIN) &&
- !capable(CAP_SYS_RAWIO))
- return -EPERM;
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- if(v.depth!=8 && v.depth!=15 && v.depth!=16 &&
- v.depth!=24 && v.depth!=32 && v.width > 16 &&
- v.height > 16 && v.bytesperline > 16)
- return -EINVAL;
- down(&btv->lock);
- if (v.base)
- btv->win.vidadr=(unsigned long)v.base;
- btv->win.sheight=v.height;
- btv->win.swidth=v.width;
- btv->win.bpp=((v.depth+7)&0x38)/8;
- btv->win.depth=v.depth;
- btv->win.bpl=v.bytesperline;
-
- /* set sefault color format */
- switch (btv->win.bpp) {
- case 8: btv->picture.palette = VIDEO_PALETTE_HI240; break;
- case 15: btv->picture.palette = VIDEO_PALETTE_RGB555; break;
- case 16: btv->picture.palette = VIDEO_PALETTE_RGB565; break;
- case 24: btv->picture.palette = VIDEO_PALETTE_RGB24; break;
- case 32: btv->picture.palette = VIDEO_PALETTE_RGB32; break;
- }
-
- if (bttv_debug)
- printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n",
- v.base, v.width,v.height, btv->win.bpp, btv->win.bpl);
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_winsize(btv);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- up(&btv->lock);
- return 0;
- }
- case VIDIOCKEY:
- {
- /* Will be handled higher up .. */
- return 0;
- }
- case VIDIOCGFREQ:
- {
- unsigned long v=btv->win.freq;
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- btv->win.freq=v;
- bttv_call_i2c_clients(btv,cmd,&v);
-#if 0
- if (btv->type == BTTV_MIROPRO && btv->radio)
- tea5757_set_freq(btv,v);
-#endif
- return 0;
- }
-
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
-
- v=btv->audio_dev;
- v.flags&=~(VIDEO_AUDIO_MUTE|VIDEO_AUDIO_MUTABLE);
- v.flags|=VIDEO_AUDIO_MUTABLE;
- strcpy(v.name,"TV");
-
- v.mode = VIDEO_SOUND_MONO;
- bttv_call_i2c_clients(btv,cmd,&v);
-
- if (btv->type == BTTV_TERRATV) {
- v.mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
- VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
- }
-#ifndef HAVE_TVAUDIO
- else if (btv->audio_chip == TDA9840) {
- /* begin of Horrible Hack <grin@tolna.net> */
- v.flags|=VIDEO_AUDIO_VOLUME;
- v.mode = VIDEO_SOUND_MONO;
- v.mode |= VIDEO_SOUND_STEREO;
- v.mode |= VIDEO_SOUND_LANG1|VIDEO_SOUND_LANG2;
- v.volume = 32768; /* fixme */
- v.step = 4096;
- }
-#endif
-
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
-
- if(copy_from_user(&v,arg, sizeof(v)))
- return -EFAULT;
- down(&btv->lock);
- if(v.flags&VIDEO_AUDIO_MUTE)
- audio(btv, AUDIO_MUTE, 1);
- /* One audio source per tuner -- huh? <GA> */
- if(v.audio<0 || v.audio >= bttv_tvcards[btv->type].audio_inputs) {
- up(&btv->lock);
- return -EINVAL;
- }
- /* bt848_muxsel(btv,v.audio); */
- if(!(v.flags&VIDEO_AUDIO_MUTE))
- audio(btv, AUDIO_UNMUTE, 1);
-
- bttv_call_i2c_clients(btv,cmd,&v);
-
- if (btv->type == BTTV_TERRATV) {
- unsigned int con = 0;
- btor(0x180000, BT848_GPIO_OUT_EN);
- if (v.mode & VIDEO_SOUND_LANG2)
- con = 0x080000;
- if (v.mode & VIDEO_SOUND_STEREO)
- con = 0x180000;
- btaor(con, ~0x180000, BT848_GPIO_DATA);
-
- } else if (btv->type == BTTV_WINVIEW_601)
- winview_setvol(btv,&v);
-
- btv->audio_dev=v;
- up(&btv->lock);
- return 0;
- }
-
- case VIDIOCSYNC:
- {
- DECLARE_WAITQUEUE(wait, current);
-
- if(copy_from_user((void *)&i,arg,sizeof(int)))
- return -EFAULT;
- if (i < 0 || i >= gbuffers)
- return -EINVAL;
- switch (btv->gbuf[i].stat) {
- case GBUFFER_UNUSED:
- ret = -EINVAL;
- break;
- case GBUFFER_GRABBING:
- add_wait_queue(&btv->capq, &wait);
- current->state = TASK_INTERRUPTIBLE;
- while(btv->gbuf[i].stat==GBUFFER_GRABBING) {
- if (bttv_debug)
- printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i);
- schedule();
- if(signal_pending(current)) {
- remove_wait_queue(&btv->capq, &wait);
- current->state = TASK_RUNNING;
- return -EINTR;
- }
- }
- remove_wait_queue(&btv->capq, &wait);
- current->state = TASK_RUNNING;
- /* fall throuth */
- case GBUFFER_DONE:
- case GBUFFER_ERROR:
- ret = (btv->gbuf[i].stat == GBUFFER_ERROR) ? -EIO : 0;
- if (bttv_debug)
- printk("bttv%d: cap sync: buffer %d, retval %d\n",btv->nr,i,ret);
- btv->gbuf[i].stat = GBUFFER_UNUSED;
- }
- if (btv->needs_restart) {
- down(&btv->lock);
- bt848_restart(btv);
- up(&btv->lock);
- }
- return ret;
- }
-
- case BTTV_FIELDNR:
- if(copy_to_user((void *) arg, (void *) &btv->last_field,
- sizeof(btv->last_field)))
- return -EFAULT;
- break;
-
- case BTTV_PLLSET: {
- struct bttv_pll_info p;
- if(!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if(copy_from_user(&p , (void *) arg, sizeof(btv->pll)))
- return -EFAULT;
- down(&btv->lock);
- btv->pll.pll_ifreq = p.pll_ifreq;
- btv->pll.pll_ofreq = p.pll_ofreq;
- btv->pll.pll_crystal = p.pll_crystal;
- up(&btv->lock);
- break;
- }
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap vm;
- int ret;
- if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm)))
- return -EFAULT;
- down(&btv->lock);
- ret = vgrab(btv, &vm);
- up(&btv->lock);
- return ret;
- }
-
- case VIDIOCGMBUF:
- {
- struct video_mbuf vm;
- memset(&vm, 0 , sizeof(vm));
- vm.size=gbufsize*gbuffers;
- vm.frames=gbuffers;
- for (i = 0; i < gbuffers; i++)
- vm.offsets[i]=i*gbufsize;
- if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
- return -EFAULT;
- return 0;
- }
-
- case VIDIOCGUNIT:
- {
- struct video_unit vu;
- vu.video=btv->video_dev.minor;
- vu.vbi=btv->vbi_dev.minor;
- if(btv->radio_dev.minor!=-1)
- vu.radio=btv->radio_dev.minor;
- else
- vu.radio=VIDEO_NO_UNIT;
- vu.audio=VIDEO_NO_UNIT;
- vu.teletext=VIDEO_NO_UNIT;
- if(copy_to_user((void *)arg, (void *)&vu, sizeof(vu)))
- return -EFAULT;
- return 0;
- }
-
- case BTTV_BURST_ON:
- {
- burst(1);
- return 0;
- }
-
- case BTTV_BURST_OFF:
- {
- burst(0);
- return 0;
- }
-
- case BTTV_VERSION:
- {
- return BTTV_VERSION_CODE;
- }
-
- case BTTV_PICNR:
- {
- /* return picture;*/
- return 0;
- }
-
-#ifdef HACKING
- /* playing with kiobufs and dma-to-userspace */
- case BTTV_JUST_HACKING:
- {
- DECLARE_WAITQUEUE(wait, current);
- struct bttv_just_hacking hack;
- struct kiobuf *iobuf;
- int err;
-
- if(copy_from_user((void *) &hack, (void *) arg, sizeof(hack)))
- return -EFAULT;
- printk("bttv%d: hack: userland args: %dx%d, fmt=%d, buf=%lx, len=%d\n",
- btv->nr,hack.width,hack.height,hack.format,
- hack.buf,hack.len);
-
- /* pin down */
- err = alloc_kiovec(1,&iobuf);
- if (err)
- goto hack_oops;
- err = map_user_kiobuf(READ, iobuf, hack.buf, hack.len);
- if (err)
- goto hack_oops;
- err = lock_kiovec(1,&iobuf,1);
- if (err)
- goto hack_oops;
-
- /* have a look */
- printk("bttv%d: hack: kiobuf: nr_pages=%d, offset=%d, length=%d, locked=%d\n",
- btv->nr,iobuf->nr_pages,iobuf->offset,iobuf->length,
- iobuf->locked);
- printk("bttv%d: hack: pages (bus addr):",btv->nr);
- for (i = 0; i < iobuf->nr_pages; i++) {
- printk(" %lx", virt_to_bus(page_address(iobuf->maplist[i])));
- }
- printk("\n");
-
- /* start capture */
- err = -EINVAL;
- if (hack.height * hack.width * 2 * /* fixme: *2 */
- fmtbppx2[palette2fmt[hack.format]&0x0f]/2 > hack.len)
- goto hack_oops;
- err = vgrab_kiobuf(btv,&hack,iobuf);
- if (err)
- goto hack_oops;
- printk("bttv%d: hack: capture started\n",btv->nr);
-
- /* wait */
- add_wait_queue(&btv->capq, &wait);
- current->state = TASK_INTERRUPTIBLE;
- while(btv->gbuf[0].stat==GBUFFER_GRABBING) {
- if (bttv_debug)
- printk("bttv%d: hack: cap sync: sleep on %d\n",btv->nr,0);
- schedule();
-#if 0
- if(signal_pending(current)) {
- remove_wait_queue(&btv->capq, &wait);
- current->state = TASK_RUNNING;
- return -EINTR;
- }
-#endif
- }
- remove_wait_queue(&btv->capq, &wait);
- current->state = TASK_RUNNING;
- printk("bttv%d: hack: capture done\n",btv->nr);
-
- /* release */
- err = 0;
- hack_oops:
- free_kiovec(1,&iobuf);
- return 0;
- }
-#endif
-
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static int bttv_init_done(struct video_device *dev)
-{
- return 0;
-}
-
-/*
- * This maps the vmalloced and reserved fbuffer to user space.
- *
- * FIXME:
- * - PAGE_READONLY should suffice!?
- * - remap_page_range is kind of inefficient for page by page remapping.
- * But e.g. pte_alloc() does not work in modules ... :-(
- */
-
-static int do_bttv_mmap(struct bttv *btv, const char *adr, unsigned long size)
-{
- unsigned long start=(unsigned long) adr;
- unsigned long page,pos;
-
- if (size>gbuffers*gbufsize)
- return -EINVAL;
- if (!btv->fbuffer) {
- if(fbuffer_alloc(btv))
- return -EINVAL;
- }
- pos=(unsigned long) btv->fbuffer;
- while (size > 0) {
- page = kvirt_to_pa(pos);
- if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
- start+=PAGE_SIZE;
- pos+=PAGE_SIZE;
- size-=PAGE_SIZE;
- }
- return 0;
-}
-
-static int bttv_mmap(struct video_device *dev, const char *adr, unsigned long size)
-{
- struct bttv *btv=(struct bttv *)dev;
- int r;
-
- down(&btv->lock);
- r=do_bttv_mmap(btv, adr, size);
- up(&btv->lock);
- return r;
-}
-
-
-static struct video_device bttv_template=
-{
- "UNSET",
- VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY|VID_TYPE_TELETEXT,
- VID_HARDWARE_BT848,
- bttv_open,
- bttv_close,
- bttv_read,
- bttv_write,
- NULL,
- bttv_ioctl,
- bttv_mmap,
- bttv_init_done,
- NULL,
- 0,
- -1
-};
-
-
-static long vbi_read(struct video_device *v, char *buf, unsigned long count,
- int nonblock)
-{
- struct bttv *btv=(struct bttv *)(v-2);
- int q,todo;
- DECLARE_WAITQUEUE(wait, current);
-
- todo=count;
- while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
- {
- if (btv->needs_restart) {
- down(&btv->lock);
- bt848_restart(btv);
- up(&btv->lock);
- }
- if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
- return -EFAULT;
- todo-=q;
- buf+=q;
-
- add_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_INTERRUPTIBLE;
- if (todo && q==VBIBUF_SIZE-btv->vbip)
- {
- if(nonblock)
- {
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
- if(count==todo)
- return -EWOULDBLOCK;
- return count-todo;
- }
- schedule();
- if(signal_pending(current))
- {
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
- if(todo==count)
- return -EINTR;
- else
- return count-todo;
- }
- }
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
- }
- if (todo)
- {
- if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, todo))
- return -EFAULT;
- btv->vbip+=todo;
- }
- return count;
-}
-
-static unsigned int vbi_poll(struct video_device *dev, struct file *file,
- poll_table *wait)
-{
- struct bttv *btv=(struct bttv *)(dev-2);
- unsigned int mask = 0;
-
- poll_wait(file, &btv->vbiq, wait);
-
- if (btv->vbip < VBIBUF_SIZE)
- mask |= (POLLIN | POLLRDNORM);
-
- return mask;
-}
-
-static int vbi_open(struct video_device *dev, int flags)
-{
- struct bttv *btv=(struct bttv *)(dev-2);
- unsigned long irq_flags;
-
- MOD_INC_USE_COUNT;
- down(&btv->lock);
- if (btv->needs_restart)
- bt848_restart(btv);
- set_pll(btv);
- btv->vbip=VBIBUF_SIZE;
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- btv->vbi_on = 1;
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- up(&btv->lock);
-
- return 0;
-}
-
-static void vbi_close(struct video_device *dev)
-{
- struct bttv *btv=(struct bttv *)(dev-2);
- unsigned long irq_flags;
-
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- btv->vbi_on = 0;
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- MOD_DEC_USE_COUNT;
-}
-
-static int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct bttv *btv=(struct bttv *)dev;
-
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability b;
- strcpy(b.name,btv->vbi_dev.name);
- b.type = ((bttv_tvcards[btv->type].tuner != -1) ? VID_TYPE_TUNER : 0) |
- VID_TYPE_TELETEXT;
- b.channels = 0;
- b.audios = 0;
- b.maxwidth = 0;
- b.maxheight = 0;
- b.minwidth = 0;
- b.minheight = 0;
- if(copy_to_user(arg,&b,sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
- return bttv_ioctl((struct video_device *)btv,cmd,arg);
- case BTTV_VBISIZE:
- /* make alevt happy :-) */
- return VBIBUF_SIZE;
- default:
- return -EINVAL;
- }
-}
-
-static struct video_device vbi_template=
-{
- "bttv vbi",
- VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
- VID_HARDWARE_BT848,
- vbi_open,
- vbi_close,
- vbi_read,
- bttv_write,
- vbi_poll,
- vbi_ioctl,
- NULL, /* no mmap yet */
- bttv_init_done,
- NULL,
- 0,
- -1
-};
-
-
-static int radio_open(struct video_device *dev, int flags)
-{
- struct bttv *btv = (struct bttv *)(dev-1);
- unsigned long v;
-
- MOD_INC_USE_COUNT;
- down(&btv->lock);
- if (btv->user)
- goto busy_unlock;
- btv->user++;
-
- btv->radio = 1;
- v = 400*16;
- bttv_call_i2c_clients(btv,VIDIOCSFREQ,&v);
- bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
- bt848_muxsel(btv,0);
- up(&btv->lock);
-
- return 0;
-
- busy_unlock:
- up(&btv->lock);
- MOD_DEC_USE_COUNT;
- return -EBUSY;
-}
-
-static void radio_close(struct video_device *dev)
-{
- struct bttv *btv=(struct bttv *)(dev-1);
-
- down(&btv->lock);
- btv->user--;
- btv->radio = 0;
- up(&btv->lock);
- MOD_DEC_USE_COUNT;
-}
-
-static long radio_read(struct video_device *v, char *buf, unsigned long count, int nonblock)
-{
- return -EINVAL;
-}
-
-static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct bttv *btv=(struct bttv *)(dev-1);
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- strcpy(v.name,btv->video_dev.name);
- v.type = VID_TYPE_TUNER;
- v.channels = 1;
- v.audios = 1;
- /* No we don't do pictures */
- v.maxwidth = 0;
- v.maxheight = 0;
- v.minwidth = 0;
- v.minheight = 0;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- break;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v,arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner||btv->channel) /* Only tuner 0 */
- return -EINVAL;
- strcpy(v.name, "Radio");
- v.rangelow=(int)(76*16); /* jp: 76.0MHz - 89.9MHz */
- v.rangehigh=(int)(108*16); /* eu: 87.5MHz - 108.0MHz */
- v.flags= 0; /* XXX */
- v.mode = 0; /* XXX */
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- /* Only channel 0 has a tuner */
- if(v.tuner!=0 || btv->channel)
- return -EINVAL;
- /* XXX anything to do ??? */
- return 0;
- }
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
- case VIDIOCGAUDIO:
- case VIDIOCSAUDIO:
- bttv_ioctl((struct video_device *)btv,cmd,arg);
- break;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static struct video_device radio_template=
-{
- "bttv radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_BT848,
- radio_open,
- radio_close,
- radio_read, /* just returns -EINVAL */
- bttv_write, /* just returns -EINVAL */
- NULL, /* no poll */
- radio_ioctl,
- NULL, /* no mmap */
- bttv_init_done, /* just returns 0 */
- NULL,
- 0,
- -1
-};
-
-
-#define TRITON_PCON 0x50
-#define TRITON_BUS_CONCURRENCY (1<<0)
-#define TRITON_STREAMING (1<<1)
-#define TRITON_WRITE_BURST (1<<2)
-#define TRITON_PEER_CONCURRENCY (1<<3)
-
-
-static void __devinit handle_chipset(void)
-{
- struct pci_dev *dev = NULL;
-
- /* Just in case some nut set this to something dangerous */
- if (triton1)
- triton1=BT848_INT_ETBF;
-
- while ((dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, dev)))
- {
- /* Beware the SiS 85C496 my friend - rev 49 don't work with a bttv */
- printk(KERN_WARNING "BT848 and SIS 85C496 chipset don't always work together.\n");
- }
-
- while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82441, dev)))
- {
- unsigned char b;
- pci_read_config_byte(dev, 0x53, &b);
- DEBUG(printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "));
- DEBUG(printk("bufcon=0x%02x\n",b));
- }
-
- while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, dev)))
- {
- printk(KERN_INFO "bttv: Host bridge 82437FX Triton PIIX\n");
- triton1=BT848_INT_ETBF;
- }
-}
-
-
-static void bt848_set_risc_jmps(struct bttv *btv, int flags)
-{
- if (-1 == flags) {
- /* defaults */
- flags = 0;
- if (btv->scr_on)
- flags |= 0x03;
- if (btv->vbi_on)
- flags |= 0x0c;
- }
-
- if (bttv_debug > 1)
- printk("bttv%d: set_risc_jmp %08lx:",
- btv->nr,virt_to_bus(btv->risc_jmp));
-
- /* Sync to start of odd field */
- btv->risc_jmp[0]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC
- |BT848_FIFO_STATUS_VRE);
- btv->risc_jmp[1]=cpu_to_le32(0);
-
- /* Jump to odd vbi sub */
- btv->risc_jmp[2]=cpu_to_le32(BT848_RISC_JUMP|(0xd<<20));
- if (flags&8) {
- if (bttv_debug > 1)
- printk(" ev=%08lx",virt_to_bus(btv->vbi_odd));
- btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->vbi_odd));
- } else {
- if (bttv_debug > 1)
- printk(" -----------");
- btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
- }
-
- /* Jump to odd sub */
- btv->risc_jmp[4]=cpu_to_le32(BT848_RISC_JUMP|(0xe<<20));
- if (0 != btv->risc_cap_odd) {
- if (bttv_debug > 1)
- printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd);
- flags |= 3;
- btv->risc_jmp[5]=cpu_to_le32(btv->risc_cap_odd);
- } else if (flags&2) {
- if (bttv_debug > 1)
- printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd));
- btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_scr_odd));
- } else {
- if (bttv_debug > 1)
- printk(" -----------");
- btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_jmp+6));
- }
-
-
- /* Sync to start of even field */
- btv->risc_jmp[6]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC
- |BT848_FIFO_STATUS_VRO);
- btv->risc_jmp[7]=cpu_to_le32(0);
-
- /* Jump to even vbi sub */
- btv->risc_jmp[8]=cpu_to_le32(BT848_RISC_JUMP);
- if (flags&4) {
- if (bttv_debug > 1)
- printk(" ov=%08lx",virt_to_bus(btv->vbi_even));
- btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->vbi_even));
- } else {
- if (bttv_debug > 1)
- printk(" -----------");
- btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
- }
-
- /* Jump to even sub */
- btv->risc_jmp[10]=cpu_to_le32(BT848_RISC_JUMP|(8<<20));
- if (0 != btv->risc_cap_even) {
- if (bttv_debug > 1)
- printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even);
- flags |= 3;
- btv->risc_jmp[11]=cpu_to_le32(btv->risc_cap_even);
- } else if (flags&1) {
- if (bttv_debug > 1)
- printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even));
- btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_scr_even));
- } else {
- if (bttv_debug > 1)
- printk(" -----------");
- btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12));
- }
-
- if (btv->gq_start) {
- btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ);
- } else {
- btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP);
- }
- btv->risc_jmp[13]=cpu_to_le32(virt_to_bus(btv->risc_jmp));
-
- /* enable cpaturing and DMA */
- if (bttv_debug > 1)
- printk(" flags=0x%x dma=%s\n",
- flags,(flags&0x0f) ? "on" : "off");
- btaor(flags, ~0x0f, BT848_CAP_CTL);
- if (flags&0x0f)
- bt848_dma(btv, 3);
- else
- bt848_dma(btv, 0);
-}
-
-static int __devinit init_video_dev(struct bttv *btv)
-{
- memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template));
- memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template));
- memcpy(&btv->radio_dev,&radio_template,sizeof(radio_template));
-
- bttv_idcard(btv);
- audio(btv, AUDIO_MUTE, 1);
-
- if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER)<0)
- return -1;
- if(video_register_device(&btv->vbi_dev,VFL_TYPE_VBI)<0)
- {
- video_unregister_device(&btv->video_dev);
- return -1;
- }
- if (radio[btv->nr])
- {
- if(video_register_device(&btv->radio_dev, VFL_TYPE_RADIO)<0)
- {
- video_unregister_device(&btv->vbi_dev);
- video_unregister_device(&btv->video_dev);
- return -1;
- }
- }
- return 1;
-}
-
-static int __devinit init_bt848(struct bttv *btv)
-{
- int j;
- unsigned long irq_flags;
-
- btv->user=0;
- init_MUTEX(&btv->lock);
-
- /* dump current state of the gpio registers before changing them,
- * might help to make a new card work */
- if (bttv_verbose >= 2)
- printk("bttv%d: gpio: out_enable=0x%x, data=0x%x, in=0x%x\n",
- btv->nr,
- btread(BT848_GPIO_OUT_EN),
- btread(BT848_GPIO_DATA),
- btread(BT848_GPIO_REG_INP));
-
- /* reset the bt848 */
- btwrite(0, BT848_SRESET);
- DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%lx\n", btv->nr, (unsigned long) btv->bt848_mem));
-
- /* not registered yet */
- btv->video_dev.minor = -1;
- btv->radio_dev.minor = -1;
- btv->vbi_dev.minor = -1;
-
- /* default setup for max. PAL size in a 1024xXXX hicolor framebuffer */
- btv->win.norm=0; /* change this to 1 for NTSC, 2 for SECAM */
- btv->win.interlace=1;
- btv->win.x=0;
- btv->win.y=0;
- btv->win.width=768; /* 640 */
- btv->win.height=576; /* 480 */
- btv->win.bpp=2;
- btv->win.depth=16;
- btv->win.color_fmt=BT848_COLOR_FMT_RGB16;
- btv->win.bpl=1024*btv->win.bpp;
- btv->win.swidth=1024;
- btv->win.sheight=768;
- btv->win.vidadr=0;
- btv->vbi_on=0;
- btv->scr_on=0;
-
- btv->risc_scr_odd=0;
- btv->risc_scr_even=0;
- btv->risc_cap_odd=0;
- btv->risc_cap_even=0;
- btv->risc_jmp=0;
- btv->vbibuf=0;
- btv->field=btv->last_field=0;
-
- btv->errors=0;
- btv->needs_restart=0;
-
- /* i2c */
- btv->tuner_type=-1;
- init_bttv_i2c(btv);
-
- if (!(btv->risc_scr_odd=(unsigned int *) kmalloc(RISCMEM_LEN/2, GFP_KERNEL)))
- return -1;
- if (!(btv->risc_scr_even=(unsigned int *) kmalloc(RISCMEM_LEN/2, GFP_KERNEL)))
- return -1;
- if (!(btv->risc_jmp =(unsigned int *) kmalloc(2048, GFP_KERNEL)))
- return -1;
- btv->vbi_odd=btv->risc_jmp+16;
- btv->vbi_even=btv->vbi_odd+256;
- btv->bus_vbi_odd=virt_to_bus(btv->risc_jmp+12);
- btv->bus_vbi_even=virt_to_bus(btv->risc_jmp+6);
-
- btwrite(virt_to_bus(btv->risc_jmp+2), BT848_RISC_STRT_ADD);
- btv->vbibuf=(unsigned char *) vmalloc_32(VBIBUF_SIZE);
- if (!btv->vbibuf)
- return -1;
- if (!(btv->gbuf = kmalloc(sizeof(struct bttv_gbuf)*gbuffers,GFP_KERNEL)))
- return -1;
- for (j = 0; j < gbuffers; j++) {
- if (!(btv->gbuf[j].risc = kmalloc(16384,GFP_KERNEL)))
- return -1;
- }
-
- memset(btv->vbibuf, 0, VBIBUF_SIZE); /* We don't want to return random
- memory to the user */
-
- btv->fbuffer=NULL;
-
- bt848_muxsel(btv, 1);
- bt848_set_winsize(btv);
-
-/* btwrite(0, BT848_TDEC); */
- btwrite(0x10, BT848_COLOR_CTL);
- btwrite(0x00, BT848_CAP_CTL);
- /* set planar and packed mode trigger points and */
- /* set rising edge of inverted GPINTR pin as irq trigger */
- btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
- BT848_GPIO_DMA_CTL_PLTP1_16|
- BT848_GPIO_DMA_CTL_PLTP23_16|
- BT848_GPIO_DMA_CTL_GPINTC|
- BT848_GPIO_DMA_CTL_GPINTI,
- BT848_GPIO_DMA_CTL);
-
- /* select direct input */
- btwrite(0x00, BT848_GPIO_REG_INP);
-
- btwrite(BT848_IFORM_MUX1 | BT848_IFORM_XTAUTO | BT848_IFORM_AUTO,
- BT848_IFORM);
-
- btwrite(0xd8, BT848_CONTRAST_LO);
- bt848_bright(btv, 0x10);
-
- btwrite(0x20, BT848_E_VSCALE_HI);
- btwrite(0x20, BT848_O_VSCALE_HI);
- btwrite(/*BT848_ADC_SYNC_T|*/
- BT848_ADC_RESERVED|BT848_ADC_CRUSH, BT848_ADC);
-
- btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);
- btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);
-
- btv->picture.colour=254<<7;
- btv->picture.brightness=128<<8;
- btv->picture.hue=128<<8;
- btv->picture.contrast=0xd8<<7;
-
- btwrite(0x00, BT848_E_SCLOOP);
- btwrite(0x00, BT848_O_SCLOOP);
-
- /* clear interrupt status */
- btwrite(0xfffffUL, BT848_INT_STAT);
-
- /* set interrupt mask */
- btwrite(btv->triton1|
- /*BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
- BT848_INT_FDSR|BT848_INT_FTRGT|BT848_INT_FBUS|*/
- (fieldnr ? BT848_INT_VSYNC : 0)|
- BT848_INT_GPINT|
- BT848_INT_SCERR|
- BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
- BT848_INT_FMTCHG|BT848_INT_HLOCK,
- BT848_INT_MASK);
-
- make_vbitab(btv);
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_risc_jmps(btv,-1);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
-
- /*
- * Now add the template and register the device unit.
- */
- init_video_dev(btv);
-
- return 0;
-}
-
-static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
-{
- u32 stat,astat;
- u32 dstat;
- int count,i;
- struct bttv *btv;
-
- btv=(struct bttv *)dev_id;
- count=0;
- while (1)
- {
- /* get/clear interrupt status bits */
- stat=btread(BT848_INT_STAT);
- astat=stat&btread(BT848_INT_MASK);
- if (!astat)
- return;
- btwrite(astat,BT848_INT_STAT);
- IDEBUG(printk ("bttv%d: astat=%08x\n", btv->nr, astat));
- IDEBUG(printk ("bttv%d: stat=%08x\n", btv->nr, stat));
-
- /* get device status bits */
- dstat=btread(BT848_DSTATUS);
-
- if (astat&BT848_INT_GPINT) {
- IDEBUG(printk ("bttv%d: IRQ_GPINT\n", btv->nr));
- wake_up_interruptible(&btv->gpioq);
- }
-
- if (astat&BT848_INT_FMTCHG)
- {
- IDEBUG(printk ("bttv%d: IRQ_FMTCHG\n", btv->nr));
- /*btv->win.norm&=
- (dstat&BT848_DSTATUS_NUML) ? (~1) : (~0); */
- }
- if (astat&BT848_INT_VPRES)
- {
- IDEBUG(printk ("bttv%d: IRQ_VPRES\n", btv->nr));
- }
- if (astat&BT848_INT_VSYNC)
- {
- IDEBUG(printk ("bttv%d: IRQ_VSYNC\n", btv->nr));
- btv->field++;
- }
- if (astat&(BT848_INT_SCERR|BT848_INT_OCERR)) {
- if (bttv_verbose)
- printk("bttv%d: irq:%s%s risc_count=%08x\n",
- btv->nr,
- (astat&BT848_INT_SCERR) ? " SCERR" : "",
- (astat&BT848_INT_OCERR) ? " OCERR" : "",
- btread(BT848_RISC_COUNT));
- btv->errors++;
- if (btv->errors < BTTV_ERRORS) {
- spin_lock(&btv->s_lock);
- btand(~15, BT848_GPIO_DMA_CTL);
- btwrite(virt_to_bus(btv->risc_jmp+2),
- BT848_RISC_STRT_ADD);
- bt848_set_geo(btv,0);
- bt848_set_risc_jmps(btv,-1);
- spin_unlock(&btv->s_lock);
- } else {
- if (bttv_verbose)
- printk("bttv%d: aiee: error loops\n",btv->nr);
- /* cancel all outstanding grab requests */
- spin_lock(&btv->s_lock);
- btv->gq_in = 0;
- btv->gq_out = 0;
- btv->gq_grab = -1;
- for (i = 0; i < gbuffers; i++)
- if (btv->gbuf[i].stat == GBUFFER_GRABBING)
- btv->gbuf[i].stat = GBUFFER_ERROR;
- /* disable DMA */
- btv->risc_cap_odd = 0;
- btv->risc_cap_even = 0;
- bt848_set_risc_jmps(btv,0);
- btv->needs_restart = 1;
- spin_unlock(&btv->s_lock);
-
- wake_up_interruptible(&btv->vbiq);
- wake_up_interruptible(&btv->capq);
- }
- }
- if (astat&BT848_INT_RISCI)
- {
- if (bttv_debug > 1)
- printk("bttv%d: IRQ_RISCI\n",btv->nr);
-
- /* captured VBI frame */
- if (stat&(1<<28))
- {
- btv->vbip=0;
- /* inc vbi frame count for detecting drops */
- (*(u32 *)&(btv->vbibuf[VBIBUF_SIZE - 4]))++;
- wake_up_interruptible(&btv->vbiq);
- }
-
- /* captured full frame */
- if (stat&(2<<28) && btv->gq_grab != -1)
- {
- btv->last_field=btv->field;
- if (bttv_debug)
- printk("bttv%d: cap irq: done %d\n",btv->nr,btv->gq_grab);
- do_gettimeofday(&btv->gbuf[btv->gq_grab].tv);
- spin_lock(&btv->s_lock);
- btv->gbuf[btv->gq_grab].stat = GBUFFER_DONE;
- btv->gq_grab = -1;
- if (btv->gq_in != btv->gq_out)
- {
- btv->gq_grab = btv->gqueue[btv->gq_out++];
- btv->gq_out = btv->gq_out % MAX_GBUFFERS;
- if (bttv_debug)
- printk("bttv%d: cap irq: capture %d\n",btv->nr,btv->gq_grab);
- btv->risc_cap_odd = btv->gbuf[btv->gq_grab].ro;
- btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
- bt848_set_risc_jmps(btv,-1);
- bt848_set_geo(btv,0);
- btwrite(BT848_COLOR_CTL_GAMMA,
- BT848_COLOR_CTL);
- } else {
- btv->risc_cap_odd = 0;
- btv->risc_cap_even = 0;
- bt848_set_risc_jmps(btv,-1);
- bt848_set_geo(btv,0);
- btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA,
- BT848_COLOR_CTL);
- }
- spin_unlock(&btv->s_lock);
- wake_up_interruptible(&btv->capq);
- break;
- }
- if (stat&(8<<28))
- {
- spin_lock(&btv->s_lock);
- btv->gq_start = 0;
- btv->gq_grab = btv->gqueue[btv->gq_out++];
- btv->gq_out = btv->gq_out % MAX_GBUFFERS;
- if (bttv_debug)
- printk("bttv%d: cap irq: capture %d [start]\n",btv->nr,btv->gq_grab);
- btv->risc_cap_odd = btv->gbuf[btv->gq_grab].ro;
- btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
- bt848_set_risc_jmps(btv,-1);
- bt848_set_geo(btv,0);
- btwrite(BT848_COLOR_CTL_GAMMA,
- BT848_COLOR_CTL);
- spin_unlock(&btv->s_lock);
- }
- }
- if (astat&BT848_INT_OCERR)
- {
- IDEBUG(printk ("bttv%d: IRQ_OCERR\n", btv->nr));
- }
- if (astat&BT848_INT_PABORT)
- {
- IDEBUG(printk ("bttv%d: IRQ_PABORT\n", btv->nr));
- }
- if (astat&BT848_INT_RIPERR)
- {
- IDEBUG(printk ("bttv%d: IRQ_RIPERR\n", btv->nr));
- }
- if (astat&BT848_INT_PPERR)
- {
- IDEBUG(printk ("bttv%d: IRQ_PPERR\n", btv->nr));
- }
- if (astat&BT848_INT_FDSR)
- {
- IDEBUG(printk ("bttv%d: IRQ_FDSR\n", btv->nr));
- }
- if (astat&BT848_INT_FTRGT)
- {
- IDEBUG(printk ("bttv%d: IRQ_FTRGT\n", btv->nr));
- }
- if (astat&BT848_INT_FBUS)
- {
- IDEBUG(printk ("bttv%d: IRQ_FBUS\n", btv->nr));
- }
- if (astat&BT848_INT_HLOCK)
- {
- if ((dstat&BT848_DSTATUS_HLOC) || (btv->radio))
- audio(btv, AUDIO_ON,0);
- else
- audio(btv, AUDIO_OFF,0);
- }
-
- if (astat&BT848_INT_I2CDONE)
- {
- IDEBUG(printk ("bttv%d: IRQ_I2CDONE\n", btv->nr));
- }
- count++;
- if (count > 10)
- printk (KERN_WARNING "bttv%d: irq loop %d\n",
- btv->nr,count);
- if (count > 20)
- {
- btwrite(0, BT848_INT_MASK);
- printk(KERN_ERR
- "bttv%d: IRQ lockup, cleared int mask\n", btv->nr);
- }
- }
-}
-
-
-
-/*
- * Scan for a Bt848 card, request the irq and map the io memory
- */
-
-static void __devinit bttv_remove(struct pci_dev *pci_dev)
-{
- u8 command;
- int j;
- struct bttv *btv = PCI_GET_DRIVER_DATA(pci_dev);
-
- /* unregister i2c_bus */
- if (0 == btv->i2c_ok)
- i2c_bit_del_bus(&btv->i2c_adap);
-
- /* turn off all capturing, DMA and IRQs */
- btand(~15, BT848_GPIO_DMA_CTL);
-
- /* first disable interrupts before unmapping the memory! */
- btwrite(0, BT848_INT_MASK);
- btwrite(~0x0UL,BT848_INT_STAT);
- btwrite(0x0, BT848_GPIO_OUT_EN);
-
- /* disable PCI bus-mastering */
- pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
- /* Should this be &=~ ?? */
- command&=~PCI_COMMAND_MASTER;
- pci_write_config_byte(btv->dev, PCI_COMMAND, command);
-
- /* unmap and free memory */
- for (j = 0; j < gbuffers; j++)
- if (btv->gbuf[j].risc)
- kfree(btv->gbuf[j].risc);
- if (btv->gbuf)
- kfree((void *) btv->gbuf);
-
- if (btv->risc_scr_odd)
- kfree((void *) btv->risc_scr_odd);
-
- if (btv->risc_scr_even)
- kfree((void *) btv->risc_scr_even);
-
- DEBUG(printk(KERN_DEBUG "free: risc_jmp: 0x%p.\n", btv->risc_jmp));
- if (btv->risc_jmp)
- kfree((void *) btv->risc_jmp);
-
- DEBUG(printk(KERN_DEBUG "bt848_vbibuf: 0x%p.\n", btv->vbibuf));
- if (btv->vbibuf)
- vfree((void *) btv->vbibuf);
-
- free_irq(btv->irq,btv);
- DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%p.\n", btv->bt848_mem));
- if (btv->bt848_mem)
- iounmap(btv->bt848_mem);
-
- if(btv->video_dev.minor!=-1)
- video_unregister_device(&btv->video_dev);
- if(btv->vbi_dev.minor!=-1)
- video_unregister_device(&btv->vbi_dev);
- if (radio[btv->nr] && btv->radio_dev.minor != -1)
- video_unregister_device(&btv->radio_dev);
-
- release_mem_region(btv->bt848_adr,
- pci_resource_len(btv->dev,0));
- /* wake up any waiting processes
- because shutdown flag is set, no new processes (in this queue)
- are expected
- */
- btv->shutdown=1;
- wake_up(&btv->gpioq);
-
- return;
-}
-
-
-static int __devinit bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
-{
- int result;
- unsigned char command;
- struct bttv *btv;
-#if defined(__powerpc__)
- unsigned int cmd;
-#endif
-
- printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
-
- btv=&bttvs[bttv_num];
- btv->dev=dev;
- btv->nr = bttv_num;
- btv->bt848_mem=NULL;
- btv->vbibuf=NULL;
- btv->risc_jmp=NULL;
- btv->vbi_odd=NULL;
- btv->vbi_even=NULL;
- init_waitqueue_head(&btv->vbiq);
- init_waitqueue_head(&btv->capq);
- btv->vbip=VBIBUF_SIZE;
- btv->s_lock = SPIN_LOCK_UNLOCKED;
- init_waitqueue_head(&btv->gpioq);
- btv->shutdown=0;
-
- btv->id=dev->device;
- btv->irq=dev->irq;
- btv->bt848_adr=pci_resource_start(dev,0);
- if (pci_enable_device(dev))
- return -EIO;
- if (!request_mem_region(pci_resource_start(dev,0),
- pci_resource_len(dev,0),
- "bttv")) {
- return -EBUSY;
- }
- if (btv->id >= 878)
- btv->i2c_command = 0x83;
- else
- btv->i2c_command=(I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA);
-
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
- printk(KERN_INFO "bttv%d: Brooktree Bt%d (rev %d) ",
- bttv_num,btv->id, btv->revision);
- printk("bus: %d, devfn: %d, ",dev->bus->number, dev->devfn);
- printk("irq: %d, ",btv->irq);
- printk("memory: 0x%lx.\n", btv->bt848_adr);
-
-#if defined(__powerpc__)
- /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
- /* response on cards with no firmware is not enabled by OF */
- pci_read_config_dword(dev, PCI_COMMAND, &cmd);
- cmd = (cmd | PCI_COMMAND_MEMORY );
- pci_write_config_dword(dev, PCI_COMMAND, cmd);
-#endif
-
-#ifdef __sparc__
- btv->bt848_mem=(unsigned char *)btv->bt848_adr;
-#else
- btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
-#endif
-
- /* clear interrupt mask */
- btwrite(0, BT848_INT_MASK);
-
- result = request_irq(btv->irq, bttv_irq,
- SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
- if (result==-EINVAL)
- {
- printk(KERN_ERR "bttv%d: Bad irq number or handler\n",
- bttv_num);
- goto fail;
- }
- if (result==-EBUSY)
- {
- printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
- goto fail;
- }
- if (result < 0)
- goto fail;
-
- pci_set_master(dev);
-
- btv->triton1=triton1 ? BT848_INT_ETBF : 0;
- if (triton1 && btv->id >= 878)
- {
- btv->triton1 = 0;
- printk("bttv: Enabling 430FX compatibilty for bt878\n");
- pci_read_config_byte(dev, BT878_DEVCTRL, &command);
- command|=BT878_EN_TBFX;
- pci_write_config_byte(dev, BT878_DEVCTRL, command);
- pci_read_config_byte(dev, BT878_DEVCTRL, &command);
- if (!(command&BT878_EN_TBFX))
- {
- printk("bttv: 430FX compatibility could not be enabled\n");
- free_irq(btv->irq,btv);
- result = -1;
- goto fail;
- }
- }
-
- PCI_SET_DRIVER_DATA(dev,btv);
-
- if(init_bt848(btv) < 0) {
- bttv_remove(dev);
- return -EIO;
- }
- bttv_num++;
-
- return 0;
-
- fail:
- release_mem_region(pci_resource_start(btv->dev,0),
- pci_resource_len(btv->dev,0));
- return result;
-}
-
-static struct pci_device_id bttv_pci_tbl[] __devinitdata = {
- {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
-
-static struct pci_driver bttv_pci_driver = {
- name: "bttv",
- id_table: bttv_pci_tbl,
- probe: bttv_probe,
- remove: bttv_remove,
-};
-
-int bttv_init_module(void)
-{
- bttv_num = 0;
-
- printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
- (BTTV_VERSION_CODE >> 16) & 0xff,
- (BTTV_VERSION_CODE >> 8) & 0xff,
- BTTV_VERSION_CODE & 0xff);
- if (gbuffers < 2 || gbuffers > MAX_GBUFFERS)
- gbuffers = 2;
- if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF)
- gbufsize = BTTV_MAX_FBUF;
- if (bttv_verbose)
- printk(KERN_INFO "bttv: using %d buffers with %dk (%dk total) for capture\n",
- gbuffers,gbufsize/1024,gbuffers*gbufsize/1024);
-
- handle_chipset();
-
- return pci_module_init(&bttv_pci_driver);
-}
-
-void bttv_cleanup_module(void)
-{
- pci_unregister_driver(&bttv_pci_driver);
- return;
-}
-
-module_init(bttv_init_module);
-module_exit(bttv_cleanup_module);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/bttv-if.c b/drivers/char/bttv-if.c
deleted file mode 100644
index a58e441db..000000000
--- a/drivers/char/bttv-if.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- bttv-if.c -- interfaces to other kernel modules
- all the i2c code is here
- also the gpio interface exported by bttv (used by lirc)
-
-
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.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 of the License, 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.
-
-*/
-
-#define __NO_VERSION__ 1
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-#include "bttv.h"
-#include "tuner.h"
-
-
-EXPORT_SYMBOL(bttv_get_cardinfo);
-EXPORT_SYMBOL(bttv_get_id);
-EXPORT_SYMBOL(bttv_gpio_enable);
-EXPORT_SYMBOL(bttv_read_gpio);
-EXPORT_SYMBOL(bttv_write_gpio);
-EXPORT_SYMBOL(bttv_get_gpio_queue);
-
-/* ----------------------------------------------------------------------- */
-/* Exported functions - for other modules which want to access the */
-/* gpio ports (IR for example) */
-/* see bttv.h for comments */
-
-int bttv_get_cardinfo(unsigned int card, int *type, int *cardid)
-{
- if (card >= bttv_num) {
- return -1;
- }
- *type = bttvs[card].type;
- *cardid = bttvs[card].cardid;
- return 0;
-}
-
-int bttv_get_id(unsigned int card)
-{
- printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n");
- if (card >= bttv_num) {
- return -1;
- }
- return bttvs[card].type;
-}
-
-int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
-{
- struct bttv *btv;
-
- if (card >= bttv_num) {
- return -EINVAL;
- }
-
- btv = &bttvs[card];
- btaor(data, ~mask, BT848_GPIO_OUT_EN);
- return 0;
-}
-
-int bttv_read_gpio(unsigned int card, unsigned long *data)
-{
- struct bttv *btv;
-
- if (card >= bttv_num) {
- return -EINVAL;
- }
-
- btv = &bttvs[card];
-
- if(btv->shutdown) {
- return -ENODEV;
- }
-
-/* prior setting BT848_GPIO_REG_INP is (probably) not needed
- because we set direct input on init */
- *data = btread(BT848_GPIO_DATA);
- return 0;
-}
-
-int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
-{
- struct bttv *btv;
-
- if (card >= bttv_num) {
- return -EINVAL;
- }
-
- btv = &bttvs[card];
-
-/* prior setting BT848_GPIO_REG_INP is (probably) not needed
- because direct input is set on init */
- btaor(data & mask, ~mask, BT848_GPIO_DATA);
- return 0;
-}
-
-wait_queue_head_t* bttv_get_gpio_queue(unsigned int card)
-{
- struct bttv *btv;
-
- if (card >= bttv_num) {
- return NULL;
- }
-
- btv = &bttvs[card];
- if (bttvs[card].shutdown) {
- return NULL;
- }
- return &btv->gpioq;
-}
-
-
-/* ----------------------------------------------------------------------- */
-/* I2C functions */
-
-void bttv_bit_setscl(void *data, int state)
-{
- struct bttv *btv = (struct bttv*)data;
-
- if (state)
- btv->i2c_state |= 0x02;
- else
- btv->i2c_state &= ~0x02;
- btwrite(btv->i2c_state, BT848_I2C);
- btread(BT848_I2C);
-}
-
-void bttv_bit_setsda(void *data, int state)
-{
- struct bttv *btv = (struct bttv*)data;
-
- if (state)
- btv->i2c_state |= 0x01;
- else
- btv->i2c_state &= ~0x01;
- btwrite(btv->i2c_state, BT848_I2C);
- btread(BT848_I2C);
-}
-
-static int bttv_bit_getscl(void *data)
-{
- struct bttv *btv = (struct bttv*)data;
- int state;
-
- state = btread(BT848_I2C) & 0x02 ? 1 : 0;
- return state;
-}
-
-static int bttv_bit_getsda(void *data)
-{
- struct bttv *btv = (struct bttv*)data;
- int state;
-
- state = btread(BT848_I2C) & 0x01;
- return state;
-}
-
-static void bttv_inc_use(struct i2c_adapter *adap)
-{
- MOD_INC_USE_COUNT;
-}
-
-static void bttv_dec_use(struct i2c_adapter *adap)
-{
- MOD_DEC_USE_COUNT;
-}
-
-static int attach_inform(struct i2c_client *client)
-{
- struct bttv *btv = (struct bttv*)client->adapter->data;
- int i;
-
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- if (btv->i2c_clients[i] == NULL ||
- btv->i2c_clients[i]->driver->id == client->driver->id) {
- btv->i2c_clients[i] = client;
- break;
- }
- }
- if (btv->tuner_type != -1)
- bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
- if (bttv_verbose)
- printk("bttv%d: i2c attach [%s]\n",btv->nr,client->name);
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct bttv *btv = (struct bttv*)client->adapter->data;
- int i;
-
- if (bttv_verbose)
- printk("bttv%d: i2c detach [%s]\n",btv->nr,client->name);
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- if (NULL != btv->i2c_clients[i] &&
- btv->i2c_clients[i]->driver->id == client->driver->id) {
- btv->i2c_clients[i] = NULL;
- break;
- }
- }
- return 0;
-}
-
-void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
-{
- int i;
-
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- if (NULL == btv->i2c_clients[i])
- continue;
- if (NULL == btv->i2c_clients[i]->driver->command)
- continue;
- btv->i2c_clients[i]->driver->command(
- btv->i2c_clients[i],cmd,arg);
- }
-}
-
-struct i2c_algo_bit_data bttv_i2c_algo_template = {
- NULL,
- bttv_bit_setsda,
- bttv_bit_setscl,
- bttv_bit_getsda,
- bttv_bit_getscl,
- 10, 10, 100,
-};
-
-struct i2c_adapter bttv_i2c_adap_template = {
- "bt848",
- I2C_HW_B_BT848,
- NULL,
- NULL,
- bttv_inc_use,
- bttv_dec_use,
- attach_inform,
- detach_inform,
- NULL,
-};
-
-struct i2c_client bttv_i2c_client_template = {
- "bttv internal",
- -1,
- 0,
- 0,
- NULL,
- NULL
-};
-
-
-/* read I2C */
-int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
-{
- unsigned char buffer = 0;
-
- if (0 != btv->i2c_ok)
- return -1;
- if (bttv_verbose && NULL != probe_for)
- printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
- btv->nr,probe_for,addr);
- btv->i2c_client.addr = addr >> 1;
- if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
- if (NULL != probe_for) {
- if (bttv_verbose)
- printk("not found\n");
- } else
- printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
- btv->nr,addr);
- return -1;
- }
- if (bttv_verbose && NULL != probe_for)
- printk("found\n");
- return buffer;
-}
-
-/* write I2C */
-int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
- unsigned char b2, int both)
-{
- unsigned char buffer[2];
- int bytes = both ? 2 : 1;
-
- if (0 != btv->i2c_ok)
- return -1;
- btv->i2c_client.addr = addr >> 1;
- buffer[0] = b1;
- buffer[1] = b2;
- if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
- return -1;
- return 0;
-}
-
-/* read EEPROM content */
-void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
-{
- int i;
-
- if (bttv_I2CWrite(btv, addr, 0, -1, 0)<0) {
- printk(KERN_WARNING "bttv: readee error\n");
- return;
- }
- btv->i2c_client.addr = addr >> 1;
- for (i=0; i<256; i+=16) {
- if (16 != i2c_master_recv(&btv->i2c_client,eedata+i,16)) {
- printk(KERN_WARNING "bttv: readee error\n");
- break;
- }
- }
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/bttv.h b/drivers/char/bttv.h
deleted file mode 100644
index 6b35d23e5..000000000
--- a/drivers/char/bttv.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.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 of the License, 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.
-*/
-
-#ifndef _BTTV_H_
-#define _BTTV_H_
-
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,38)
-
-#ifndef PCI_GET_DRIVER_DATA
-# define PCI_GET_DRIVER_DATA(pdev) ((pdev)->driver_data)
-# define PCI_SET_DRIVER_DATA(pdev,data) (((pdev)->driver_data) = (data))
-#endif /* PCI_GET_DRIVER_DATA */
-
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/videodev.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "audiochip.h"
-#include "bt848.h"
-
-#ifdef __KERNEL__
-
-/* fwd decl */
-struct bttv;
-
-
-/* ---------------------------------------------------------- */
-/* exported by bttv-cards.c */
-
-#define BTTV_UNKNOWN 0x00
-#define BTTV_MIRO 0x01
-#define BTTV_HAUPPAUGE 0x02
-#define BTTV_STB 0x03
-#define BTTV_INTEL 0x04
-#define BTTV_DIAMOND 0x05
-#define BTTV_AVERMEDIA 0x06
-#define BTTV_MATRIX_VISION 0x07
-#define BTTV_FLYVIDEO 0x08
-#define BTTV_TURBOTV 0x09
-#define BTTV_HAUPPAUGE878 0x0a
-#define BTTV_MIROPRO 0x0b
-#define BTTV_ADSTECH_TV 0x0c
-#define BTTV_AVERMEDIA98 0x0d
-#define BTTV_VHX 0x0e
-#define BTTV_ZOLTRIX 0x0f
-#define BTTV_PIXVIEWPLAYTV 0x10
-#define BTTV_WINVIEW_601 0x11
-#define BTTV_AVEC_INTERCAP 0x12
-#define BTTV_LIFE_FLYKIT 0x13
-#define BTTV_CEI_RAFFLES 0x14
-#define BTTV_CONFERENCETV 0x15
-#define BTTV_PHOEBE_TVMAS 0x16
-#define BTTV_MODTEC_205 0x17
-#define BTTV_MAGICTVIEW061 0x18
-#define BTTV_VOBIS_BOOSTAR 0x19
-#define BTTV_HAUPPAUG_WCAM 0x1a
-#define BTTV_MAXI 0x1b
-#define BTTV_TERRATV 0x1c
-#define BTTV_PXC200 0x1d
-#define BTTV_FLYVIDEO_98 0x1e
-#define BTTV_IPROTV 0x1f
-#define BTTV_INTEL_C_S_PCI 0x20
-#define BTTV_TERRATVALUE 0x21
-#define BTTV_WINFAST2000 0x22
-#define BTTV_CHRONOS_VS2 0x23
-#define BTTV_TYPHOON_TVIEW 0x24
-#define BTTV_PXELVWPLTVPRO 0x25
-#define BTTV_MAGICTVIEW063 0x26
-#define BTTV_PINNACLERAVE 0x27
-#define BTTV_STB2 0x28
-#define BTTV_AVPHONE98 0x29
-#define BTTV_PV951 0x2a
-#define BTTV_ONAIR_TV 0x2b
-#define BTTV_SIGMA_TVII_FM 0x2c
-#define BTTV_MATRIX_VISION2 0x2d
-#define BTTV_ZOLTRIX_GENIE 0x2e
-#define BTTV_TERRATVRADIO 0x2f
-#define BTTV_DYNALINK 0x30
-
-struct tvcard
-{
- char *name;
- int video_inputs;
- int audio_inputs;
- int tuner;
- int svhs;
- u32 gpiomask;
- u32 muxsel[8];
- u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
- u32 gpiomask2; /* GPIO MUX mask */
-
- /* look for these i2c audio chips */
- int msp34xx:1;
- int tda8425:1;
- int tda9840:1;
- int tda985x:1;
- int tea63xx:1;
- int tea64xx:1;
- int tda7432:1;
- int tda9875:1;
-
- /* other settings */
- int pll;
-#define PLL_NONE 0
-#define PLL_28 1
-#define PLL_35 2
-
- int tuner_type;
-};
-
-extern struct tvcard bttv_tvcards[];
-extern const int bttv_num_tvcards;
-
-/* identification / initialization of the card */
-extern void bttv_idcard(struct bttv *btv);
-
-/* card-specific funtions */
-extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void winview_setvol(struct bttv *btv, struct video_audio *v);
-
-/* ---------------------------------------------------------- */
-/* exported by bttv-if.c */
-/* interface for gpio access by other modules */
-
-/* returns card type + card ID (for bt878-based ones)
- for possible values see lines below beginning with #define BTTV_UNKNOWN
- returns negative value if error ocurred
-*/
-extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid);
-
-/* obsolete, use bttv_get_cardinfo instead */
-extern int bttv_get_id(unsigned int card);
-
-/* sets GPOE register (BT848_GPIO_OUT_EN) to new value:
- data | (current_GPOE_value & ~mask)
- returns negative value if error ocurred
-*/
-extern int bttv_gpio_enable(unsigned int card,
- unsigned long mask, unsigned long data);
-
-/* fills data with GPDATA register contents
- returns negative value if error ocurred
-*/
-extern int bttv_read_gpio(unsigned int card, unsigned long *data);
-
-/* sets GPDATA register to new value:
- (data & mask) | (current_GPDATA_value & ~mask)
- returns negative value if error ocurred
-*/
-extern int bttv_write_gpio(unsigned int card,
- unsigned long mask, unsigned long data);
-
-/* returns pointer to task queue which can be used as parameter to
- interruptible_sleep_on
- in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated
- (wake_up_interruptible) and following call to the function bttv_read_gpio
- should return new value of GPDATA,
- returns NULL value if error ocurred or queue is not available
- WARNING: because there is no buffer for GPIO data, one MUST
- process data ASAP
-*/
-extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
-
-/* i2c */
-struct i2c_algo_bit_data bttv_i2c_algo_template;
-struct i2c_adapter bttv_i2c_adap_template;
-struct i2c_client bttv_i2c_client_template;
-void bttv_bit_setscl(void *data, int state);
-void bttv_bit_setsda(void *data, int state);
-void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
-int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
-int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
- unsigned char b2, int both);
-void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
-
-
-/* ---------------------------------------------------------- */
-/* bttv-driver.c */
-
-/* insmod options */
-extern unsigned int bttv_verbose;
-extern unsigned int bttv_debug;
-
-/* Anybody who uses more than four? */
-#define BTTV_MAX 4
-extern int bttv_num; /* number of Bt848s in use */
-extern struct bttv bttvs[BTTV_MAX];
-
-
-#ifndef O_NONCAP
-#define O_NONCAP O_TRUNC
-#endif
-
-#define MAX_GBUFFERS 64
-#define RISCMEM_LEN (32744*2)
-#define VBI_MAXLINES 16
-#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
-
-#define BTTV_MAX_FBUF 0x208000
-#define I2C_CLIENTS_MAX 8
-
-struct bttv_window
-{
- int x, y;
- ushort width, height;
- ushort bpp, bpl;
- ushort swidth, sheight;
- unsigned long vidadr;
- ushort freq;
- int norm;
- int interlace;
- int color_fmt;
- ushort depth;
-};
-
-struct bttv_pll_info {
- unsigned int pll_ifreq; /* PLL input frequency */
- unsigned int pll_ofreq; /* PLL output frequency */
- unsigned int pll_crystal; /* Crystal used for input */
- unsigned int pll_current; /* Currently programmed ofreq */
-};
-
-struct bttv_gbuf {
- int stat;
-#define GBUFFER_UNUSED 0
-#define GBUFFER_GRABBING 1
-#define GBUFFER_DONE 2
-#define GBUFFER_ERROR 3
- struct timeval tv;
-
- u16 width;
- u16 height;
- u16 fmt;
-
- u32 *risc;
- unsigned long ro;
- unsigned long re;
-};
-
-struct bttv {
- struct video_device video_dev;
- struct video_device radio_dev;
- struct video_device vbi_dev;
- struct video_picture picture; /* Current picture params */
- struct video_audio audio_dev; /* Current audio params */
-
- spinlock_t s_lock;
- struct semaphore lock;
- int user;
- int capuser;
-
- /* i2c */
- struct i2c_adapter i2c_adap;
- struct i2c_algo_bit_data i2c_algo;
- struct i2c_client i2c_client;
- int i2c_state, i2c_ok;
- struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
-
- int tuner_type;
- int channel;
-
- unsigned int nr;
- unsigned short id;
- struct pci_dev *dev;
- unsigned int irq; /* IRQ used by Bt848 card */
- unsigned char revision;
- unsigned long bt848_adr; /* bus address of IO mem returned by PCI BIOS */
- unsigned char *bt848_mem; /* pointer to mapped IO memory */
- unsigned long busriscmem;
- u32 *riscmem;
-
- unsigned char *vbibuf;
- struct bttv_window win;
- int fb_color_ctl;
- int type; /* card type */
- int cardid;
- int audio; /* audio mode */
- int audio_chip; /* set to one of the chips supported by bttv.c */
- int radio;
-
- u32 *risc_jmp;
- u32 *vbi_odd;
- u32 *vbi_even;
- u32 bus_vbi_even;
- u32 bus_vbi_odd;
- wait_queue_head_t vbiq;
- wait_queue_head_t capq;
- int vbip;
-
- u32 *risc_scr_odd;
- u32 *risc_scr_even;
- u32 risc_cap_odd;
- u32 risc_cap_even;
- int scr_on;
- int vbi_on;
- struct video_clip *cliprecs;
-
- struct bttv_gbuf *gbuf;
- int gqueue[MAX_GBUFFERS];
- int gq_in,gq_out,gq_grab,gq_start;
- char *fbuffer;
-
- struct bttv_pll_info pll;
- unsigned int Fsc;
- unsigned int field;
- unsigned int last_field; /* number of last grabbed field */
- int i2c_command;
- int triton1;
-
- int errors;
- int needs_restart;
-
- wait_queue_head_t gpioq;
- int shutdown;
-};
-#endif
-
-#if defined(__powerpc__) /* big-endian */
-extern __inline__ void io_st_le32(volatile unsigned *addr, unsigned val)
-{
- __asm__ __volatile__ ("stwbrx %1,0,%2" : \
- "=m" (*addr) : "r" (val), "r" (addr));
- __asm__ __volatile__ ("eieio" : : : "memory");
-}
-
-#define btwrite(dat,adr) io_st_le32((unsigned *)(btv->bt848_mem+(adr)),(dat))
-#define btread(adr) ld_le32((unsigned *)(btv->bt848_mem+(adr)))
-#else
-#define btwrite(dat,adr) writel((dat), (char *) (btv->bt848_mem+(adr)))
-#define btread(adr) readl(btv->bt848_mem+(adr))
-#endif
-
-#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
-#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
-#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-
-/* bttv ioctls */
-
-#define BTTV_READEE _IOW('v', BASE_VIDIOCPRIVATE+0, char [256])
-#define BTTV_WRITEE _IOR('v', BASE_VIDIOCPRIVATE+1, char [256])
-#define BTTV_FIELDNR _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)
-#define BTTV_PLLSET _IOW('v' , BASE_VIDIOCPRIVATE+3, struct bttv_pll_info)
-#define BTTV_BURST_ON _IOR('v' , BASE_VIDIOCPRIVATE+4, int)
-#define BTTV_BURST_OFF _IOR('v' , BASE_VIDIOCPRIVATE+5, int)
-#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int)
-#define BTTV_PICNR _IOR('v' , BASE_VIDIOCPRIVATE+7, int)
-#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int)
-
-#define AUDIO_TUNER 0x00
-#define AUDIO_RADIO 0x01
-#define AUDIO_EXTERN 0x02
-#define AUDIO_INTERN 0x03
-#define AUDIO_OFF 0x04
-#define AUDIO_ON 0x05
-#define AUDIO_MUTE 0x80
-#define AUDIO_UNMUTE 0x81
-
-#define TDA9850 0x01
-#define TDA9840 0x02
-#define TDA8425 0x03
-#define TEA6300 0x04
-
-#define I2C_TSA5522 0xc2
-#define I2C_TDA7432 0x8a
-#define I2C_TDA8425 0x82
-#define I2C_TDA9840 0x84
-#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */
-#define I2C_TDA9875 0xb0
-#define I2C_HAUPEE 0xa0
-#define I2C_STBEE 0xae
-#define I2C_VHX 0xc0
-#define I2C_MSP3400 0x80
-#define I2C_TEA6300 0x80
-#define I2C_DPL3518 0x84
-
-#ifndef HAVE_TVAUDIO
-#define TDA9840_SW 0x00
-#define TDA9840_LVADJ 0x02
-#define TDA9840_STADJ 0x03
-#define TDA9840_TEST 0x04
-#endif
-
-#define PT2254_L_CHANEL 0x10
-#define PT2254_R_CHANEL 0x08
-#define PT2254_DBS_IN_2 0x400
-#define PT2254_DBS_IN_10 0x20000
-#define WINVIEW_PT2254_CLK 0x40
-#define WINVIEW_PT2254_DATA 0x20
-#define WINVIEW_PT2254_STROBE 0x80
-
-struct bttv_just_hacking {
- int height,width; /* size */
- unsigned int format; /* should be VIDEO_PALETTE_* */
- long buf;
- int len;
-};
-
-#define BTTV_JUST_HACKING _IOR('v' , BASE_VIDIOCPRIVATE+31,struct bttv_just_hacking)
-
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/buz.c b/drivers/char/buz.c
deleted file mode 100644
index ca3cb4f47..000000000
--- a/drivers/char/buz.c
+++ /dev/null
@@ -1,3479 +0,0 @@
-#define MAX_KMALLOC_MEM (512*1024)
-/*
- buz - Iomega Buz driver version 1.0
-
- Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
-
- based on
-
- buz.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
-
- and
-
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.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 of the License, 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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <asm/segment.h>
-#include <linux/types.h>
-#include <linux/wrapper.h>
-#include <linux/spinlock.h>
-#include <linux/vmalloc.h>
-
-#include <linux/videodev.h>
-
-#include <linux/version.h>
-#include <asm/uaccess.h>
-
-#include <linux/i2c-old.h>
-#include "buz.h"
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
-
-#define IRQ_MASK ( ZR36057_ISR_GIRQ0 | /* ZR36057_ISR_GIRQ1 | ZR36057_ISR_CodRepIRQ | */ ZR36057_ISR_JPEGRepIRQ )
-#define GPIO_MASK 0xdf
-
-/*
-
- BUZ
-
- GPIO0 = 1, take board out of reset
- GPIO1 = 1, take JPEG codec out of sleep mode
- GPIO3 = 1, deassert FRAME# to 36060
-
-
- GIRQ0 signals a vertical sync of the video signal
- GIRQ1 signals that ZR36060's DATERR# line is asserted.
-
- SAA7111A
-
- In their infinite wisdom, the Iomega engineers decided to
- use the same input line for composite and S-Video Color,
- although there are two entries not connected at all!
- Through this ingenious strike, it is not possible to
- keep two running video sources connected at the same time
- to Composite and S-VHS input!
-
- mode 0 - N/C
- mode 1 - S-Video Y
- mode 2 - noise or something I don't know
- mode 3 - Composite and S-Video C
- mode 4 - N/C
- mode 5 - S-Video (gain C independently selectable of gain Y)
- mode 6 - N/C
- mode 7 - S-Video (gain C adapted to gain Y)
- */
-
-#define MAJOR_VERSION 1 /* driver major version */
-#define MINOR_VERSION 0 /* driver minor version */
-
-#define BUZ_NAME "Iomega BUZ V-1.0" /* name of the driver */
-
-#define DEBUG(x) /* Debug driver */
-#define IDEBUG(x) /* Debug interrupt handler */
-#define IOCTL_DEBUG(x)
-
-
-/* The parameters for this driver */
-
-/*
- The video mem address of the video card.
- The driver has a little database for some videocards
- to determine it from there. If your video card is not in there
- you have either to give it to the driver as a parameter
- or set in in a VIDIOCSFBUF ioctl
- */
-
-static unsigned long vidmem = 0; /* Video memory base address */
-
-/* Special purposes only: */
-
-static int triton = 0; /* 0=no, 1=yes */
-static int natoma = 0; /* 0=no, 1=yes */
-
-/*
- Number and size of grab buffers for Video 4 Linux
- The vast majority of applications should not need more than 2,
- the very popular BTTV driver actually does ONLY have 2.
- Time sensitive applications might need more, the maximum
- is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
-
- The size is set so that the maximum possible request
- can be satisfied. Decrease it, if bigphys_area alloc'd
- memory is low. If you don't have the bigphys_area patch,
- set it to 128 KB. Will you allow only to grab small
- images with V4L, but that's better than nothing.
-
- v4l_bufsize has to be given in KB !
-
- */
-
-static int v4l_nbufs = 2;
-static int v4l_bufsize = 128; /* Everybody should be able to work with this setting */
-
-/*
- Default input and video norm at startup of the driver.
- */
-
-static int default_input = 0; /* 0=Composite, 1=S-VHS */
-static int default_norm = 0; /* 0=PAL, 1=NTSC */
-
-MODULE_PARM(vidmem, "i");
-MODULE_PARM(triton, "i");
-MODULE_PARM(natoma, "i");
-MODULE_PARM(v4l_nbufs, "i");
-MODULE_PARM(v4l_bufsize, "i");
-MODULE_PARM(default_input, "i");
-MODULE_PARM(default_norm, "i");
-
-/* Anybody who uses more than four? */
-#define BUZ_MAX 4
-
-static int zoran_num; /* number of Buzs in use */
-static struct zoran zoran[BUZ_MAX];
-
-/* forward references */
-
-static void v4l_fbuffer_free(struct zoran *zr);
-static void jpg_fbuffer_free(struct zoran *zr);
-static void zoran_feed_stat_com(struct zoran *zr);
-
-
-
-/*
- * Allocate the V4L grab buffers
- *
- * These have to be pysically contiguous.
- * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
- */
-
-static int v4l_fbuffer_alloc(struct zoran *zr)
-{
- int i, off;
- unsigned char *mem;
-
- for (i = 0; i < v4l_nbufs; i++) {
- if (zr->v4l_gbuf[i].fbuffer)
- printk(KERN_WARNING "%s: v4l_fbuffer_alloc: buffer %d allready allocated ?\n", zr->name, i);
-
- if (v4l_bufsize <= MAX_KMALLOC_MEM) {
- /* Use kmalloc */
-
- mem = (unsigned char *) kmalloc(v4l_bufsize, GFP_KERNEL);
- if (mem == 0) {
- printk(KERN_ERR "%s: kmalloc for V4L bufs failed\n", zr->name);
- v4l_fbuffer_free(zr);
- return -ENOBUFS;
- }
- zr->v4l_gbuf[i].fbuffer = mem;
- zr->v4l_gbuf[i].fbuffer_phys = virt_to_phys(mem);
- zr->v4l_gbuf[i].fbuffer_bus = virt_to_bus(mem);
- for (off = 0; off < v4l_bufsize; off += PAGE_SIZE)
- mem_map_reserve(virt_to_page(mem + off));
- DEBUG(printk(BUZ_INFO ": V4L frame %d mem 0x%x (bus: 0x%x=%d)\n", i, mem, virt_to_bus(mem), virt_to_bus(mem)));
- } else {
- return -ENOBUFS;
- }
- }
-
- return 0;
-}
-
-/* free the V4L grab buffers */
-static void v4l_fbuffer_free(struct zoran *zr)
-{
- int i, off;
- unsigned char *mem;
-
- for (i = 0; i < v4l_nbufs; i++) {
- if (!zr->v4l_gbuf[i].fbuffer)
- continue;
-
- mem = zr->v4l_gbuf[i].fbuffer;
- for (off = 0; off < v4l_bufsize; off += PAGE_SIZE)
- mem_map_unreserve(virt_to_page(mem + off));
- kfree((void *) zr->v4l_gbuf[i].fbuffer);
- zr->v4l_gbuf[i].fbuffer = NULL;
- }
-}
-
-/*
- * Allocate the MJPEG grab buffers.
- *
- * If the requested buffer size is smaller than MAX_KMALLOC_MEM,
- * kmalloc is used to request a physically contiguous area,
- * else we allocate the memory in framgents with get_free_page.
- *
- * If a Natoma chipset is present and this is a revision 1 zr36057,
- * each MJPEG buffer needs to be physically contiguous.
- * (RJ: This statement is from Dave Perks' original driver,
- * I could never check it because I have a zr36067)
- * The driver cares about this because it reduces the buffer
- * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
- *
- * RJ: The contents grab buffers needs never be accessed in the driver.
- * Therefore there is no need to allocate them with vmalloc in order
- * to get a contiguous virtual memory space.
- * I don't understand why many other drivers first allocate them with
- * vmalloc (which uses internally also get_free_page, but delivers you
- * virtual addresses) and then again have to make a lot of efforts
- * to get the physical address.
- *
- */
-
-static int jpg_fbuffer_alloc(struct zoran *zr)
-{
- int i, j, off, alloc_contig;
- unsigned long mem;
-
- /* Decide if we should alloc contiguous or fragmented memory */
- /* This has to be identical in jpg_fbuffer_alloc and jpg_fbuffer_free */
-
- alloc_contig = (zr->jpg_bufsize < MAX_KMALLOC_MEM);
-
- for (i = 0; i < zr->jpg_nbufs; i++) {
- if (zr->jpg_gbuf[i].frag_tab)
- printk(KERN_WARNING "%s: jpg_fbuffer_alloc: buffer %d allready allocated ???\n", zr->name, i);
-
- /* Allocate fragment table for this buffer */
-
- mem = get_free_page(GFP_KERNEL);
- if (mem == 0) {
- printk(KERN_ERR "%s: jpg_fbuffer_alloc: get_free_page (frag_tab) failed for buffer %d\n", zr->name, i);
- jpg_fbuffer_free(zr);
- return -ENOBUFS;
- }
- memset((void *) mem, 0, PAGE_SIZE);
- zr->jpg_gbuf[i].frag_tab = (u32 *) mem;
- zr->jpg_gbuf[i].frag_tab_bus = virt_to_bus((void *) mem);
-
- if (alloc_contig) {
- mem = (unsigned long) kmalloc(zr->jpg_bufsize, GFP_KERNEL);
- if (mem == 0) {
- jpg_fbuffer_free(zr);
- return -ENOBUFS;
- }
- zr->jpg_gbuf[i].frag_tab[0] = virt_to_bus((void *) mem);
- zr->jpg_gbuf[i].frag_tab[1] = ((zr->jpg_bufsize / 4) << 1) | 1;
- for (off = 0; off < zr->jpg_bufsize; off += PAGE_SIZE)
- mem_map_reserve(virt_to_page(mem + off));
- } else {
- /* jpg_bufsize is alreay page aligned */
- for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) {
- mem = get_free_page(GFP_KERNEL);
- if (mem == 0) {
- jpg_fbuffer_free(zr);
- return -ENOBUFS;
- }
- zr->jpg_gbuf[i].frag_tab[2 * j] = virt_to_bus((void *) mem);
- zr->jpg_gbuf[i].frag_tab[2 * j + 1] = (PAGE_SIZE / 4) << 1;
- mem_map_reserve(virt_to_page(mem));
- }
-
- zr->jpg_gbuf[i].frag_tab[2 * j - 1] |= 1;
- }
- }
-
- DEBUG(printk("jpg_fbuffer_alloc: %d KB allocated\n",
- (zr->jpg_nbufs * zr->jpg_bufsize) >> 10));
- zr->jpg_buffers_allocated = 1;
- return 0;
-}
-
-/* free the MJPEG grab buffers */
-static void jpg_fbuffer_free(struct zoran *zr)
-{
- int i, j, off, alloc_contig;
- unsigned char *mem;
-
- /* Decide if we should alloc contiguous or fragmented memory */
- /* This has to be identical in jpg_fbuffer_alloc and jpg_fbuffer_free */
-
- alloc_contig = (zr->jpg_bufsize < MAX_KMALLOC_MEM);
-
- for (i = 0; i < zr->jpg_nbufs; i++) {
- if (!zr->jpg_gbuf[i].frag_tab)
- continue;
-
- if (alloc_contig) {
- if (zr->jpg_gbuf[i].frag_tab[0]) {
- mem = (unsigned char *) bus_to_virt(zr->jpg_gbuf[i].frag_tab[0]);
- for (off = 0; off < zr->jpg_bufsize; off += PAGE_SIZE)
- mem_map_unreserve(virt_to_page(mem + off));
- kfree((void *) mem);
- zr->jpg_gbuf[i].frag_tab[0] = 0;
- zr->jpg_gbuf[i].frag_tab[1] = 0;
- }
- } else {
- for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) {
- if (!zr->jpg_gbuf[i].frag_tab[2 * j])
- break;
- mem_map_unreserve(virt_to_page(bus_to_virt(zr->jpg_gbuf[i].frag_tab[2 * j])));
- free_page((unsigned long) bus_to_virt(zr->jpg_gbuf[i].frag_tab[2 * j]));
- zr->jpg_gbuf[i].frag_tab[2 * j] = 0;
- zr->jpg_gbuf[i].frag_tab[2 * j + 1] = 0;
- }
- }
-
- free_page((unsigned long) zr->jpg_gbuf[i].frag_tab);
- zr->jpg_gbuf[i].frag_tab = NULL;
- }
- zr->jpg_buffers_allocated = 0;
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-/* I2C functions */
-
-#define I2C_DELAY 10
-
-
-/* software I2C functions */
-
-static void i2c_setlines(struct i2c_bus *bus, int ctrl, int data)
-{
- struct zoran *zr = (struct zoran *) bus->data;
- btwrite((data << 1) | ctrl, ZR36057_I2CBR);
- btread(ZR36057_I2CBR);
- udelay(I2C_DELAY);
-}
-
-static int i2c_getdataline(struct i2c_bus *bus)
-{
- struct zoran *zr = (struct zoran *) bus->data;
- return (btread(ZR36057_I2CBR) >> 1) & 1;
-}
-
-static void attach_inform(struct i2c_bus *bus, int id)
-{
- DEBUG(struct zoran *zr = (struct zoran *) bus->data);
- DEBUG(printk(BUZ_DEBUG "-%u: i2c attach %02x\n", zr->id, id));
-}
-
-static void detach_inform(struct i2c_bus *bus, int id)
-{
- DEBUG(struct zoran *zr = (struct zoran *) bus->data);
- DEBUG(printk(BUZ_DEBUG "-%u: i2c detach %02x\n", zr->id, id));
-}
-
-static struct i2c_bus zoran_i2c_bus_template =
-{
- "zr36057",
- I2C_BUSID_BT848,
- NULL,
-
- SPIN_LOCK_UNLOCKED,
-
- attach_inform,
- detach_inform,
-
- i2c_setlines,
- i2c_getdataline,
- NULL,
- NULL,
-};
-
-
-/* ----------------------------------------------------------------------- */
-
-static void GPIO(struct zoran *zr, unsigned bit, unsigned value)
-{
- u32 reg;
- u32 mask;
-
- mask = 1 << (24 + bit);
- reg = btread(ZR36057_GPPGCR1) & ~mask;
- if (value) {
- reg |= mask;
- }
- btwrite(reg, ZR36057_GPPGCR1);
- /* Stop any PCI posting on the GPIO bus */
- btread(ZR36057_I2CBR);
-}
-
-
-/*
- * Set the registers for the size we have specified. Don't bother
- * trying to understand this without the ZR36057 manual in front of
- * you [AC].
- *
- * PS: The manual is free for download in .pdf format from
- * www.zoran.com - nicely done those folks.
- */
-
-struct tvnorm {
- u16 Wt, Wa, Ht, Ha, HStart, VStart;
-};
-
-static struct tvnorm tvnorms[] =
-{
- /* PAL-BDGHI */
- {864, 720, 625, 576, 31, 16},
- /* NTSC */
- {858, 720, 525, 480, 21, 8},
-};
-#define TVNORMS (sizeof(tvnorms) / sizeof(tvnorm))
-
-static int format2bpp(int format)
-{
- int bpp;
-
- /* Determine the number of bytes per pixel for the video format requested */
-
- switch (format) {
-
- case VIDEO_PALETTE_YUV422:
- bpp = 2;
- break;
-
- case VIDEO_PALETTE_RGB555:
- bpp = 2;
- break;
-
- case VIDEO_PALETTE_RGB565:
- bpp = 2;
- break;
-
- case VIDEO_PALETTE_RGB24:
- bpp = 3;
- break;
-
- case VIDEO_PALETTE_RGB32:
- bpp = 4;
- break;
-
- default:
- bpp = 0;
- }
-
- return bpp;
-}
-
-/*
- * set geometry
- */
-static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height,
- unsigned int video_format)
-{
- struct tvnorm *tvn;
- unsigned HStart, HEnd, VStart, VEnd;
- unsigned DispMode;
- unsigned VidWinWid, VidWinHt;
- unsigned hcrop1, hcrop2, vcrop1, vcrop2;
- unsigned Wa, We, Ha, He;
- unsigned X, Y, HorDcm, VerDcm;
- u32 reg;
- unsigned mask_line_size;
-
- if (zr->params.norm < 0 || zr->params.norm > 1) {
- printk(KERN_ERR "%s: set_vfe: video_norm = %d not valid\n", zr->name, zr->params.norm);
- return;
- }
- if (video_width < BUZ_MIN_WIDTH || video_height < BUZ_MIN_HEIGHT) {
- printk(KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n", zr->name, video_width, video_height);
- return;
- }
- tvn = &tvnorms[zr->params.norm];
-
- Wa = tvn->Wa;
- Ha = tvn->Ha;
-
- /* if window has more than half of active height,
- switch on interlacing - we want the full information */
-
- zr->video_interlace = (video_height > Ha / 2);
-
-/**** zr36057 ****/
-
- /* horizontal */
- VidWinWid = video_width;
- X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa;
- We = (VidWinWid * 64) / X;
- HorDcm = 64 - X;
- hcrop1 = 2 * ((tvn->Wa - We) / 4);
- hcrop2 = tvn->Wa - We - hcrop1;
- HStart = tvn->HStart | 1;
- HEnd = HStart + tvn->Wa - 1;
- HStart += hcrop1;
- HEnd -= hcrop2;
- reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart)
- | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd);
- reg |= ZR36057_VFEHCR_HSPol;
- btwrite(reg, ZR36057_VFEHCR);
-
- /* Vertical */
- DispMode = !zr->video_interlace;
- VidWinHt = DispMode ? video_height : video_height / 2;
- Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha;
- He = (VidWinHt * 64) / Y;
- VerDcm = 64 - Y;
- vcrop1 = (tvn->Ha / 2 - He) / 2;
- vcrop2 = tvn->Ha / 2 - He - vcrop1;
- VStart = tvn->VStart;
- VEnd = VStart + tvn->Ha / 2 - 1;
- VStart += vcrop1;
- VEnd -= vcrop2;
- reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart)
- | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd);
- reg |= ZR36057_VFEVCR_VSPol;
- btwrite(reg, ZR36057_VFEVCR);
-
- /* scaler and pixel format */
- reg = 0 // ZR36057_VFESPFR_ExtFl /* Trying to live without ExtFl */
- | (HorDcm << ZR36057_VFESPFR_HorDcm)
- | (VerDcm << ZR36057_VFESPFR_VerDcm)
- | (DispMode << ZR36057_VFESPFR_DispMode)
- | ZR36057_VFESPFR_LittleEndian;
- /* RJ: I don't know, why the following has to be the opposite
- of the corresponding ZR36060 setting, but only this way
- we get the correct colors when uncompressing to the screen */
- reg |= ZR36057_VFESPFR_VCLKPol;
- /* RJ: Don't know if that is needed for NTSC also */
- reg |= ZR36057_VFESPFR_TopField;
- switch (video_format) {
-
- case VIDEO_PALETTE_YUV422:
- reg |= ZR36057_VFESPFR_YUV422;
- break;
-
- case VIDEO_PALETTE_RGB555:
- reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif;
- break;
-
- case VIDEO_PALETTE_RGB565:
- reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif;
- break;
-
- case VIDEO_PALETTE_RGB24:
- reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24;
- break;
-
- case VIDEO_PALETTE_RGB32:
- reg |= ZR36057_VFESPFR_RGB888;
- break;
-
- default:
- printk(KERN_INFO "%s: Unknown color_fmt=%x\n", zr->name, video_format);
- return;
-
- }
- if (HorDcm >= 48) {
- reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */
- } else if (HorDcm >= 32) {
- reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */
- } else if (HorDcm >= 16) {
- reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */
- }
- btwrite(reg, ZR36057_VFESPFR);
-
- /* display configuration */
-
- reg = (16 << ZR36057_VDCR_MinPix)
- | (VidWinHt << ZR36057_VDCR_VidWinHt)
- | (VidWinWid << ZR36057_VDCR_VidWinWid);
- if (triton)
- reg &= ~ZR36057_VDCR_Triton;
- else
- reg |= ZR36057_VDCR_Triton;
- btwrite(reg, ZR36057_VDCR);
-
- /* Write overlay clipping mask data, but don't enable overlay clipping */
- /* RJ: since this makes only sense on the screen, we use
- zr->window.width instead of video_width */
-
- mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
- reg = virt_to_bus(zr->overlay_mask);
- btwrite(reg, ZR36057_MMTR);
- reg = virt_to_bus(zr->overlay_mask + mask_line_size);
- btwrite(reg, ZR36057_MMBR);
- reg = mask_line_size - (zr->window.width + 31) / 32;
- if (DispMode == 0)
- reg += mask_line_size;
- reg <<= ZR36057_OCR_MaskStride;
- btwrite(reg, ZR36057_OCR);
-
-}
-
-/*
- * Switch overlay on or off
- */
-
-static void zr36057_overlay(struct zoran *zr, int on)
-{
- int fmt, bpp;
- u32 reg;
-
- if (on) {
- /* do the necessary settings ... */
-
- btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */
-
- switch (zr->buffer.depth) {
- case 15:
- fmt = VIDEO_PALETTE_RGB555;
- bpp = 2;
- break;
- case 16:
- fmt = VIDEO_PALETTE_RGB565;
- bpp = 2;
- break;
- case 24:
- fmt = VIDEO_PALETTE_RGB24;
- bpp = 3;
- break;
- case 32:
- fmt = VIDEO_PALETTE_RGB32;
- bpp = 4;
- break;
- default:
- fmt = 0;
- bpp = 0;
- }
-
- zr36057_set_vfe(zr, zr->window.width, zr->window.height, fmt);
-
- /* Start and length of each line MUST be 4-byte aligned.
- This should be allready checked before the call to this routine.
- All error messages are internal driver checking only! */
-
- /* video display top and bottom registers */
-
- reg = (u32) zr->buffer.base
- + zr->window.x * bpp
- + zr->window.y * zr->buffer.bytesperline;
- btwrite(reg, ZR36057_VDTR);
- if (reg & 3)
- printk(KERN_ERR "%s: zr36057_overlay: video_address not aligned\n", zr->name);
- if (zr->video_interlace)
- reg += zr->buffer.bytesperline;
- btwrite(reg, ZR36057_VDBR);
-
- /* video stride, status, and frame grab register */
-
- reg = zr->buffer.bytesperline - zr->window.width * bpp;
- if (zr->video_interlace)
- reg += zr->buffer.bytesperline;
- if (reg & 3)
- printk(KERN_ERR "%s: zr36057_overlay: video_stride not aligned\n", zr->name);
- reg = (reg << ZR36057_VSSFGR_DispStride);
- reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */
- btwrite(reg, ZR36057_VSSFGR);
-
- /* Set overlay clipping */
-
- if (zr->window.clipcount)
- btor(ZR36057_OCR_OvlEnable, ZR36057_OCR);
-
- /* ... and switch it on */
-
- btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);
- } else {
- /* Switch it off */
-
- btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
- }
-}
-
-/*
- * The overlay mask has one bit for each pixel on a scan line,
- * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
- */
-static void write_overlay_mask(struct zoran *zr, struct video_clip *vp, int count)
-{
- unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
- u32 *mask;
- int x, y, width, height;
- unsigned i, j, k;
- u32 reg;
-
- /* fill mask with one bits */
- memset(zr->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT);
- reg = 0;
-
- for (i = 0; i < count; ++i) {
- /* pick up local copy of clip */
- x = vp[i].x;
- y = vp[i].y;
- width = vp[i].width;
- height = vp[i].height;
-
- /* trim clips that extend beyond the window */
- if (x < 0) {
- width += x;
- x = 0;
- }
- if (y < 0) {
- height += y;
- y = 0;
- }
- if (x + width > zr->window.width) {
- width = zr->window.width - x;
- }
- if (y + height > zr->window.height) {
- height = zr->window.height - y;
- }
- /* ignore degenerate clips */
- if (height <= 0) {
- continue;
- }
- if (width <= 0) {
- continue;
- }
- /* apply clip for each scan line */
- for (j = 0; j < height; ++j) {
- /* reset bit for each pixel */
- /* this can be optimized later if need be */
- mask = zr->overlay_mask + (y + j) * mask_line_size;
- for (k = 0; k < width; ++k) {
- mask[(x + k) / 32] &= ~((u32) 1 << (x + k) % 32);
- }
- }
- }
-}
-
-/* Enable/Disable uncompressed memory grabbing of the 36057 */
-
-static void zr36057_set_memgrab(struct zoran *zr, int mode)
-{
- if (mode) {
- if (btread(ZR36057_VSSFGR) & (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab))
- printk(KERN_WARNING "%s: zr36057_set_memgrab_on with SnapShot or FrameGrab on ???\n", zr->name);
-
- /* switch on VSync interrupts */
-
- btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts
-
- btor(ZR36057_ICR_GIRQ0, ZR36057_ICR);
-
- /* enable SnapShot */
-
- btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
-
- /* Set zr36057 video front end and enable video */
-
-#ifdef XAWTV_HACK
- zr36057_set_vfe(zr, zr->gwidth > 720 ? 720 : zr->gwidth, zr->gheight, zr->gformat);
-#else
- zr36057_set_vfe(zr, zr->gwidth, zr->gheight, zr->gformat);
-#endif
-
- zr->v4l_memgrab_active = 1;
- } else {
- zr->v4l_memgrab_active = 0;
-
- /* switch off VSync interrupts */
-
- btand(~ZR36057_ICR_GIRQ0, ZR36057_ICR);
-
- /* reenable grabbing to screen if it was running */
-
- if (zr->v4l_overlay_active) {
- zr36057_overlay(zr, 1);
- } else {
- btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
- btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
- }
- }
-}
-
-static int wait_grab_pending(struct zoran *zr)
-{
- unsigned long flags;
-
- /* wait until all pending grabs are finished */
-
- if (!zr->v4l_memgrab_active)
- return 0;
-
- while (zr->v4l_pend_tail != zr->v4l_pend_head) {
- interruptible_sleep_on(&zr->v4l_capq);
- if (signal_pending(current))
- return -ERESTARTSYS;
- }
-
- spin_lock_irqsave(&zr->lock, flags);
- zr36057_set_memgrab(zr, 0);
- spin_unlock_irqrestore(&zr->lock, flags);
-
- return 0;
-}
-
-/*
- * V4L Buffer grabbing
- */
-
-static int v4l_grab(struct zoran *zr, struct video_mmap *mp)
-{
- unsigned long flags;
- int res, bpp;
-
- /*
- * There is a long list of limitations to what is allowed to be grabbed
- * We don't output error messages her, since some programs (e.g. xawtv)
- * just try several settings to find out what is valid or not.
- */
-
- /* No grabbing outside the buffer range! */
-
- if (mp->frame >= v4l_nbufs || mp->frame < 0)
- return -EINVAL;
-
- /* Check size and format of the grab wanted */
-
- if (mp->height < BUZ_MIN_HEIGHT || mp->width < BUZ_MIN_WIDTH)
- return -EINVAL;
- if (mp->height > BUZ_MAX_HEIGHT || mp->width > BUZ_MAX_WIDTH)
- return -EINVAL;
-
- bpp = format2bpp(mp->format);
- if (bpp == 0)
- return -EINVAL;
-
- /* Check against available buffer size */
-
- if (mp->height * mp->width * bpp > v4l_bufsize)
- return -EINVAL;
-
- /* The video front end needs 4-byte alinged line sizes */
-
- if ((bpp == 2 && (mp->width & 1)) || (bpp == 3 && (mp->width & 3)))
- return -EINVAL;
-
- /*
- * To minimize the time spent in the IRQ routine, we avoid setting up
- * the video front end there.
- * If this grab has different parameters from a running streaming capture
- * we stop the streaming capture and start it over again.
- */
-
- if (zr->v4l_memgrab_active &&
- (zr->gwidth != mp->width || zr->gheight != mp->height || zr->gformat != mp->format)) {
- res = wait_grab_pending(zr);
- if (res)
- return res;
- }
- zr->gwidth = mp->width;
- zr->gheight = mp->height;
- zr->gformat = mp->format;
- zr->gbpl = bpp * zr->gwidth;
-
-
- spin_lock_irqsave(&zr->lock, flags);
-
- /* make sure a grab isn't going on currently with this buffer */
-
- switch (zr->v4l_gbuf[mp->frame].state) {
-
- default:
- case BUZ_STATE_PEND:
- res = -EBUSY; /* what are you doing? */
- break;
-
- case BUZ_STATE_USER:
- case BUZ_STATE_DONE:
- /* since there is at least one unused buffer there's room for at least one more pend[] entry */
- zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = mp->frame;
- zr->v4l_gbuf[mp->frame].state = BUZ_STATE_PEND;
- res = 0;
- break;
-
- }
-
- /* put the 36057 into frame grabbing mode */
-
- if (!res && !zr->v4l_memgrab_active)
- zr36057_set_memgrab(zr, 1);
-
- spin_unlock_irqrestore(&zr->lock, flags);
-
- return res;
-}
-
-/*
- * Sync on a V4L buffer
- */
-
-static int v4l_sync(struct zoran *zr, int frame)
-{
- unsigned long flags;
-
-
- /* check passed-in frame number */
- if (frame >= v4l_nbufs || frame < 0) {
- printk(KERN_ERR "%s: v4l_sync: frame %d is invalid\n", zr->name, frame);
- return -EINVAL;
- }
- /* Check if is buffer was queued at all */
-
- if (zr->v4l_gbuf[frame].state == BUZ_STATE_USER) {
-// printk(KERN_ERR "%s: v4l_sync: Trying to sync on a buffer which was not queued?\n", zr->name);
- return -EINVAL;
- }
- /* wait on this buffer to get ready */
-
- while (zr->v4l_gbuf[frame].state == BUZ_STATE_PEND) {
- interruptible_sleep_on(&zr->v4l_capq);
- if (signal_pending(current))
- return -ERESTARTSYS;
- }
-
- /* buffer should now be in BUZ_STATE_DONE */
-
- if (zr->v4l_gbuf[frame].state != BUZ_STATE_DONE)
- printk(KERN_ERR "%s: v4l_sync - internal error\n", zr->name);
-
- /* Check if streaming capture has finished */
-
- spin_lock_irqsave(&zr->lock, flags);
-
- if (zr->v4l_pend_tail == zr->v4l_pend_head)
- zr36057_set_memgrab(zr, 0);
-
- spin_unlock_irqrestore(&zr->lock, flags);
-
- return 0;
-}
-/*****************************************************************************
- * *
- * Set up the Buz-specific MJPEG part *
- * *
- *****************************************************************************/
-
-/*
- * Wait til post office is no longer busy
- */
-
-static int post_office_wait(struct zoran *zr)
-{
- u32 por;
- u32 ct=0;
-
- while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) {
- ct++;
- if(ct>100000)
- {
- printk(KERN_ERR "%s: timeout on post office.\n", zr->name);
- return -1;
- }
- /* wait for something to happen */
- }
- if ((por & ZR36057_POR_POPen) != 0) {
- printk(KERN_WARNING "%s: pop pending %08x\n", zr->name, por);
- return -1;
- }
- if ((por & (ZR36057_POR_POTime | ZR36057_POR_POPen)) != 0) {
- printk(KERN_WARNING "%s: pop timeout %08x\n", zr->name, por);
- return -1;
- }
- return 0;
-}
-
-static int post_office_write(struct zoran *zr, unsigned guest, unsigned reg, unsigned value)
-{
- u32 por;
-
- post_office_wait(zr);
- por = ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16) | (value & 0xFF);
- btwrite(por, ZR36057_POR);
- return post_office_wait(zr);
-}
-
-static int post_office_read(struct zoran *zr, unsigned guest, unsigned reg)
-{
- u32 por;
-
- post_office_wait(zr);
- por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16);
- btwrite(por, ZR36057_POR);
- if (post_office_wait(zr) < 0) {
- return -1;
- }
- return btread(ZR36057_POR) & 0xFF;
-}
-
-static int zr36060_write_8(struct zoran *zr, unsigned reg, unsigned val)
-{
- if (post_office_wait(zr)
- || post_office_write(zr, 0, 1, reg >> 8)
- || post_office_write(zr, 0, 2, reg)) {
- return -1;
- }
- return post_office_write(zr, 0, 3, val);
-}
-
-static int zr36060_write_16(struct zoran *zr, unsigned reg, unsigned val)
-{
- if (zr36060_write_8(zr, reg + 0, val >> 8)) {
- return -1;
- }
- return zr36060_write_8(zr, reg + 1, val >> 0);
-}
-
-static int zr36060_write_24(struct zoran *zr, unsigned reg, unsigned val)
-{
- if (zr36060_write_8(zr, reg + 0, val >> 16)) {
- return -1;
- }
- return zr36060_write_16(zr, reg + 1, val >> 0);
-}
-
-static int zr36060_write_32(struct zoran *zr, unsigned reg, unsigned val)
-{
- if (zr36060_write_16(zr, reg + 0, val >> 16)) {
- return -1;
- }
- return zr36060_write_16(zr, reg + 2, val >> 0);
-}
-
-static u32 zr36060_read_8(struct zoran *zr, unsigned reg)
-{
- if (post_office_wait(zr)
- || post_office_write(zr, 0, 1, reg >> 8)
- || post_office_write(zr, 0, 2, reg)) {
- return -1;
- }
- return post_office_read(zr, 0, 3) & 0xFF;
-}
-
-static int zr36060_reset(struct zoran *zr)
-{
- return post_office_write(zr, 3, 0, 0);
-}
-
-static void zr36060_sleep(struct zoran *zr, int sleep)
-{
- GPIO(zr, 1, !sleep);
-}
-
-
-static void zr36060_set_jpg(struct zoran *zr, enum zoran_codec_mode mode)
-{
- struct tvnorm *tvn;
- u32 reg;
- int size;
-
- reg = (1 << 0) /* CodeMstr */
- |(0 << 2) /* CFIS=0 */
- |(0 << 6) /* Endian=0 */
- |(0 << 7); /* Code16=0 */
- zr36060_write_8(zr, 0x002, reg);
-
- switch (mode) {
-
- case BUZ_MODE_MOTION_DECOMPRESS:
- case BUZ_MODE_STILL_DECOMPRESS:
- reg = 0x00; /* Codec mode = decompression */
- break;
-
- case BUZ_MODE_MOTION_COMPRESS:
- case BUZ_MODE_STILL_COMPRESS:
- default:
- reg = 0xa4; /* Codec mode = compression with variable scale factor */
- break;
-
- }
- zr36060_write_8(zr, 0x003, reg);
-
- reg = 0x00; /* reserved, mbz */
- zr36060_write_8(zr, 0x004, reg);
-
- reg = 0xff; /* 510 bits/block */
- zr36060_write_8(zr, 0x005, reg);
-
- /* JPEG markers */
- reg = (zr->params.jpeg_markers) & 0x38; /* DRI, DQT, DHT */
- if (zr->params.COM_len)
- reg |= JPEG_MARKER_COM;
- if (zr->params.APP_len)
- reg |= JPEG_MARKER_APP;
- zr36060_write_8(zr, 0x006, reg);
-
- reg = (0 << 3) /* DATERR=0 */
- |(0 << 2) /* END=0 */
- |(0 << 1) /* EOI=0 */
- |(0 << 0); /* EOAV=0 */
- zr36060_write_8(zr, 0x007, reg);
-
- /* code volume */
-
- /* Target field size in pixels: */
- tvn = &tvnorms[zr->params.norm];
- size = (tvn->Ha / 2) * (tvn->Wa) / (zr->params.HorDcm) / (zr->params.VerDcm);
-
- /* Target compressed field size in bits: */
- size = size * 16; /* uncompressed size in bits */
- size = size * zr->params.quality / 400; /* quality = 100 is a compression ratio 1:4 */
-
- /* Lower limit (arbitrary, 1 KB) */
- if (size < 8192)
- size = 8192;
-
- /* Upper limit: 7/8 of the code buffers */
- if (size * zr->params.field_per_buff > zr->jpg_bufsize * 7)
- size = zr->jpg_bufsize * 7 / zr->params.field_per_buff;
-
- reg = size;
- zr36060_write_32(zr, 0x009, reg);
-
- /* how do we set initial SF as a function of quality parameter? */
- reg = 0x0100; /* SF=1.0 */
- zr36060_write_16(zr, 0x011, reg);
-
- reg = 0x00ffffff; /* AF=max */
- zr36060_write_24(zr, 0x013, reg);
-
- reg = 0x0000; /* test */
- zr36060_write_16(zr, 0x024, reg);
-}
-
-static void zr36060_set_video(struct zoran *zr, enum zoran_codec_mode mode)
-{
- struct tvnorm *tvn;
- u32 reg;
-
- reg = (0 << 7) /* Video8=0 */
- |(0 << 6) /* Range=0 */
- |(0 << 3) /* FlDet=0 */
- |(1 << 2) /* FlVedge=1 */
- |(0 << 1) /* FlExt=0 */
- |(0 << 0); /* SyncMstr=0 */
-
- /* According to ZR36067 documentation, FlDet should correspond
- to the odd_even flag of the ZR36067 */
- if (zr->params.odd_even)
- reg |= (1 << 3);
-
- if (mode != BUZ_MODE_STILL_DECOMPRESS) {
- /* limit pixels to range 16..235 as per CCIR-601 */
- reg |= (1 << 6); /* Range=1 */
- }
- zr36060_write_8(zr, 0x030, reg);
-
- reg = (0 << 7) /* VCLKPol=0 */
- |(0 << 6) /* PValPol=0 */
- |(1 << 5) /* PoePol=1 */
- |(0 << 4) /* SImgPol=0 */
- |(0 << 3) /* BLPol=0 */
- |(0 << 2) /* FlPol=0 */
- |(0 << 1) /* HSPol=0, sync on falling edge */
- |(1 << 0); /* VSPol=1 */
- zr36060_write_8(zr, 0x031, reg);
-
- switch (zr->params.HorDcm) {
- default:
- case 1:
- reg = (0 << 0);
- break; /* HScale = 0 */
-
- case 2:
- reg = (1 << 0);
- break; /* HScale = 1 */
-
- case 4:
- reg = (2 << 0);
- break; /* HScale = 2 */
- }
- if (zr->params.VerDcm == 2)
- reg |= (1 << 2);
- zr36060_write_8(zr, 0x032, reg);
-
- reg = 0x80; /* BackY */
- zr36060_write_8(zr, 0x033, reg);
-
- reg = 0xe0; /* BackU */
- zr36060_write_8(zr, 0x034, reg);
-
- reg = 0xe0; /* BackV */
- zr36060_write_8(zr, 0x035, reg);
-
- /* sync generator */
-
- tvn = &tvnorms[zr->params.norm];
-
- reg = tvn->Ht - 1; /* Vtotal */
- zr36060_write_16(zr, 0x036, reg);
-
- reg = tvn->Wt - 1; /* Htotal */
- zr36060_write_16(zr, 0x038, reg);
-
- reg = 6 - 1; /* VsyncSize */
- zr36060_write_8(zr, 0x03a, reg);
-
- reg = 100 - 1; /* HsyncSize */
- zr36060_write_8(zr, 0x03b, reg);
-
- reg = tvn->VStart - 1; /* BVstart */
- zr36060_write_8(zr, 0x03c, reg);
-
- reg += tvn->Ha / 2; /* BVend */
- zr36060_write_16(zr, 0x03e, reg);
-
- reg = tvn->HStart - 1; /* BHstart */
- zr36060_write_8(zr, 0x03d, reg);
-
- reg += tvn->Wa; /* BHend */
- zr36060_write_16(zr, 0x040, reg);
-
- /* active area */
- reg = zr->params.img_y + tvn->VStart; /* Vstart */
- zr36060_write_16(zr, 0x042, reg);
-
- reg += zr->params.img_height; /* Vend */
- zr36060_write_16(zr, 0x044, reg);
-
- reg = zr->params.img_x + tvn->HStart; /* Hstart */
- zr36060_write_16(zr, 0x046, reg);
-
- reg += zr->params.img_width; /* Hend */
- zr36060_write_16(zr, 0x048, reg);
-
- /* subimage area */
- reg = zr->params.img_y + tvn->VStart; /* SVstart */
- zr36060_write_16(zr, 0x04a, reg);
-
- reg += zr->params.img_height; /* SVend */
- zr36060_write_16(zr, 0x04c, reg);
-
- reg = zr->params.img_x + tvn->HStart; /* SHstart */
- zr36060_write_16(zr, 0x04e, reg);
-
- reg += zr->params.img_width; /* SHend */
- zr36060_write_16(zr, 0x050, reg);
-}
-
-static void zr36060_set_jpg_SOF(struct zoran *zr)
-{
- u32 reg;
-
-
- reg = 0xffc0; /* SOF marker */
- zr36060_write_16(zr, 0x060, reg);
-
- reg = 17; /* SOF length */
- zr36060_write_16(zr, 0x062, reg);
-
- reg = 8; /* precision 8 bits */
- zr36060_write_8(zr, 0x064, reg);
-
- reg = zr->params.img_height / zr->params.VerDcm; /* image height */
- zr36060_write_16(zr, 0x065, reg);
-
- reg = zr->params.img_width / zr->params.HorDcm; /* image width */
- zr36060_write_16(zr, 0x067, reg);
-
- reg = 3; /* 3 color components */
- zr36060_write_8(zr, 0x069, reg);
-
- reg = 0x002100; /* Y component */
- zr36060_write_24(zr, 0x06a, reg);
-
- reg = 0x011101; /* U component */
- zr36060_write_24(zr, 0x06d, reg);
-
- reg = 0x021101; /* V component */
- zr36060_write_24(zr, 0x070, reg);
-}
-
-static void zr36060_set_jpg_SOS(struct zoran *zr)
-{
- u32 reg;
-
-
- reg = 0xffda; /* SOS marker */
- zr36060_write_16(zr, 0x07a, reg);
-
- reg = 12; /* SOS length */
- zr36060_write_16(zr, 0x07c, reg);
-
- reg = 3; /* 3 color components */
- zr36060_write_8(zr, 0x07e, reg);
-
- reg = 0x0000; /* Y component */
- zr36060_write_16(zr, 0x07f, reg);
-
- reg = 0x0111; /* U component */
- zr36060_write_16(zr, 0x081, reg);
-
- reg = 0x0211; /* V component */
- zr36060_write_16(zr, 0x083, reg);
-
- reg = 0x003f00; /* Start, end spectral scans */
- zr36060_write_24(zr, 0x085, reg);
-}
-
-static void zr36060_set_jpg_DRI(struct zoran *zr)
-{
- u32 reg;
-
-
- reg = 0xffdd; /* DRI marker */
- zr36060_write_16(zr, 0x0c0, reg);
-
- reg = 4; /* DRI length */
- zr36060_write_16(zr, 0x0c2, reg);
-
- reg = 8; /* length in MCUs */
- zr36060_write_16(zr, 0x0c4, reg);
-}
-
-static void zr36060_set_jpg_DQT(struct zoran *zr)
-{
- unsigned i;
- unsigned adr;
- static const u8 dqt[] =
- {
- 0xff, 0xdb, /* DHT marker */
- 0x00, 0x84, /* DHT length */
- 0x00, /* table ID 0 */
- 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
- 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
- 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
- 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
- 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
- 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
- 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
- 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
- 0x01, /* table ID 1 */
- 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
- 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
- };
-
- /* write fixed quantitization tables */
- adr = 0x0cc;
- for (i = 0; i < sizeof(dqt); ++i) {
- zr36060_write_8(zr, adr++, dqt[i]);
- }
-}
-
-static void zr36060_set_jpg_DHT(struct zoran *zr)
-{
- unsigned i;
- unsigned adr;
- static const u8 dht[] =
- {
- 0xff, 0xc4, /* DHT marker */
- 0x01, 0xa2, /* DHT length */
- 0x00, /* table class 0, ID 0 */
- 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, /* # codes of length 1..8 */
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* # codes of length 8..16 */
- 0x00, /* values for codes of length 2 */
- 0x01, 0x02, 0x03, 0x04, 0x05, /* values for codes of length 3 */
- 0x06, /* values for codes of length 4 */
- 0x07, /* values for codes of length 5 */
- 0x08, /* values for codes of length 6 */
- 0x09, /* values for codes of length 7 */
- 0x0a, /* values for codes of length 8 */
- 0x0b, /* values for codes of length 9 */
- 0x01, /* table class 0, ID 1 */
- 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* # codes of length 1..8 */
- 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* # codes of length 9..16 */
- 0x00, 0x01, 0x02, /* values for codes of length 2 */
- 0x03, /* values for codes of length 3 */
- 0x04, /* values for codes of length 4 */
- 0x05, /* values for codes of length 5 */
- 0x06, /* values for codes of length 6 */
- 0x07, /* values for codes of length 7 */
- 0x08, /* values for codes of length 8 */
- 0x09, /* values for codes of length 9 */
- 0x0a, /* values for codes of length 10 */
- 0x0b, /* values for codes of length 11 */
- 0x10,
- 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
- 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
- 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
- 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
- 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04,
- 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00,
- 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
- 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
- 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08,
- 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23,
- 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a,
- 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
- 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35,
- 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
- 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55,
- 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
- 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
- 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84,
- 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
- 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2,
- 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
- 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
- 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
- 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
- 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5,
- 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
- };
-
- /* write fixed Huffman tables */
- adr = 0x1d4;
- for (i = 0; i < sizeof(dht); ++i) {
- zr36060_write_8(zr, adr++, dht[i]);
- }
-}
-
-static void zr36060_set_jpg_APP(struct zoran *zr)
-{
- unsigned adr;
- int len, i;
- u32 reg;
-
-
- len = zr->params.APP_len;
- if (len < 0)
- len = 0;
- if (len > 60)
- len = 60;
-
- i = zr->params.APPn;
- if (i < 0)
- i = 0;
- if (i > 15)
- i = 15;
-
- reg = 0xffe0 + i; /* APPn marker */
- zr36060_write_16(zr, 0x380, reg);
-
- reg = len + 2; /* APPn len */
- zr36060_write_16(zr, 0x382, reg);
-
- /* write APPn data */
- adr = 0x384;
- for (i = 0; i < 60; i++) {
- zr36060_write_8(zr, adr++, (i < len ? zr->params.APP_data[i] : 0));
- }
-}
-
-static void zr36060_set_jpg_COM(struct zoran *zr)
-{
- unsigned adr;
- int len, i;
- u32 reg;
-
-
- len = zr->params.COM_len;
- if (len < 0)
- len = 0;
- if (len > 60)
- len = 60;
-
- reg = 0xfffe; /* COM marker */
- zr36060_write_16(zr, 0x3c0, reg);
-
- reg = len + 2; /* COM len */
- zr36060_write_16(zr, 0x3c2, reg);
-
- /* write COM data */
- adr = 0x3c4;
- for (i = 0; i < 60; i++) {
- zr36060_write_8(zr, adr++, (i < len ? zr->params.COM_data[i] : 0));
- }
-}
-
-static void zr36060_set_cap(struct zoran *zr, enum zoran_codec_mode mode)
-{
- unsigned i;
- u32 reg;
-
- zr36060_reset(zr);
- mdelay(10);
-
- reg = (0 << 7) /* Load=0 */
- |(1 << 0); /* SynRst=1 */
- zr36060_write_8(zr, 0x000, reg);
-
- zr36060_set_jpg(zr, mode);
- zr36060_set_video(zr, mode);
- zr36060_set_jpg_SOF(zr);
- zr36060_set_jpg_SOS(zr);
- zr36060_set_jpg_DRI(zr);
- zr36060_set_jpg_DQT(zr);
- zr36060_set_jpg_DHT(zr);
- zr36060_set_jpg_APP(zr);
- zr36060_set_jpg_COM(zr);
-
- reg = (1 << 7) /* Load=1 */
- |(0 << 0); /* SynRst=0 */
- zr36060_write_8(zr, 0x000, reg);
-
- /* wait for codec to unbusy */
- for (i = 0; i < 1000; ++i) {
- reg = zr36060_read_8(zr, 0x001);
- if ((reg & (1 << 7)) == 0) {
- DEBUG(printk(KERN_DEBUG "060: loaded, loops=%u\n", i));
- return;
- }
- udelay(1000);
- }
- printk(KERN_INFO "060: stuck busy, statux=%02x\n", reg);
-}
-
-static void zr36057_set_jpg(struct zoran *zr, enum zoran_codec_mode mode)
-{
- struct tvnorm *tvn;
- u32 reg;
- int i;
-
- tvn = &tvnorms[zr->params.norm];
-
- /* assert P_Reset */
- btwrite(0, ZR36057_JPC);
-
- /* re-initialize DMA ring stuff */
- zr->jpg_que_head = 0;
- zr->jpg_dma_head = 0;
- zr->jpg_dma_tail = 0;
- zr->jpg_que_tail = 0;
- zr->jpg_seq_num = 0;
- for (i = 0; i < BUZ_NUM_STAT_COM; ++i) {
- zr->stat_com[i] = 1; /* mark as unavailable to zr36057 */
- }
- for (i = 0; i < zr->jpg_nbufs; i++) {
- zr->jpg_gbuf[i].state = BUZ_STATE_USER; /* nothing going on */
- }
-
- /* MJPEG compression mode */
- switch (mode) {
-
- case BUZ_MODE_MOTION_COMPRESS:
- default:
- reg = ZR36057_JMC_MJPGCmpMode;
- break;
-
- case BUZ_MODE_MOTION_DECOMPRESS:
- reg = ZR36057_JMC_MJPGExpMode;
- reg |= ZR36057_JMC_SyncMstr;
- /* RJ: The following is experimental - improves the output to screen */
- if (zr->params.VFIFO_FB)
- reg |= ZR36057_JMC_VFIFO_FB;
- break;
-
- case BUZ_MODE_STILL_COMPRESS:
- reg = ZR36057_JMC_JPGCmpMode;
- break;
-
- case BUZ_MODE_STILL_DECOMPRESS:
- reg = ZR36057_JMC_JPGExpMode;
- break;
-
- }
- reg |= ZR36057_JMC_JPG;
- if (zr->params.field_per_buff == 1)
- reg |= ZR36057_JMC_Fld_per_buff;
- btwrite(reg, ZR36057_JMC);
-
- /* vertical */
- btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR);
- reg = (6 << ZR36057_VSP_VsyncSize) | (tvn->Ht << ZR36057_VSP_FrmTot);
- btwrite(reg, ZR36057_VSP);
- reg = ((zr->params.img_y + tvn->VStart) << ZR36057_FVAP_NAY)
- | (zr->params.img_height << ZR36057_FVAP_PAY);
- btwrite(reg, ZR36057_FVAP);
-
- /* horizontal */
- btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
- reg = ((tvn->Wt - 100) << ZR36057_HSP_HsyncStart) | (tvn->Wt << ZR36057_HSP_LineTot);
- btwrite(reg, ZR36057_HSP);
- reg = ((zr->params.img_x + tvn->HStart) << ZR36057_FHAP_NAX)
- | (zr->params.img_width << ZR36057_FHAP_PAX);
- btwrite(reg, ZR36057_FHAP);
-
- /* field process parameters */
- if (zr->params.odd_even)
- reg = ZR36057_FPP_Odd_Even;
- else
- reg = 0;
- btwrite(reg, ZR36057_FPP);
-
- /* Set proper VCLK Polarity, else colors will be wrong during playback */
- btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR);
-
- /* code base address and FIFO threshold */
- reg = virt_to_bus(zr->stat_com);
- btwrite(reg, ZR36057_JCBA);
- reg = 0x50;
- btwrite(reg, ZR36057_JCFT);
-
- /* JPEG codec guest ID */
- reg = (1 << ZR36057_JCGI_JPEGuestID) | (0 << ZR36057_JCGI_JPEGuestReg);
- btwrite(reg, ZR36057_JCGI);
-
- /* Code transfer guest ID */
- reg = (0 << ZR36057_MCTCR_CodGuestID) | (3 << ZR36057_MCTCR_CodGuestReg);
- reg |= ZR36057_MCTCR_CFlush;
- btwrite(reg, ZR36057_MCTCR);
-
- /* deassert P_Reset */
- btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);
-}
-
-static void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode)
-{
- static int zero = 0;
- static int one = 1;
-
- switch (mode) {
-
- case BUZ_MODE_MOTION_COMPRESS:
- zr36060_set_cap(zr, mode);
- zr36057_set_jpg(zr, mode);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero);
-
- /* deassert P_Reset, assert Code transfer enable */
- btwrite(IRQ_MASK, ZR36057_ISR);
- btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- break;
-
- case BUZ_MODE_MOTION_DECOMPRESS:
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &zero);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &one);
- zr36060_set_cap(zr, mode);
- zr36057_set_jpg(zr, mode);
-
- /* deassert P_Reset, assert Code transfer enable */
- btwrite(IRQ_MASK, ZR36057_ISR);
- btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- break;
-
- case BUZ_MODE_IDLE:
- default:
- /* shut down processing */
- btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);
- btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);
- btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC);
- btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
- btwrite(0, ZR36057_ISR);
- zr36060_reset(zr);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero);
- break;
-
- }
- zr->codec_mode = mode;
-}
-
-/*
- * Queue a MJPEG buffer for capture/playback
- */
-
-static int jpg_qbuf(struct zoran *zr, int frame, enum zoran_codec_mode mode)
-{
- unsigned long flags;
- int res;
-
- /* Check if buffers are allocated */
-
- if (!zr->jpg_buffers_allocated) {
- printk(KERN_ERR "%s: jpg_qbuf: buffers not yet allocated\n", zr->name);
- return -ENOMEM;
- }
- /* Does the user want to stop streaming? */
-
- if (frame < 0) {
- if (zr->codec_mode == mode) {
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
- return 0;
- } else {
- printk(KERN_ERR "%s: jpg_qbuf - stop streaming but not in streaming mode\n", zr->name);
- return -EINVAL;
- }
- }
- /* No grabbing outside the buffer range! */
-
- if (frame >= zr->jpg_nbufs) {
- printk(KERN_ERR "%s: jpg_qbuf: buffer %d out of range\n", zr->name, frame);
- return -EINVAL;
- }
- /* what is the codec mode right now? */
-
- if (zr->codec_mode == BUZ_MODE_IDLE) {
- /* Ok load up the zr36060 and go */
- zr36057_enable_jpg(zr, mode);
- } else if (zr->codec_mode != mode) {
- /* wrong codec mode active - invalid */
- printk(KERN_ERR "%s: jpg_qbuf - codec in wrong mode\n", zr->name);
- return -EINVAL;
- }
- spin_lock_irqsave(&zr->lock, flags);
-
- /* make sure a grab isn't going on currently with this buffer */
-
- switch (zr->jpg_gbuf[frame].state) {
-
- default:
- case BUZ_STATE_DMA:
- case BUZ_STATE_PEND:
- case BUZ_STATE_DONE:
- res = -EBUSY; /* what are you doing? */
- break;
-
- case BUZ_STATE_USER:
- /* since there is at least one unused buffer there's room for at least one more pend[] entry */
- zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = frame;
- zr->jpg_gbuf[frame].state = BUZ_STATE_PEND;
- zoran_feed_stat_com(zr);
- res = 0;
- break;
-
- }
-
- spin_unlock_irqrestore(&zr->lock, flags);
-
- /* Start the zr36060 when the first frame is queued */
- if (zr->jpg_que_head == 1) {
- btor(ZR36057_JMC_Go_en, ZR36057_JMC);
- btwrite(ZR36057_JPC_P_Reset | ZR36057_JPC_CodTrnsEn | ZR36057_JPC_Active, ZR36057_JPC);
- }
- return res;
-}
-
-/*
- * Sync on a MJPEG buffer
- */
-
-static int jpg_sync(struct zoran *zr, struct zoran_sync *bs)
-{
- unsigned long flags;
- int frame;
-
- if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
- zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
- return -EINVAL;
- }
- while (zr->jpg_que_tail == zr->jpg_dma_tail) {
- interruptible_sleep_on(&zr->jpg_capq);
- if (signal_pending(current))
- return -ERESTARTSYS;
- }
-
- spin_lock_irqsave(&zr->lock, flags);
-
- frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];
-
- /* buffer should now be in BUZ_STATE_DONE */
-
- if (zr->jpg_gbuf[frame].state != BUZ_STATE_DONE)
- printk(KERN_ERR "%s: jpg_sync - internal error\n", zr->name);
-
- *bs = zr->jpg_gbuf[frame].bs;
- zr->jpg_gbuf[frame].state = BUZ_STATE_USER;
-
- spin_unlock_irqrestore(&zr->lock, flags);
-
- return 0;
-}
-
-/* when this is called the spinlock must be held */
-static void zoran_feed_stat_com(struct zoran *zr)
-{
- /* move frames from pending queue to DMA */
-
- int frame, i, max_stat_com;
-
- max_stat_com = (zr->params.TmpDcm == 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);
-
- while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com
- && zr->jpg_dma_head != zr->jpg_que_head) {
-
- frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME];
- if (zr->params.TmpDcm == 1) {
- /* fill 1 stat_com entry */
- i = zr->jpg_dma_head & BUZ_MASK_STAT_COM;
- zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus;
- } else {
- /* fill 2 stat_com entries */
- i = (zr->jpg_dma_head & 1) * 2;
- zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus;
- zr->stat_com[i + 1] = zr->jpg_gbuf[frame].frag_tab_bus;
- }
- zr->jpg_gbuf[frame].state = BUZ_STATE_DMA;
- zr->jpg_dma_head++;
-
- }
-}
-
-/* when this is called the spinlock must be held */
-static void zoran_reap_stat_com(struct zoran *zr)
-{
- /* move frames from DMA queue to done queue */
-
- int i;
- u32 stat_com;
- unsigned int seq;
- unsigned int dif;
- int frame;
- struct zoran_gbuffer *gbuf;
-
- /* In motion decompress we don't have a hardware frame counter,
- we just count the interrupts here */
-
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
- zr->jpg_seq_num++;
-
- while (zr->jpg_dma_tail != zr->jpg_dma_head) {
- if (zr->params.TmpDcm == 1)
- i = zr->jpg_dma_tail & BUZ_MASK_STAT_COM;
- else
- i = (zr->jpg_dma_tail & 1) * 2 + 1;
-
- stat_com = zr->stat_com[i];
-
- if ((stat_com & 1) == 0) {
- return;
- }
- frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
- gbuf = &zr->jpg_gbuf[frame];
- get_fast_time(&gbuf->bs.timestamp);
-
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- gbuf->bs.length = (stat_com & 0x7fffff) >> 1;
-
- /* update sequence number with the help of the counter in stat_com */
-
- seq = stat_com >> 24;
- dif = (seq - zr->jpg_seq_num) & 0xff;
- zr->jpg_seq_num += dif;
- } else {
- gbuf->bs.length = 0;
- }
- gbuf->bs.seq = zr->params.TmpDcm == 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;
- gbuf->state = BUZ_STATE_DONE;
-
- zr->jpg_dma_tail++;
- }
-}
-
-static void zoran_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
- u32 stat, astat;
- int count;
- struct zoran *zr;
- unsigned long flags;
-
- zr = (struct zoran *) dev_id;
- count = 0;
-
- spin_lock_irqsave(&zr->lock, flags);
- while (1) {
- /* get/clear interrupt status bits */
- stat = btread(ZR36057_ISR);
- astat = stat & IRQ_MASK;
- if (!astat) {
- break;
- }
- btwrite(astat, ZR36057_ISR);
- IDEBUG(printk(BUZ_DEBUG "-%u: astat %08x stat %08x\n", zr->id, astat, stat));
-
-#if (IRQ_MASK & ZR36057_ISR_GIRQ0)
- if (astat & ZR36057_ISR_GIRQ0) {
-
- /* Interrupts may still happen when zr->v4l_memgrab_active is switched off.
- We simply ignore them */
-
- if (zr->v4l_memgrab_active) {
-
-/* A lot more checks should be here ... */
- if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0)
- printk(KERN_WARNING "%s: BuzIRQ with SnapShot off ???\n", zr->name);
-
- if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
- /* There is a grab on a frame going on, check if it has finished */
-
- if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) {
- /* it is finished, notify the user */
-
- zr->v4l_gbuf[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
- zr->v4l_grab_frame = NO_GRAB_ACTIVE;
- zr->v4l_grab_seq++;
- zr->v4l_pend_tail++;
- }
- }
- if (zr->v4l_grab_frame == NO_GRAB_ACTIVE)
- wake_up_interruptible(&zr->v4l_capq);
-
- /* Check if there is another grab queued */
-
- if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
- zr->v4l_pend_tail != zr->v4l_pend_head) {
-
- int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
- u32 reg;
-
- zr->v4l_grab_frame = frame;
-
- /* Set zr36057 video front end and enable video */
-
- /* Buffer address */
-
- reg = zr->v4l_gbuf[frame].fbuffer_bus;
- btwrite(reg, ZR36057_VDTR);
- if (zr->video_interlace)
- reg += zr->gbpl;
- btwrite(reg, ZR36057_VDBR);
-
- /* video stride, status, and frame grab register */
-
-#ifdef XAWTV_HACK
- reg = (zr->gwidth > 720) ? ((zr->gwidth & ~3) - 720) * zr->gbpl / zr->gwidth : 0;
-#else
- reg = 0;
-#endif
- if (zr->video_interlace)
- reg += zr->gbpl;
- reg = (reg << ZR36057_VSSFGR_DispStride);
- reg |= ZR36057_VSSFGR_VidOvf;
- reg |= ZR36057_VSSFGR_SnapShot;
- reg |= ZR36057_VSSFGR_FrameGrab;
- btwrite(reg, ZR36057_VSSFGR);
-
- btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);
- }
- }
- }
-#endif /* (IRQ_MASK & ZR36057_ISR_GIRQ0) */
-
-#if (IRQ_MASK & ZR36057_ISR_GIRQ1)
- if (astat & ZR36057_ISR_GIRQ1) {
- unsigned csr = zr36060_read_8(zr, 0x001);
- unsigned isr = zr36060_read_8(zr, 0x008);
-
- IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_GIRQ1 60_code=%02x 60_intr=%02x\n",
- zr->name, csr, isr));
-
- btand(~ZR36057_ICR_GIRQ1, ZR36057_ICR);
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- }
-#endif /* (IRQ_MASK & ZR36057_ISR_GIRQ1) */
-
-#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
- if (astat & ZR36057_ISR_CodRepIRQ) {
- IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", zr->name));
- btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
- }
-#endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
-
-#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
- if ((astat & ZR36057_ISR_JPEGRepIRQ) &&
- (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) {
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- }
-#endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
-
- count++;
- if (count > 10) {
- printk(KERN_WARNING "%s: irq loop %d\n", zr->name, count);
- if (count > 20) {
- btwrite(0, ZR36057_ICR);
- printk(KERN_ERR "%s: IRQ lockup, cleared int mask\n", zr->name);
- break;
- }
- }
- }
- spin_unlock_irqrestore(&zr->lock, flags);
-}
-
-/* Check a zoran_params struct for correctness, insert default params */
-
-static int zoran_check_params(struct zoran *zr, struct zoran_params *params)
-{
- int err = 0, err0 = 0;
-
- /* insert constant params */
-
- params->major_version = MAJOR_VERSION;
- params->minor_version = MINOR_VERSION;
-
- /* Check input and norm */
-
- if (params->input != 0 && params->input != 1) {
- err++;
- }
- if (params->norm != VIDEO_MODE_PAL && params->norm != VIDEO_MODE_NTSC) {
- err++;
- }
- /* Check decimation, set default values for decimation = 1, 2, 4 */
-
- switch (params->decimation) {
- case 1:
-
- params->HorDcm = 1;
- params->VerDcm = 1;
- params->TmpDcm = 1;
- params->field_per_buff = 2;
-
- params->img_x = 0;
- params->img_y = 0;
- params->img_width = 720;
- params->img_height = tvnorms[params->norm].Ha / 2;
- break;
-
- case 2:
-
- params->HorDcm = 2;
- params->VerDcm = 1;
- params->TmpDcm = 2;
- params->field_per_buff = 1;
-
- params->img_x = 8;
- params->img_y = 0;
- params->img_width = 704;
- params->img_height = tvnorms[params->norm].Ha / 2;
- break;
-
- case 4:
-
- params->HorDcm = 4;
- params->VerDcm = 2;
- params->TmpDcm = 2;
- params->field_per_buff = 1;
-
- params->img_x = 8;
- params->img_y = 0;
- params->img_width = 704;
- params->img_height = tvnorms[params->norm].Ha / 2;
- break;
-
- case 0:
-
- /* We have to check the data the user has set */
-
- if (params->HorDcm != 1 && params->HorDcm != 2 && params->HorDcm != 4)
- err0++;
- if (params->VerDcm != 1 && params->VerDcm != 2)
- err0++;
- if (params->TmpDcm != 1 && params->TmpDcm != 2)
- err0++;
- if (params->field_per_buff != 1 && params->field_per_buff != 2)
- err0++;
-
- if (params->img_x < 0)
- err0++;
- if (params->img_y < 0)
- err0++;
- if (params->img_width < 0)
- err0++;
- if (params->img_height < 0)
- err0++;
- if (params->img_x + params->img_width > 720)
- err0++;
- if (params->img_y + params->img_height > tvnorms[params->norm].Ha / 2)
- err0++;
- if (params->img_width % (16 * params->HorDcm) != 0)
- err0++;
- if (params->img_height % (8 * params->VerDcm) != 0)
- err0++;
-
- if (err0) {
- err++;
- }
- break;
-
- default:
- err++;
- break;
- }
-
- if (params->quality > 100)
- params->quality = 100;
- if (params->quality < 5)
- params->quality = 5;
-
- if (params->APPn < 0)
- params->APPn = 0;
- if (params->APPn > 15)
- params->APPn = 15;
- if (params->APP_len < 0)
- params->APP_len = 0;
- if (params->APP_len > 60)
- params->APP_len = 60;
- if (params->COM_len < 0)
- params->COM_len = 0;
- if (params->COM_len > 60)
- params->COM_len = 60;
-
- if (err)
- return -EINVAL;
-
- return 0;
-
-}
-static void zoran_open_init_params(struct zoran *zr)
-{
- int i;
-
- /* Per default, map the V4L Buffers */
-
- zr->map_mjpeg_buffers = 0;
-
- /* User must explicitly set a window */
-
- zr->window_set = 0;
-
- zr->window.x = 0;
- zr->window.y = 0;
- zr->window.width = 0;
- zr->window.height = 0;
- zr->window.chromakey = 0;
- zr->window.flags = 0;
- zr->window.clips = NULL;
- zr->window.clipcount = 0;
-
- zr->video_interlace = 0;
-
- zr->v4l_memgrab_active = 0;
- zr->v4l_overlay_active = 0;
-
- zr->v4l_grab_frame = NO_GRAB_ACTIVE;
- zr->v4l_grab_seq = 0;
-
- zr->gwidth = 0;
- zr->gheight = 0;
- zr->gformat = 0;
- zr->gbpl = 0;
-
- /* DMA ring stuff for V4L */
-
- zr->v4l_pend_tail = 0;
- zr->v4l_pend_head = 0;
- for (i = 0; i < v4l_nbufs; i++) {
- zr->v4l_gbuf[i].state = BUZ_STATE_USER; /* nothing going on */
- }
-
- /* Set necessary params and call zoran_check_params to set the defaults */
-
- zr->params.decimation = 1;
-
- zr->params.quality = 50; /* default compression factor 8 */
- zr->params.odd_even = 1;
-
- zr->params.APPn = 0;
- zr->params.APP_len = 0; /* No APPn marker */
- for (i = 0; i < 60; i++)
- zr->params.APP_data[i] = 0;
-
- zr->params.COM_len = 0; /* No COM marker */
- for (i = 0; i < 60; i++)
- zr->params.COM_data[i] = 0;
-
- zr->params.VFIFO_FB = 0;
-
- memset(zr->params.reserved, 0, sizeof(zr->params.reserved));
-
- zr->params.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT;
-
- i = zoran_check_params(zr, &zr->params);
- if (i)
- printk(KERN_ERR "%s: zoran_open_init_params internal error\n", zr->name);
-}
-
-/*
- * Open a buz card. Right now the flags stuff is just playing
- */
-
-static int zoran_open(struct video_device *dev, int flags)
-{
- struct zoran *zr = (struct zoran *) dev;
-
- DEBUG(printk(KERN_INFO ": zoran_open\n"));
-
- switch (flags) {
-
- case 0:
- if (zr->user)
- return -EBUSY;
- zr->user++;
-
- if (v4l_fbuffer_alloc(zr) < 0) {
- zr->user--;
- return -ENOMEM;
- }
- /* default setup */
-
- zoran_open_init_params(zr);
-
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
-
- btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts
-
- btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);
-
- break;
-
- default:
- return -EBUSY;
-
- }
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void zoran_close(struct video_device *dev)
-{
- struct zoran *zr = (struct zoran *) dev;
-
- DEBUG(printk(KERN_INFO ": zoran_close\n"));
-
- /* disable interrupts */
- btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
-
- /* wake up sleeping beauties */
- wake_up_interruptible(&zr->v4l_capq);
- wake_up_interruptible(&zr->jpg_capq);
-
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
- zr36057_set_memgrab(zr, 0);
- if (zr->v4l_overlay_active)
- zr36057_overlay(zr, 0);
-
- zr->user--;
-
- v4l_fbuffer_free(zr);
- jpg_fbuffer_free(zr);
- zr->jpg_nbufs = 0;
-
- MOD_DEC_USE_COUNT;
- DEBUG(printk(KERN_INFO ": zoran_close done\n"));
-}
-
-
-static long zoran_read(struct video_device *dev, char *buf, unsigned long count, int nonblock)
-{
- return -EINVAL;
-}
-
-static long zoran_write(struct video_device *dev, const char *buf, unsigned long count, int nonblock)
-{
- return -EINVAL;
-}
-
-/*
- * ioctl routine
- */
-
-
-static int zoran_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct zoran *zr = (struct zoran *) dev;
-
- switch (cmd) {
-
- case VIDIOCGCAP:
- {
- struct video_capability b;
- IOCTL_DEBUG(printk("buz ioctl VIDIOCGCAP\n"));
- strncpy(b.name, zr->video_dev.name, sizeof(b.name));
- b.type = VID_TYPE_CAPTURE |
- VID_TYPE_OVERLAY |
- VID_TYPE_CLIPPING |
- VID_TYPE_FRAMERAM |
- VID_TYPE_SCALES;
- /* theoretically we could also flag VID_TYPE_SUBCAPTURE
- but this is not even implemented in the BTTV driver */
-
- b.channels = 2; /* composite, svhs */
- b.audios = 0;
- b.maxwidth = BUZ_MAX_WIDTH;
- b.maxheight = BUZ_MAX_HEIGHT;
- b.minwidth = BUZ_MIN_WIDTH;
- b.minheight = BUZ_MIN_HEIGHT;
- if (copy_to_user(arg, &b, sizeof(b))) {
- return -EFAULT;
- }
- return 0;
- }
-
- case VIDIOCGCHAN:
- {
- struct video_channel v;
-
- if (copy_from_user(&v, arg, sizeof(v))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl VIDIOCGCHAN for channel %d\n", v.channel));
- switch (v.channel) {
- case 0:
- strcpy(v.name, "Composite");
- break;
- case 1:
- strcpy(v.name, "SVHS");
- break;
- default:
- return -EINVAL;
- }
- v.tuners = 0;
- v.flags = 0;
- v.type = VIDEO_TYPE_CAMERA;
- v.norm = zr->params.norm;
- if (copy_to_user(arg, &v, sizeof(v))) {
- return -EFAULT;
- }
- return 0;
- }
-
- /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:
-
- * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input."
- * ^^^^^^^
- * The famos BTTV driver has it implemented with a struct video_channel argument
- * and we follow it for compatibility reasons
- *
- * BTW: this is the only way the user can set the norm!
- */
-
- case VIDIOCSCHAN:
- {
- struct video_channel v;
- int input;
- int on, res;
-
- if (copy_from_user(&v, arg, sizeof(v))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl VIDIOCSCHAN: channel=%d, norm=%d\n", v.channel, v.norm));
- switch (v.channel) {
- case 0:
- input = 3;
- break;
- case 1:
- input = 7;
- break;
- default:
- return -EINVAL;
- }
-
- if (v.norm != VIDEO_MODE_PAL
- && v.norm != VIDEO_MODE_NTSC) {
- return -EINVAL;
- }
- zr->params.norm = v.norm;
- zr->params.input = v.channel;
-
- /* We switch overlay off and on since a change in the norm
- needs different VFE settings */
-
- on = zr->v4l_overlay_active && !zr->v4l_memgrab_active;
- if (on)
- zr36057_overlay(zr, 0);
-
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_NORM, &zr->params.norm);
-
- if (on)
- zr36057_overlay(zr, 1);
-
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
- if (res)
- return res;
-
- return 0;
- }
-
- case VIDIOCGTUNER:
- case VIDIOCSTUNER:
- return -EINVAL;
-
- case VIDIOCGPICT:
- {
- struct video_picture p = zr->picture;
-
- IOCTL_DEBUG(printk("buz ioctl VIDIOCGPICT\n"));
- p.depth = zr->buffer.depth;
- switch (zr->buffer.depth) {
- case 15:
- p.palette = VIDEO_PALETTE_RGB555;
- break;
-
- case 16:
- p.palette = VIDEO_PALETTE_RGB565;
- break;
-
- case 24:
- p.palette = VIDEO_PALETTE_RGB24;
- break;
-
- case 32:
- p.palette = VIDEO_PALETTE_RGB32;
- break;
- }
-
- if (copy_to_user(arg, &p, sizeof(p))) {
- return -EFAULT;
- }
- return 0;
- }
-
- case VIDIOCSPICT:
- {
- struct video_picture p;
-
- if (copy_from_user(&p, arg, sizeof(p))) {
- return -EFAULT;
- }
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);
- IOCTL_DEBUG(printk("buz ioctl VIDIOCSPICT bri=%d hue=%d col=%d con=%d dep=%d pal=%d\n",
- p.brightness, p.hue, p.colour, p.contrast, p.depth, p.palette));
- /* The depth and palette values have no meaning to us,
- should we return -EINVAL if they don't fit ? */
- zr->picture = p;
- return 0;
- }
-
- case VIDIOCCAPTURE:
- {
- int v, res;
-
- if (copy_from_user(&v, arg, sizeof(v))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl VIDIOCCAPTURE: %d\n", v));
- /* If there is nothing to do, return immediatly */
-
- if ((v && zr->v4l_overlay_active) || (!v && !zr->v4l_overlay_active))
- return 0;
-
- if (v == 0) {
- zr->v4l_overlay_active = 0;
- if (!zr->v4l_memgrab_active)
- zr36057_overlay(zr, 0);
- /* When a grab is running, the video simply won't be switched on any more */
- } else {
- if (!zr->buffer_set || !zr->window_set) {
- return -EINVAL;
- }
- zr->v4l_overlay_active = 1;
- if (!zr->v4l_memgrab_active)
- zr36057_overlay(zr, 1);
- /* When a grab is running, the video will be switched on when grab is finished */
- }
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
- if (res)
- return res;
- return 0;
- }
-
- case VIDIOCGWIN:
- {
- IOCTL_DEBUG(printk("buz ioctl VIDIOCGWIN\n"));
- if (copy_to_user(arg, &zr->window, sizeof(zr->window))) {
- return -EFAULT;
- }
- return 0;
- }
-
- case VIDIOCSWIN:
- {
- struct video_clip *vcp;
- struct video_window vw;
- int on, end, res;
-
- if (copy_from_user(&vw, arg, sizeof(vw))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl VIDIOCSWIN: x=%d y=%d w=%d h=%d clipcount=%d\n", vw.x, vw.y, vw.width, vw.height, vw.clipcount));
- if (!zr->buffer_set) {
- return -EINVAL;
- }
- /*
- * The video front end needs 4-byte alinged line sizes, we correct that
- * silently here if necessary
- */
-
- if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
- end = (vw.x + vw.width) & ~1; /* round down */
- vw.x = (vw.x + 1) & ~1; /* round up */
- vw.width = end - vw.x;
- }
- if (zr->buffer.depth == 24) {
- end = (vw.x + vw.width) & ~3; /* round down */
- vw.x = (vw.x + 3) & ~3; /* round up */
- vw.width = end - vw.x;
- }
-#if 0
- // At least xawtv seems to care about the following - just leave it away
- /*
- * Also corrected silently (as long as window fits at all):
- * video not fitting the screen
- */
-#if 0
- if (vw.x < 0 || vw.y < 0 || vw.x + vw.width > zr->buffer.width ||
- vw.y + vw.height > zr->buffer.height) {
- printk(BUZ_ERR ": VIDIOCSWIN: window does not fit frame buffer: %dx%d+%d*%d\n",
- vw.width, vw.height, vw.x, vw.y);
- return -EINVAL;
- }
-#else
- if (vw.x < 0)
- vw.x = 0;
- if (vw.y < 0)
- vw.y = 0;
- if (vw.x + vw.width > zr->buffer.width)
- vw.width = zr->buffer.width - vw.x;
- if (vw.y + vw.height > zr->buffer.height)
- vw.height = zr->buffer.height - vw.y;
-#endif
-#endif
-
- /* Check for vaild parameters */
- if (vw.width < BUZ_MIN_WIDTH || vw.height < BUZ_MIN_HEIGHT ||
- vw.width > BUZ_MAX_WIDTH || vw.height > BUZ_MAX_HEIGHT) {
- return -EINVAL;
- }
-#ifdef XAWTV_HACK
- if (vw.width > 720)
- vw.width = 720;
-#endif
-
- zr->window.x = vw.x;
- zr->window.y = vw.y;
- zr->window.width = vw.width;
- zr->window.height = vw.height;
- zr->window.chromakey = 0;
- zr->window.flags = 0; // RJ: Is this intended for interlace on/off ?
-
- zr->window.clips = NULL;
- zr->window.clipcount = vw.clipcount;
-
- /*
- * If an overlay is running, we have to switch it off
- * and switch it on again in order to get the new settings in effect.
- *
- * We also want to avoid that the overlay mask is written
- * when an overlay is running.
- */
-
- on = zr->v4l_overlay_active && !zr->v4l_memgrab_active;
- if (on)
- zr36057_overlay(zr, 0);
-
- /*
- * Write the overlay mask if clips are wanted.
- */
- if (vw.clipcount) {
- vcp = vmalloc(sizeof(struct video_clip) * (vw.clipcount + 4));
- if (vcp == NULL) {
- return -ENOMEM;
- }
- if (copy_from_user(vcp, vw.clips, sizeof(struct video_clip) * vw.clipcount)) {
- vfree(vcp);
- return -EFAULT;
- }
- write_overlay_mask(zr, vcp, vw.clipcount);
- vfree(vcp);
- }
- if (on)
- zr36057_overlay(zr, 1);
- zr->window_set = 1;
-
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
- if (res)
- return res;
-
- return 0;
- }
-
- case VIDIOCGFBUF:
- {
- IOCTL_DEBUG(printk("buz ioctl VIDIOCGFBUF\n"));
- if (copy_to_user(arg, &zr->buffer, sizeof(zr->buffer))) {
- return -EFAULT;
- }
- return 0;
- }
-
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
-
- if (!capable(CAP_SYS_ADMIN)
- || !capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
-
- IOCTL_DEBUG(printk("buz ioctl VIDIOCSFBUF: base=0x%x w=%d h=%d depth=%d bpl=%d\n", (u32) v.base, v.width, v.height, v.depth, v.bytesperline));
- if (zr->v4l_overlay_active) {
- /* Has the user gotten crazy ... ? */
- return -EINVAL;
- }
- if (v.depth != 15
- && v.depth != 16
- && v.depth != 24
- && v.depth != 32) {
- return -EINVAL;
- }
- if (v.height <= 0 || v.width <= 0 || v.bytesperline <= 0) {
- return -EINVAL;
- }
- if (v.bytesperline & 3) {
- return -EINVAL;
- }
- if (v.base) {
- zr->buffer.base = (void *) ((unsigned long) v.base & ~3);
- }
- zr->buffer.height = v.height;
- zr->buffer.width = v.width;
- zr->buffer.depth = v.depth;
- zr->buffer.bytesperline = v.bytesperline;
-
- if (zr->buffer.base)
- zr->buffer_set = 1;
- zr->window_set = 0; /* The user should set new window parameters */
- return 0;
- }
-
- /* RJ: what is VIDIOCKEY intended to do ??? */
-
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
- case VIDIOCGAUDIO:
- case VIDIOCSAUDIO:
- return -EINVAL;
-
- case VIDIOCSYNC:
- {
- int v;
-
- if (copy_from_user(&v, arg, sizeof(v))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl VIDIOCSYNC %d\n", v));
- return v4l_sync(zr, v);
- }
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap vm;
-
- if (copy_from_user((void *) &vm, (void *) arg, sizeof(vm))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl VIDIOCMCAPTURE frame=%d geom=%dx%d fmt=%d\n",
- vm.frame, vm.height, vm.width, vm.format));
- return v4l_grab(zr, &vm);
- }
-
- case VIDIOCGMBUF:
- {
- struct video_mbuf vm;
- int i;
-
- IOCTL_DEBUG(printk("buz ioctl VIDIOCGMBUF\n"));
-
- vm.size = v4l_nbufs * v4l_bufsize;
- vm.frames = v4l_nbufs;
- for (i = 0; i < v4l_nbufs; i++) {
- vm.offsets[i] = i * v4l_bufsize;
- }
-
- /* The next mmap will map the V4L buffers */
- zr->map_mjpeg_buffers = 0;
-
- if (copy_to_user(arg, &vm, sizeof(vm))) {
- return -EFAULT;
- }
- return 0;
- }
-
- case VIDIOCGUNIT:
- {
- struct video_unit vu;
-
- IOCTL_DEBUG(printk("buz ioctl VIDIOCGUNIT\n"));
- vu.video = zr->video_dev.minor;
- vu.vbi = VIDEO_NO_UNIT;
- vu.radio = VIDEO_NO_UNIT;
- vu.audio = VIDEO_NO_UNIT;
- vu.teletext = VIDEO_NO_UNIT;
- if (copy_to_user(arg, &vu, sizeof(vu)))
- return -EFAULT;
- return 0;
- }
-
- /*
- * RJ: In principal we could support subcaptures for V4L grabbing.
- * Not even the famous BTTV driver has them, however.
- * If there should be a strong demand, one could consider
- * to implement them.
- */
- case VIDIOCGCAPTURE:
- case VIDIOCSCAPTURE:
- return -EINVAL;
-
- case BUZIOC_G_PARAMS:
- {
- IOCTL_DEBUG(printk("buz ioctl BUZIOC_G_PARAMS\n"));
- if (copy_to_user(arg, &(zr->params), sizeof(zr->params)))
- return -EFAULT;
- return 0;
- }
-
- case BUZIOC_S_PARAMS:
- {
- struct zoran_params bp;
- int input, on;
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- return -EINVAL;
- }
- if (copy_from_user(&bp, arg, sizeof(bp))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl BUZIOC_S_PARAMS\n"));
-
- /* Check the params first before overwriting our internal values */
-
- if (zoran_check_params(zr, &bp))
- return -EINVAL;
-
- zr->params = bp;
-
- /* Make changes of input and norm go into effect immediatly */
-
- /* We switch overlay off and on since a change in the norm
- needs different VFE settings */
-
- on = zr->v4l_overlay_active && !zr->v4l_memgrab_active;
- if (on)
- zr36057_overlay(zr, 0);
-
- input = zr->params.input == 0 ? 3 : 7;
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_NORM, &zr->params.norm);
-
- if (on)
- zr36057_overlay(zr, 1);
-
- if (copy_to_user(arg, &bp, sizeof(bp))) {
- return -EFAULT;
- }
- return 0;
- }
-
- case BUZIOC_REQBUFS:
- {
- struct zoran_requestbuffers br;
-
- if (zr->jpg_buffers_allocated) {
- return -EINVAL;
- }
- if (copy_from_user(&br, arg, sizeof(br))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl BUZIOC_REQBUFS count = %lu size=%lu\n",
- br.count, br.size));
- /* Enforce reasonable lower and upper limits */
- if (br.count < 4)
- br.count = 4; /* Could be choosen smaller */
- if (br.count > BUZ_MAX_FRAME)
- br.count = BUZ_MAX_FRAME;
- br.size = PAGE_ALIGN(br.size);
- if (br.size < 8192)
- br.size = 8192; /* Arbitrary */
- /* br.size is limited by 1 page for the stat_com tables to a Maximum of 2 MB */
- if (br.size > (512 * 1024))
- br.size = (512 * 1024); /* 512 K should be enough */
- if (zr->need_contiguous && br.size > MAX_KMALLOC_MEM)
- br.size = MAX_KMALLOC_MEM;
-
- zr->jpg_nbufs = br.count;
- zr->jpg_bufsize = br.size;
-
- if (jpg_fbuffer_alloc(zr))
- return -ENOMEM;
-
- /* The next mmap will map the MJPEG buffers */
- zr->map_mjpeg_buffers = 1;
-
- if (copy_to_user(arg, &br, sizeof(br))) {
- return -EFAULT;
- }
- return 0;
- }
-
- case BUZIOC_QBUF_CAPT:
- {
- int nb;
-
- if (copy_from_user((void *) &nb, (void *) arg, sizeof(int))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl BUZIOC_QBUF_CAPT %d\n", nb));
- return jpg_qbuf(zr, nb, BUZ_MODE_MOTION_COMPRESS);
- }
-
- case BUZIOC_QBUF_PLAY:
- {
- int nb;
-
- if (copy_from_user((void *) &nb, (void *) arg, sizeof(int))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl BUZIOC_QBUF_PLAY %d\n", nb));
- return jpg_qbuf(zr, nb, BUZ_MODE_MOTION_DECOMPRESS);
- }
-
- case BUZIOC_SYNC:
- {
- struct zoran_sync bs;
- int res;
-
- IOCTL_DEBUG(printk("buz ioctl BUZIOC_SYNC\n"));
- res = jpg_sync(zr, &bs);
- if (copy_to_user(arg, &bs, sizeof(bs))) {
- return -EFAULT;
- }
- return res;
- }
-
- case BUZIOC_G_STATUS:
- {
- struct zoran_status bs;
- int norm, input, status;
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- return -EINVAL;
- }
- if (copy_from_user(&bs, arg, sizeof(bs))) {
- return -EFAULT;
- }
- IOCTL_DEBUG(printk("buz ioctl BUZIOC_G_STATUS\n"));
- switch (bs.input) {
- case 0:
- input = 3;
- break;
- case 1:
- input = 7;
- break;
- default:
- return -EINVAL;
- }
-
- /* Set video norm to VIDEO_MODE_AUTO */
-
- norm = VIDEO_MODE_AUTO;
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &norm);
-
- /* sleep 1 second */
-
- schedule_timeout(HZ);
-
- /* Get status of video decoder */
-
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_STATUS, &status);
- bs.signal = (status & DECODER_STATUS_GOOD) ? 1 : 0;
- bs.norm = (status & DECODER_STATUS_NTSC) ? VIDEO_MODE_NTSC : VIDEO_MODE_PAL;
- bs.color = (status & DECODER_STATUS_COLOR) ? 1 : 0;
-
- /* restore previous input and norm */
- input = zr->params.input == 0 ? 3 : 7;
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
-
- if (copy_to_user(arg, &bs, sizeof(bs))) {
- return -EFAULT;
- }
- return 0;
- }
-
- default:
- return -ENOIOCTLCMD;
-
- }
- return 0;
-}
-
-
-/*
- * This maps the buffers to user space.
- *
- * Depending on the state of zr->map_mjpeg_buffers
- * the V4L or the MJPEG buffers are mapped
- *
- */
-
-static int zoran_mmap(struct video_device *dev, const char *adr, unsigned long size)
-{
- struct zoran *zr = (struct zoran *) dev;
- unsigned long start = (unsigned long) adr;
- unsigned long page, pos, todo, fraglen;
- int i, j;
-
- if (zr->map_mjpeg_buffers) {
- /* Map the MJPEG buffers */
-
- if (!zr->jpg_buffers_allocated) {
- return -ENOMEM;
- }
- if (size > zr->jpg_nbufs * zr->jpg_bufsize) {
- return -EINVAL;
- }
-
- for (i = 0; i < zr->jpg_nbufs; i++) {
- for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) {
- fraglen = (zr->jpg_gbuf[i].frag_tab[2 * j + 1] & ~1) << 1;
- todo = size;
- if (todo > fraglen)
- todo = fraglen;
- pos = (unsigned long) zr->jpg_gbuf[i].frag_tab[2 * j];
- page = virt_to_phys(bus_to_virt(pos)); /* should just be pos on i386 */
- if (remap_page_range(start, page, todo, PAGE_SHARED)) {
- printk(KERN_ERR "%s: zoran_mmap(V4L): remap_page_range failed\n", zr->name);
- return -EAGAIN;
- }
- size -= todo;
- start += todo;
- if (size == 0)
- break;
- if (zr->jpg_gbuf[i].frag_tab[2 * j + 1] & 1)
- break; /* was last fragment */
- }
- if (size == 0)
- break;
- }
- } else {
- /* Map the V4L buffers */
-
- if (size > v4l_nbufs * v4l_bufsize) {
- return -EINVAL;
- }
-
- for (i = 0; i < v4l_nbufs; i++) {
- todo = size;
- if (todo > v4l_bufsize)
- todo = v4l_bufsize;
- page = zr->v4l_gbuf[i].fbuffer_phys;
- DEBUG(printk("V4L remap page range %d 0x%x %d to 0x%x\n", i, page, todo, start));
- if (remap_page_range(start, page, todo, PAGE_SHARED)) {
- printk(KERN_ERR "%s: zoran_mmap(V4L): remap_page_range failed\n", zr->name);
- return -EAGAIN;
- }
- size -= todo;
- start += todo;
- if (size == 0)
- break;
- }
- }
- return 0;
-}
-
-static int zoran_init_done(struct video_device *dev)
-{
- return 0;
-}
-
-static struct video_device zoran_template =
-{
- BUZ_NAME,
- VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
- VID_TYPE_SCALES | VID_TYPE_SUBCAPTURE,
- VID_HARDWARE_ZR36067,
- zoran_open,
- zoran_close,
- zoran_read,
- zoran_write,
- NULL,
- zoran_ioctl,
- zoran_mmap,
- zoran_init_done,
- NULL,
- 0,
- 0
-};
-
-static int zr36057_init(int i)
-{
- struct zoran *zr = &zoran[i];
- unsigned long mem;
- unsigned mem_needed;
- int j;
- int rev;
-
- /* reset zr36057 */
- btwrite(0, ZR36057_SPGPPCR);
- mdelay(10);
-
- /* default setup of all parameters which will persist beetween opens */
-
- zr->user = 0;
-
- init_waitqueue_head(&zr->v4l_capq);
- init_waitqueue_head(&zr->jpg_capq);
-
- zr->map_mjpeg_buffers = 0; /* Map V4L buffers by default */
-
- zr->jpg_nbufs = 0;
- zr->jpg_bufsize = 0;
- zr->jpg_buffers_allocated = 0;
-
- zr->buffer_set = 0; /* Flag if frame buffer has been set */
- zr->buffer.base = (void *) vidmem;
- zr->buffer.width = 0;
- zr->buffer.height = 0;
- zr->buffer.depth = 0;
- zr->buffer.bytesperline = 0;
-
- zr->params.norm = default_norm ? 1 : 0; /* Avoid nonsense settings from user */
- zr->params.input = default_input ? 1 : 0; /* Avoid nonsense settings from user */
- zr->video_interlace = 0;
-
- /* Should the following be reset at every open ? */
-
- zr->picture.colour = 32768;
- zr->picture.brightness = 32768;
- zr->picture.hue = 32768;
- zr->picture.contrast = 32768;
- zr->picture.whiteness = 0;
- zr->picture.depth = 0;
- zr->picture.palette = 0;
-
- for (j = 0; j < VIDEO_MAX_FRAME; j++) {
- zr->v4l_gbuf[i].fbuffer = 0;
- zr->v4l_gbuf[i].fbuffer_phys = 0;
- zr->v4l_gbuf[i].fbuffer_bus = 0;
- }
-
- zr->stat_com = 0;
-
- /* default setup (will be repeated at every open) */
-
- zoran_open_init_params(zr);
-
- /* allocate memory *before* doing anything to the hardware in case allocation fails */
-
- /* STAT_COM table and overlay mask */
-
- mem_needed = (BUZ_NUM_STAT_COM + ((BUZ_MAX_WIDTH + 31) / 32) * BUZ_MAX_HEIGHT) * 4;
- mem = (unsigned long) kmalloc(mem_needed, GFP_KERNEL);
- if (!mem) {
- return -ENOMEM;
- }
- memset((void *) mem, 0, mem_needed);
-
- zr->stat_com = (u32 *) mem;
- for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */
- }
- zr->overlay_mask = (u32 *) (mem + BUZ_NUM_STAT_COM * 4);
-
- /* Initialize zr->jpg_gbuf */
-
- for (j = 0; j < BUZ_MAX_FRAME; j++) {
- zr->jpg_gbuf[j].frag_tab = 0;
- zr->jpg_gbuf[j].frag_tab_bus = 0;
- zr->jpg_gbuf[j].state = BUZ_STATE_USER;
- zr->jpg_gbuf[j].bs.frame = j;
- }
-
- /* take zr36057 out of reset now */
- btwrite(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR);
- mdelay(10);
-
- /* stop all DMA processes */
- btwrite(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
- /* assert P_Reset */
- btwrite(0, ZR36057_JPC);
-
- switch(zr->board)
- {
- case BOARD_BUZ:
-
- /* set up GPIO direction */
- btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR);
-
- /* Set up guest bus timing - Guests 0..3 Tdur=12, Trec=3 */
- btwrite((GPIO_MASK << 24) | 0x8888, ZR36057_GPPGCR1);
- mdelay(10);
-
- /* reset video decoder */
-
- GPIO(zr, 0, 0);
- mdelay(10);
- GPIO(zr, 0, 1);
- mdelay(10);
-
- /* reset JPEG codec */
- zr36060_sleep(zr, 0);
- mdelay(10);
- zr36060_reset(zr);
- mdelay(10);
-
- /* display codec revision */
- if ((rev=zr36060_read_8(zr, 0x022)) == 0x33) {
- printk(KERN_INFO "%s: Zoran ZR36060 (rev %d)\n",
- zr->name, zr36060_read_8(zr, 0x023));
- } else {
- printk(KERN_ERR "%s: Zoran ZR36060 not found (Rev=%d)\n", zr->name, rev);
- kfree((void *) zr->stat_com);
- return -1;
- }
- break;
-
- case BOARD_LML33:
-// btwrite(btread(ZR36057_SPGPPCR)&~ZR36057_SPGPPCR_SoftReset , ZR36057_SPGPPCR);
-// udelay(100);
-// btwrite(btread(ZR36057_SPGPPCR)|ZR36057_SPGPPCR_SoftReset , ZR36057_SPGPPCR);
-// udelay(1000);
-
- /*
- * Set up the GPIO direction
- */
- btwrite(btread(ZR36057_SPGPPCR_SoftReset)|0 , ZR36057_SPGPPCR);
- /* Set up guest bus timing - Guests 0..2 Tdur=12, Trec=3 */
- btwrite(0xFF00F888, ZR36057_GPPGCR1);
- mdelay(10);
- GPIO(zr, 5, 0); /* Analog video bypass */
- udelay(3000);
- GPIO(zr, 0, 0); /* Reset 819 */
- udelay(3000);
- GPIO(zr, 0, 1); /* 819 back */
- udelay(3000);
- /* reset JPEG codec */
- zr36060_sleep(zr, 0);
- udelay(3000);
- zr36060_reset(zr);
- udelay(3000);
-
- /* display codec revision */
- if ((rev=zr36060_read_8(zr, 0x022)) == 0x33) {
- printk(KERN_INFO "%s: Zoran ZR36060 (rev %d)\n",
- zr->name, zr36060_read_8(zr, 0x023));
- } else {
- printk(KERN_ERR "%s: Zoran ZR36060 not found (rev=%d)\n", zr->name, rev);
- kfree((void *) zr->stat_com);
- return -1;
- }
- break;
- }
- /* i2c */
- memcpy(&zr->i2c, &zoran_i2c_bus_template, sizeof(struct i2c_bus));
- sprintf(zr->i2c.name, "zoran%u", zr->id);
- zr->i2c.data = zr;
- if (i2c_register_bus(&zr->i2c) < 0) {
- kfree((void *) zr->stat_com);
- return -1;
- }
- /*
- * Now add the template and register the device unit.
- */
- memcpy(&zr->video_dev, &zoran_template, sizeof(zoran_template));
- sprintf(zr->video_dev.name, "zoran%u", zr->id);
- if (video_register_device(&zr->video_dev, VFL_TYPE_GRABBER) < 0) {
- i2c_unregister_bus(&zr->i2c);
- kfree((void *) zr->stat_com);
- return -1;
- }
- /* toggle JPEG codec sleep to sync PLL */
- zr36060_sleep(zr, 1);
- mdelay(10);
- zr36060_sleep(zr, 0);
- mdelay(10);
-
- /* Enable bus-mastering */
- pci_set_master(zr->pci_dev);
-
- j = zr->params.input == 0 ? 3 : 7;
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &j);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
- i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_NORM, &zr->params.norm);
-
- /* set individual interrupt enables (without GIRQ0)
- but don't global enable until zoran_open() */
-
- btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ0, ZR36057_ICR);
-
- if(request_irq(zr->pci_dev->irq, zoran_irq,
- SA_SHIRQ | SA_INTERRUPT, zr->name, (void *) zr)<0)
- {
- printk(KERN_ERR "%s: Can't assign irq.\n", zr->name);
- video_unregister_device(&zr->video_dev);
- i2c_unregister_bus(&zr->i2c);
- kfree((void *) zr->stat_com);
- return -1;
- }
- zr->initialized = 1;
- return 0;
-}
-
-
-
-static void release_zoran(void)
-{
- u8 command;
- int i;
- struct zoran *zr;
-
- for (i = 0; i < zoran_num; i++) {
- zr = &zoran[i];
-
- if (!zr->initialized)
- continue;
-
- /* unregister i2c_bus */
- i2c_unregister_bus((&zr->i2c));
-
- /* disable PCI bus-mastering */
- pci_read_config_byte(zr->pci_dev, PCI_COMMAND, &command);
- command &= ~PCI_COMMAND_MASTER;
- pci_write_config_byte(zr->pci_dev, PCI_COMMAND, command);
-
- /* put chip into reset */
- btwrite(0, ZR36057_SPGPPCR);
-
- free_irq(zr->pci_dev->irq, zr);
-
- /* unmap and free memory */
-
- kfree((void *) zr->stat_com);
-
- iounmap(zr->zr36057_mem);
-
- video_unregister_device(&zr->video_dev);
- }
-}
-
-/*
- * Scan for a Buz card (actually for the PCI controller ZR36057),
- * request the irq and map the io memory
- */
-
-static int find_zr36057(void)
-{
- unsigned char latency;
- struct zoran *zr;
- struct pci_dev *dev = NULL;
-
- zoran_num = 0;
-
- while (zoran_num < BUZ_MAX
- && (dev = pci_find_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
- zr = &zoran[zoran_num];
- zr->pci_dev = dev;
- zr->zr36057_mem = NULL;
- zr->id = zoran_num;
- sprintf(zr->name, "zoran%u", zr->id);
-
- spin_lock_init(&zr->lock);
-
- if (pci_enable_device(dev))
- continue;
-
- zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
- pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
- if (zr->revision < 2) {
- printk(KERN_INFO "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
- zr->name, zr->revision, zr->pci_dev->irq, zr->zr36057_adr);
- } else {
- unsigned short ss_vendor_id, ss_id;
-
- ss_vendor_id = zr->pci_dev->subsystem_vendor;
- ss_id = zr->pci_dev->subsystem_device;
- printk(KERN_INFO "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
- zr->name, zr->revision, zr->pci_dev->irq, zr->zr36057_adr);
- printk(KERN_INFO "%s: subsystem vendor=0x%04x id=0x%04x\n",
- zr->name, ss_vendor_id, ss_id);
- if(ss_vendor_id==0xFF10 && ss_id == 0xDE41)
- {
- zr->board = BOARD_LML33;
- printk(KERN_INFO "%s: LML33 detected.\n", zr->name);
- }
- }
-
- zr->zr36057_mem = ioremap(zr->zr36057_adr, 0x1000);
- if (!zr->zr36057_mem) {
- printk(KERN_ERR "%s: ioremap failed\n", zr->name);
- /* XXX handle error */
- }
-
- /* set PCI latency timer */
- pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, &latency);
- if (latency != 48) {
- printk(KERN_INFO "%s: Changing PCI latency from %d to 48.\n", zr->name, latency);
- latency = 48;
- pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, latency);
- }
- zoran_num++;
- }
- if (zoran_num == 0)
- printk(KERN_INFO "zoran: no cards found.\n");
-
- return zoran_num;
-}
-
-static void handle_chipset(void)
-{
- if(pci_pci_problems&PCIPCI_FAIL)
- {
- printk(KERN_WARNING "buz: This configuration is known to have PCI to PCI DMA problems\n");
- printk(KERN_WARNING "buz: You may not be able to use overlay mode.\n");
- }
-
-
- if(pci_pci_problems&PCIPCI_TRITON)
- {
- printk("buz: Enabling Triton support.\n");
- triton = 1;
- }
-
- if(pci_pci_problems&PCIPCI_NATOMA)
- {
- printk("buz: Enabling Natoma workaround.\n");
- natoma = 1;
- }
-}
-
-#ifdef MODULE
-int init_module(void)
-#else
-int init_zoran_cards(struct video_init *unused)
-#endif
-{
- int i;
-
-
- printk(KERN_INFO "Zoran driver 1.00 (c) 1999 Rainer Johanni, Dave Perks.\n");
-
- /* Look for Buz cards */
-
- if (find_zr36057() <= 0) {
- return -EIO;
- }
- printk(KERN_INFO"zoran: %d zoran card(s) found\n", zoran_num);
-
- if (zoran_num == 0)
- return -ENXIO;
-
-
- /* check the parameters we have been given, adjust if necessary */
-
- if (v4l_nbufs < 0)
- v4l_nbufs = 0;
- if (v4l_nbufs > VIDEO_MAX_FRAME)
- v4l_nbufs = VIDEO_MAX_FRAME;
- /* The user specfies the in KB, we want them in byte (and page aligned) */
- v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024);
- if (v4l_bufsize < 32768)
- v4l_bufsize = 32768;
- /* 2 MB is arbitrary but sufficient for the maximum possible images */
- if (v4l_bufsize > 2048 * 1024)
- v4l_bufsize = 2048 * 1024;
-
- printk(KERN_INFO "zoran: using %d V4L buffers of size %d KB\n", v4l_nbufs, v4l_bufsize >> 10);
-
- /* Use parameter for vidmem or try to find a video card */
-
- if (vidmem) {
- printk(KERN_INFO "zoran: Using supplied video memory base address @ 0x%lx\n", vidmem);
- }
-
- /* check if we have a Triton or Natome chipset */
-
- handle_chipset();
-
- /* take care of Natoma chipset and a revision 1 zr36057 */
-
- for (i = 0; i < zoran_num; i++) {
- if (natoma && zoran[i].revision <= 1) {
- zoran[i].need_contiguous = 1;
- printk(KERN_INFO "%s: ZR36057/Natome bug, max. buffer size is 128K\n", zoran[i].name);
- } else {
- zoran[i].need_contiguous = 0;
- }
- }
-
- /* initialize the Buzs */
-
- /* We have to know which ones must be released if an error occurs */
- for (i = 0; i < zoran_num; i++)
- zoran[i].initialized = 0;
-
- for (i = 0; i < zoran_num; i++) {
- if (zr36057_init(i) < 0) {
- release_zoran();
- return -EIO;
- }
- }
-
- return 0;
-}
-
-
-
-#ifdef MODULE
-
-void cleanup_module(void)
-{
- release_zoran();
-}
-
-#endif
diff --git a/drivers/char/buz.h b/drivers/char/buz.h
deleted file mode 100644
index 06b794a09..000000000
--- a/drivers/char/buz.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- buz - Iomega Buz driver
-
- Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
-
- based on
-
- buz.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
-
- and
-
- bttv - Bt848 frame grabber driver
- Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.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 of the License, 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.
- */
-
-#ifndef _BUZ_H_
-#define _BUZ_H_
-
-/* The Buz only supports a maximum width of 720, but some V4L
- applications (e.g. xawtv are more happy with 768).
- If XAWTV_HACK is defined, we try to fake a device with bigger width */
-
-#define XAWTV_HACK
-
-#ifdef XAWTV_HACK
-#define BUZ_MAX_WIDTH 768 /* never display more than 768 pixels */
-#else
-#define BUZ_MAX_WIDTH 720 /* never display more than 720 pixels */
-#endif
-#define BUZ_MAX_HEIGHT 576 /* never display more than 576 rows */
-#define BUZ_MIN_WIDTH 32 /* never display less than 32 pixels */
-#define BUZ_MIN_HEIGHT 24 /* never display less than 24 rows */
-
-struct zoran_requestbuffers {
- unsigned long count; /* Number of buffers for MJPEG grabbing */
- unsigned long size; /* Size PER BUFFER in bytes */
-};
-
-struct zoran_sync {
- unsigned long frame; /* number of buffer that has been free'd */
- unsigned long length; /* number of code bytes in buffer (capture only) */
- unsigned long seq; /* frame sequence number */
- struct timeval timestamp; /* timestamp */
-};
-
-struct zoran_status {
- int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */
- int signal; /* Returned: 1 if valid video signal detected */
- int norm; /* Returned: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
- int color; /* Returned: 1 if color signal detected */
-};
-
-struct zoran_params {
-
- /* The following parameters can only be queried */
-
- int major_version; /* Major version number of driver */
- int minor_version; /* Minor version number of driver */
-
- /* Main control parameters */
-
- int input; /* Input channel: 0 = Composite, 1 = S-VHS */
- int norm; /* Norm: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
- int decimation; /* decimation of captured video,
- enlargement of video played back.
- Valid values are 1, 2, 4 or 0.
- 0 is a special value where the user
- has full control over video scaling */
-
- /* The following parameters only have to be set if decimation==0,
- for other values of decimation they provide the data how the image is captured */
-
- int HorDcm; /* Horizontal decimation: 1, 2 or 4 */
- int VerDcm; /* Vertical decimation: 1 or 2 */
- int TmpDcm; /* Temporal decimation: 1 or 2,
- if TmpDcm==2 in capture every second frame is dropped,
- in playback every frame is played twice */
- int field_per_buff; /* Number of fields per buffer: 1 or 2 */
- int img_x; /* start of image in x direction */
- int img_y; /* start of image in y direction */
- int img_width; /* image width BEFORE decimation,
- must be a multiple of HorDcm*16 */
- int img_height; /* image height BEFORE decimation,
- must be a multiple of VerDcm*8 */
-
- /* --- End of parameters for decimation==0 only --- */
-
- /* JPEG control parameters */
-
- int quality; /* Measure for quality of compressed images.
- Scales linearly with the size of the compressed images.
- Must be beetween 0 and 100, 100 is a compression
- ratio of 1:4 */
-
- int odd_even; /* Which field should come first ??? */
-
- int APPn; /* Number of APP segment to be written, must be 0..15 */
- int APP_len; /* Length of data in JPEG APPn segment */
- char APP_data[60]; /* Data in the JPEG APPn segment. */
-
- int COM_len; /* Length of data in JPEG COM segment */
- char COM_data[60]; /* Data in JPEG COM segment */
-
- unsigned long jpeg_markers; /* Which markers should go into the JPEG output.
- Unless you exactly know what you do, leave them untouched.
- Inluding less markers will make the resulting code
- smaller, but there will be fewer aplications
- which can read it.
- The presence of the APP and COM marker is
- influenced by APP0_len and COM_len ONLY! */
-#define JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
-#define JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
-#define JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
-#define JPEG_MARKER_COM (1<<6) /* Comment segment */
-#define JPEG_MARKER_APP (1<<7) /* App segment, driver will allways use APP0 */
-
- int VFIFO_FB; /* Flag for enabling Video Fifo Feedback.
- If this flag is turned on and JPEG decompressing
- is going to the screen, the decompress process
- is stopped every time the Video Fifo is full.
- This enables a smooth decompress to the screen
- but the video output signal will get scrambled */
-
- /* Misc */
-
- char reserved[312]; /* Makes 512 bytes for this structure */
-};
-
-/*
- Private IOCTL to set up for displaying MJPEG
- */
-#define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOCPRIVATE+0, struct zoran_params)
-#define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOCPRIVATE+1, struct zoran_params)
-#define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOCPRIVATE+2, struct zoran_requestbuffers)
-#define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOCPRIVATE+3, int)
-#define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOCPRIVATE+4, int)
-#define BUZIOC_SYNC _IOR ('v', BASE_VIDIOCPRIVATE+5, struct zoran_sync)
-#define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOCPRIVATE+6, struct zoran_status)
-
-
-#ifdef __KERNEL__
-
-#define BUZ_NUM_STAT_COM 4
-#define BUZ_MASK_STAT_COM 3
-
-#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */
-#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */
-
-#if VIDEO_MAX_FRAME <= 32
-#define V4L_MAX_FRAME 32
-#elif VIDEO_MAX_FRAME <= 64
-#define V4L_MAX_FRAME 64
-#else
-#error "Too many video frame buffers to handle"
-#endif
-#define V4L_MASK_FRAME (V4L_MAX_FRAME - 1)
-
-
-#include "zr36057.h"
-
-enum zoran_codec_mode {
- BUZ_MODE_IDLE, /* nothing going on */
- BUZ_MODE_MOTION_COMPRESS, /* grabbing frames */
- BUZ_MODE_MOTION_DECOMPRESS, /* playing frames */
- BUZ_MODE_STILL_COMPRESS, /* still frame conversion */
- BUZ_MODE_STILL_DECOMPRESS /* still frame conversion */
-};
-
-enum zoran_buffer_state {
- BUZ_STATE_USER, /* buffer is owned by application */
- BUZ_STATE_PEND, /* buffer is queued in pend[] ready to feed to I/O */
- BUZ_STATE_DMA, /* buffer is queued in dma[] for I/O */
- BUZ_STATE_DONE /* buffer is ready to return to application */
-};
-
-struct zoran_gbuffer {
- u32 *frag_tab; /* addresses of frag table */
- u32 frag_tab_bus; /* same value cached to save time in ISR */
- enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */
- struct zoran_sync bs; /* DONE: info to return to application */
-};
-
-struct v4l_gbuffer {
- char *fbuffer; /* virtual address of frame buffer */
- unsigned long fbuffer_phys; /* physical address of frame buffer */
- unsigned long fbuffer_bus; /* bus address of frame buffer */
- enum zoran_buffer_state state; /* state: unused/pending/done */
-};
-
-struct zoran {
- struct video_device video_dev;
- struct i2c_bus i2c;
-
- int initialized; /* flag if zoran has been correctly initalized */
- int user; /* number of current users (0 or 1) */
-
- unsigned short id; /* number of this device */
- char name[32]; /* name of this device */
- struct pci_dev *pci_dev; /* PCI device */
- unsigned char revision; /* revision of zr36057 */
- int board; /* Board type */
-#define BOARD_BUZ 0
-#define BOARD_LML33 1
- unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */
- unsigned char *zr36057_mem; /* pointer to mapped IO memory */
-
- int map_mjpeg_buffers; /* Flag which bufferset will map by next mmap() */
-
- spinlock_t lock; /* Spinlock */
-
- /* Video for Linux parameters */
-
- struct video_picture picture; /* Current picture params */
- struct video_buffer buffer; /* Current buffer params */
- struct video_window window; /* Current window params */
- int buffer_set, window_set; /* Flags if the above structures are set */
- int video_interlace; /* Image on screen is interlaced */
-
- u32 *overlay_mask;
-
- wait_queue_head_t v4l_capq; /* wait here for grab to finish */
-
- int v4l_overlay_active; /* Overlay grab is activated */
- int v4l_memgrab_active; /* Memory grab is activated */
-
- int v4l_grab_frame; /* Frame number being currently grabbed */
-#define NO_GRAB_ACTIVE (-1)
- int v4l_grab_seq; /* Number of frames grabbed */
- int gwidth; /* Width of current memory capture */
- int gheight; /* Height of current memory capture */
- int gformat; /* Format of ... */
- int gbpl; /* byte per line of ... */
-
- /* V4L grab queue of frames pending */
-
- unsigned v4l_pend_head;
- unsigned v4l_pend_tail;
- int v4l_pend[V4L_MAX_FRAME];
-
- struct v4l_gbuffer v4l_gbuf[VIDEO_MAX_FRAME]; /* V4L buffers' info */
-
- /* Buz MJPEG parameters */
-
- unsigned long jpg_nbufs; /* Number of buffers */
- unsigned long jpg_bufsize; /* Size of mjpeg buffers in bytes */
- int jpg_buffers_allocated; /* Flag if buffers are allocated */
- int need_contiguous; /* Flag if contiguous buffers are needed */
-
- enum zoran_codec_mode codec_mode; /* status of codec */
- struct zoran_params params; /* structure with a lot of things to play with */
-
- wait_queue_head_t jpg_capq; /* wait here for grab to finish */
-
- /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
- /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
- /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
- unsigned long jpg_que_head; /* Index where to put next buffer which is queued */
- unsigned long jpg_dma_head; /* Index of next buffer which goes into stat_com */
- unsigned long jpg_dma_tail; /* Index of last buffer in stat_com */
- unsigned long jpg_que_tail; /* Index of last buffer in queue */
- unsigned long jpg_seq_num; /* count of frames since grab/play started */
-
- /* zr36057's code buffer table */
- u32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
-
- /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */
- int jpg_pend[BUZ_MAX_FRAME];
-
- /* array indexed by frame number */
- struct zoran_gbuffer jpg_gbuf[BUZ_MAX_FRAME]; /* MJPEG buffers' info */
-};
-
-#endif
-
-/*The following should be done in more portable way. It depends on define
- of _ALPHA_BUZ in the Makefile. */
-
-#ifdef _ALPHA_BUZ
-#define btwrite(dat,adr) writel((dat),(char *) (zr->zr36057_adr+(adr)))
-#define btread(adr) readl(zr->zr36057_adr+(adr))
-#else
-#define btwrite(dat,adr) writel((dat), (char *) (zr->zr36057_mem+(adr)))
-#define btread(adr) readl(zr->zr36057_mem+(adr))
-#endif
-
-#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
-#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
-#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-
-#define I2C_TSA5522 0xc2
-#define I2C_TDA9850 0xb6
-#define I2C_HAUPEE 0xa0
-#define I2C_STBEE 0xae
-#define I2C_SAA7111 0x48
-#define I2C_SAA7185 0x88
-
-#define TDA9850_CON1 0x04
-#define TDA9850_CON2 0x05
-#define TDA9850_CON3 0x06
-#define TDA9850_CON4 0x07
-#define TDA9850_ALI1 0x08
-#define TDA9850_ALI2 0x09
-#define TDA9850_ALI3 0x0a
-
-#endif
diff --git a/drivers/char/bw-qcam.c b/drivers/char/bw-qcam.c
deleted file mode 100644
index 17f7d25dc..000000000
--- a/drivers/char/bw-qcam.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/*
- * QuickCam Driver For Video4Linux.
- *
- * This version only works as a module.
- *
- * Video4Linux conversion work by Alan Cox.
- * Parport compatibility by Phil Blundell.
- * Busy loop avoidance by Mark Cooke.
- *
- * Module parameters:
- *
- * maxpoll=<1 - 5000>
- *
- * When polling the QuickCam for a response, busy-wait for a
- * maximum of this many loops. The default of 250 gives little
- * impact on interactive response.
- *
- * NOTE: If this parameter is set too high, the processor
- * will busy wait until this loop times out, and then
- * slowly poll for a further 5 seconds before failing
- * the transaction. You have been warned.
- *
- * yieldlines=<1 - 250>
- *
- * When acquiring a frame from the camera, the data gathering
- * loop will yield back to the scheduler after completing
- * this many lines. The default of 4 provides a trade-off
- * between increased frame acquisition time and impact on
- * interactive response.
- */
-
-/* qcam-lib.c -- Library for programming with the Connectix QuickCam.
- * See the included documentation for usage instructions and details
- * of the protocol involved. */
-
-
-/* Version 0.5, August 4, 1996 */
-/* Version 0.7, August 27, 1996 */
-/* Version 0.9, November 17, 1996 */
-
-
-/******************************************************************
-
-Copyright (C) 1996 by Scott Laird
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-******************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/parport.h>
-#include <linux/sched.h>
-#include <linux/version.h>
-#include <linux/videodev.h>
-#include <asm/semaphore.h>
-#include <asm/uaccess.h>
-
-#include "bw-qcam.h"
-
-static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */
-static unsigned int yieldlines=4; /* Yield after this many during capture */
-
-#if LINUX_VERSION_CODE >= 0x020117
-MODULE_PARM(maxpoll,"i");
-MODULE_PARM(yieldlines,"i");
-#endif
-
-extern __inline__ int read_lpstatus(struct qcam_device *q)
-{
- return parport_read_status(q->pport);
-}
-
-extern __inline__ int read_lpcontrol(struct qcam_device *q)
-{
- return parport_read_control(q->pport);
-}
-
-extern __inline__ int read_lpdata(struct qcam_device *q)
-{
- return parport_read_data(q->pport);
-}
-
-extern __inline__ void write_lpdata(struct qcam_device *q, int d)
-{
- parport_write_data(q->pport, d);
-}
-
-extern __inline__ void write_lpcontrol(struct qcam_device *q, int d)
-{
- parport_write_control(q->pport, d);
-}
-
-static int qc_waithand(struct qcam_device *q, int val);
-static int qc_command(struct qcam_device *q, int command);
-static int qc_readparam(struct qcam_device *q);
-static int qc_setscanmode(struct qcam_device *q);
-static int qc_readbytes(struct qcam_device *q, char buffer[]);
-
-static struct video_device qcam_template;
-
-static int qc_calibrate(struct qcam_device *q)
-{
- /*
- * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
- * The white balance is an individiual value for each
- * quickcam.
- */
-
- int value;
- int count = 0;
-
- qc_command(q, 27); /* AutoAdjustOffset */
- qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
-
- /* GetOffset (33) will read 255 until autocalibration */
- /* is finished. After that, a value of 1-254 will be */
- /* returned. */
-
- do {
- qc_command(q, 33);
- value = qc_readparam(q);
- mdelay(1);
- schedule();
- count++;
- } while (value == 0xff && count<2048);
-
- q->whitebal = value;
- return value;
-}
-
-/* Initialize the QuickCam driver control structure. This is where
- * defaults are set for people who don't have a config file.*/
-
-static struct qcam_device *qcam_init(struct parport *port)
-{
- struct qcam_device *q;
-
- q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
- if(q==NULL)
- return NULL;
-
- q->pport = port;
- q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
- NULL, 0, NULL);
- if (q->pdev == NULL)
- {
- printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
- port->name);
- kfree(q);
- return NULL;
- }
-
- memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
-
- init_MUTEX(&q->lock);
-
- q->port_mode = (QC_ANY | QC_NOTSET);
- q->width = 320;
- q->height = 240;
- q->bpp = 4;
- q->transfer_scale = 2;
- q->contrast = 192;
- q->brightness = 180;
- q->whitebal = 105;
- q->top = 1;
- q->left = 14;
- q->mode = -1;
- q->status = QC_PARAM_CHANGE;
- return q;
-}
-
-
-/* qc_command is probably a bit of a misnomer -- it's used to send
- * bytes *to* the camera. Generally, these bytes are either commands
- * or arguments to commands, so the name fits, but it still bugs me a
- * bit. See the documentation for a list of commands. */
-
-static int qc_command(struct qcam_device *q, int command)
-{
- int n1, n2;
- int cmd;
-
- write_lpdata(q, command);
- write_lpcontrol(q, 6);
-
- n1 = qc_waithand(q, 1);
-
- write_lpcontrol(q, 0xe);
- n2 = qc_waithand(q, 0);
-
- cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
- return cmd;
-}
-
-static int qc_readparam(struct qcam_device *q)
-{
- int n1, n2;
- int cmd;
-
- write_lpcontrol(q, 6);
- n1 = qc_waithand(q, 1);
-
- write_lpcontrol(q, 0xe);
- n2 = qc_waithand(q, 0);
-
- cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
- return cmd;
-}
-
-/* qc_waithand busy-waits for a handshake signal from the QuickCam.
- * Almost all communication with the camera requires handshaking. */
-
-static int qc_waithand(struct qcam_device *q, int val)
-{
- int status;
- int runs=0;
-
- if (val)
- {
- while (!((status = read_lpstatus(q)) & 8))
- {
- /* 1000 is enough spins on the I/O for all normal
- cases, at that point we start to poll slowly
- until the camera wakes up. However, we are
- busy blocked until the camera responds, so
- setting it lower is much better for interactive
- response. */
-
- if(runs++>maxpoll)
- {
- current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/200);
- }
- if(runs>(maxpoll+1000)) /* 5 seconds */
- return -1;
- }
- }
- else
- {
- while (((status = read_lpstatus(q)) & 8))
- {
- /* 1000 is enough spins on the I/O for all normal
- cases, at that point we start to poll slowly
- until the camera wakes up. However, we are
- busy blocked until the camera responds, so
- setting it lower is much better for interactive
- response. */
-
- if(runs++>maxpoll)
- {
- current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/200);
- }
- if(runs++>(maxpoll+1000)) /* 5 seconds */
- return -1;
- }
- }
-
- return status;
-}
-
-/* Waithand2 is used when the qcam is in bidirectional mode, and the
- * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
- * (bit 3 of status register). It also returns the last value read,
- * since this data is useful. */
-
-static unsigned int qc_waithand2(struct qcam_device *q, int val)
-{
- unsigned int status;
- int runs=0;
-
- do
- {
- status = read_lpdata(q);
- /* 1000 is enough spins on the I/O for all normal
- cases, at that point we start to poll slowly
- until the camera wakes up. However, we are
- busy blocked until the camera responds, so
- setting it lower is much better for interactive
- response. */
-
- if(runs++>maxpoll)
- {
- current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/200);
- }
- if(runs++>(maxpoll+1000)) /* 5 seconds */
- return 0;
- }
- while ((status & 1) != val);
-
- return status;
-}
-
-
-/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
- the status register at 5-10 Hz. This is only used in the autoprobe
- code. Be aware that this isn't the way Connectix detects the
- camera (they send a reset and try to handshake), but this should be
- almost completely safe, while their method screws up my printer if
- I plug it in before the camera. */
-
-static int qc_detect(struct qcam_device *q)
-{
- int reg, lastreg;
- int count = 0;
- int i;
-
- lastreg = reg = read_lpstatus(q) & 0xf0;
-
- for (i = 0; i < 500; i++)
- {
- reg = read_lpstatus(q) & 0xf0;
- if (reg != lastreg)
- count++;
- lastreg = reg;
- mdelay(2);
- }
-
-
-#if 0
- /* Force camera detection during testing. Sometimes the camera
- won't be flashing these bits. Possibly unloading the module
- in the middle of a grab? Or some timeout condition?
- I've seen this parameter as low as 19 on my 450Mhz box - mpc */
- printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
- return 1;
-#endif
-
- /* Be (even more) liberal in what you accept... */
-
-/* if (count > 30 && count < 200) */
- if (count > 20 && count < 300)
- return 1; /* found */
- else
- return 0; /* not found */
-}
-
-
-/* Reset the QuickCam. This uses the same sequence the Windows
- * QuickPic program uses. Someone with a bi-directional port should
- * check that bi-directional mode is detected right, and then
- * implement bi-directional mode in qc_readbyte(). */
-
-static void qc_reset(struct qcam_device *q)
-{
- switch (q->port_mode & QC_FORCE_MASK)
- {
- case QC_FORCE_UNIDIR:
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
- break;
-
- case QC_FORCE_BIDIR:
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
- break;
-
- case QC_ANY:
- write_lpcontrol(q, 0x20);
- write_lpdata(q, 0x75);
-
- if (read_lpdata(q) != 0x75) {
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
- } else {
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
- }
- break;
- }
-
- write_lpcontrol(q, 0xb);
- udelay(250);
- write_lpcontrol(q, 0xe);
- qc_setscanmode(q); /* in case port_mode changed */
-}
-
-
-/* Decide which scan mode to use. There's no real requirement that
- * the scanmode match the resolution in q->height and q-> width -- the
- * camera takes the picture at the resolution specified in the
- * "scanmode" and then returns the image at the resolution specified
- * with the resolution commands. If the scan is bigger than the
- * requested resolution, the upper-left hand corner of the scan is
- * returned. If the scan is smaller, then the rest of the image
- * returned contains garbage. */
-
-static int qc_setscanmode(struct qcam_device *q)
-{
- int old_mode = q->mode;
-
- switch (q->transfer_scale)
- {
- case 1:
- q->mode = 0;
- break;
- case 2:
- q->mode = 4;
- break;
- case 4:
- q->mode = 8;
- break;
- }
-
- switch (q->bpp)
- {
- case 4:
- break;
- case 6:
- q->mode += 2;
- break;
- }
-
- switch (q->port_mode & QC_MODE_MASK)
- {
- case QC_BIDIR:
- q->mode += 1;
- break;
- case QC_NOTSET:
- case QC_UNIDIR:
- break;
- }
-
- if (q->mode != old_mode)
- q->status |= QC_PARAM_CHANGE;
-
- return 0;
-}
-
-
-/* Reset the QuickCam and program for brightness, contrast,
- * white-balance, and resolution. */
-
-void qc_set(struct qcam_device *q)
-{
- int val;
- int val2;
-
- qc_reset(q);
-
- /* Set the brightness. Yes, this is repetitive, but it works.
- * Shorter versions seem to fail subtly. Feel free to try :-). */
- /* I think the problem was in qc_command, not here -- bls */
-
- qc_command(q, 0xb);
- qc_command(q, q->brightness);
-
- val = q->height / q->transfer_scale;
- qc_command(q, 0x11);
- qc_command(q, val);
- if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
- /* The normal "transfers per line" calculation doesn't seem to work
- as expected here (and yet it works fine in qc_scan). No idea
- why this case is the odd man out. Fortunately, Laird's original
- working version gives me a good way to guess at working values.
- -- bls */
- val = q->width;
- val2 = q->transfer_scale * 4;
- } else {
- val = q->width * q->bpp;
- val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
- q->transfer_scale;
- }
- val = (val + val2 - 1) / val2;
- qc_command(q, 0x13);
- qc_command(q, val);
-
- /* Setting top and left -- bls */
- qc_command(q, 0xd);
- qc_command(q, q->top);
- qc_command(q, 0xf);
- qc_command(q, q->left / 2);
-
- qc_command(q, 0x19);
- qc_command(q, q->contrast);
- qc_command(q, 0x1f);
- qc_command(q, q->whitebal);
-
- /* Clear flag that we must update the grabbing parameters on the camera
- before we grab the next frame */
- q->status &= (~QC_PARAM_CHANGE);
-}
-
-/* Qc_readbytes reads some bytes from the QC and puts them in
- the supplied buffer. It returns the number of bytes read,
- or -1 on error. */
-
-extern __inline__ int qc_readbytes(struct qcam_device *q, char buffer[])
-{
- int ret=1;
- unsigned int hi, lo;
- unsigned int hi2, lo2;
- static int state = 0;
-
- if (buffer == NULL)
- {
- state = 0;
- return 0;
- }
-
- switch (q->port_mode & QC_MODE_MASK)
- {
- case QC_BIDIR: /* Bi-directional Port */
- write_lpcontrol(q, 0x26);
- lo = (qc_waithand2(q, 1) >> 1);
- hi = (read_lpstatus(q) >> 3) & 0x1f;
- write_lpcontrol(q, 0x2e);
- lo2 = (qc_waithand2(q, 0) >> 1);
- hi2 = (read_lpstatus(q) >> 3) & 0x1f;
- switch (q->bpp)
- {
- case 4:
- buffer[0] = lo & 0xf;
- buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
- buffer[2] = (hi & 0x1e) >> 1;
- buffer[3] = lo2 & 0xf;
- buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
- buffer[5] = (hi2 & 0x1e) >> 1;
- ret = 6;
- break;
- case 6:
- buffer[0] = lo & 0x3f;
- buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
- buffer[2] = lo2 & 0x3f;
- buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
- ret = 4;
- break;
- }
- break;
-
- case QC_UNIDIR: /* Unidirectional Port */
- write_lpcontrol(q, 6);
- lo = (qc_waithand(q, 1) & 0xf0) >> 4;
- write_lpcontrol(q, 0xe);
- hi = (qc_waithand(q, 0) & 0xf0) >> 4;
-
- switch (q->bpp)
- {
- case 4:
- buffer[0] = lo;
- buffer[1] = hi;
- ret = 2;
- break;
- case 6:
- switch (state)
- {
- case 0:
- buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
- q->saved_bits = (hi & 3) << 4;
- state = 1;
- ret = 1;
- break;
- case 1:
- buffer[0] = lo | q->saved_bits;
- q->saved_bits = hi << 2;
- state = 2;
- ret = 1;
- break;
- case 2:
- buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
- buffer[1] = ((lo & 3) << 4) | hi;
- state = 0;
- ret = 2;
- break;
- }
- break;
- }
- break;
- }
- return ret;
-}
-
-/* requests a scan from the camera. It sends the correct instructions
- * to the camera and then reads back the correct number of bytes. In
- * previous versions of this routine the return structure contained
- * the raw output from the camera, and there was a 'qc_convertscan'
- * function that converted that to a useful format. In version 0.3 I
- * rolled qc_convertscan into qc_scan and now I only return the
- * converted scan. The format is just an one-dimensional array of
- * characters, one for each pixel, with 0=black up to n=white, where
- * n=2^(bit depth)-1. Ask me for more details if you don't understand
- * this. */
-
-long qc_capture(struct qcam_device * q, char *buf, unsigned long len)
-{
- int i, j, k, yield;
- int bytes;
- int linestotrans, transperline;
- int divisor;
- int pixels_per_line;
- int pixels_read = 0;
- int got=0;
- char buffer[6];
- int shift=8-q->bpp;
- char invert;
-
- if (q->mode == -1)
- return -ENXIO;
-
- qc_command(q, 0x7);
- qc_command(q, q->mode);
-
- if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
- {
- write_lpcontrol(q, 0x2e); /* turn port around */
- write_lpcontrol(q, 0x26);
- (void) qc_waithand(q, 1);
- write_lpcontrol(q, 0x2e);
- (void) qc_waithand(q, 0);
- }
-
- /* strange -- should be 15:63 below, but 4bpp is odd */
- invert = (q->bpp == 4) ? 16 : 63;
-
- linestotrans = q->height / q->transfer_scale;
- pixels_per_line = q->width / q->transfer_scale;
- transperline = q->width * q->bpp;
- divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
- q->transfer_scale;
- transperline = (transperline + divisor - 1) / divisor;
-
- for (i = 0, yield = yieldlines; i < linestotrans; i++)
- {
- for (pixels_read = j = 0; j < transperline; j++)
- {
- bytes = qc_readbytes(q, buffer);
- for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
- {
- int o;
- if (buffer[k] == 0 && invert == 16)
- {
- /* 4bpp is odd (again) -- inverter is 16, not 15, but output
- must be 0-15 -- bls */
- buffer[k] = 16;
- }
- o=i*pixels_per_line + pixels_read + k;
- if(o<len)
- {
- got++;
- put_user((invert - buffer[k])<<shift, buf+o);
- }
- }
- pixels_read += bytes;
- }
- (void) qc_readbytes(q, 0); /* reset state machine */
-
- /* Grabbing an entire frame from the quickcam is a lengthy
- process. We don't (usually) want to busy-block the
- processor for the entire frame. yieldlines is a module
- parameter. If we yield every line, the minimum frame
- time will be 240 / 200 = 1.2 seconds. The compile-time
- default is to yield every 4 lines. */
- if (i >= yield) {
- current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/200);
- yield = i + yieldlines;
- }
- }
-
- if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
- {
- write_lpcontrol(q, 2);
- write_lpcontrol(q, 6);
- udelay(3);
- write_lpcontrol(q, 0xe);
- }
- if(got<len)
- return got;
- return len;
-}
-
-/*
- * Video4linux interfacing
- */
-
-static int qcam_open(struct video_device *dev, int flags)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void qcam_close(struct video_device *dev)
-{
- MOD_DEC_USE_COUNT;
-}
-
-static int qcam_init_done(struct video_device *dev)
-{
- return 0;
-}
-
-static long qcam_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
-{
- return -EINVAL;
-}
-
-static int qcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct qcam_device *qcam=(struct qcam_device *)dev;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability b;
- strcpy(b.name, "Quickcam");
- b.type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
- b.channels = 1;
- b.audios = 0;
- b.maxwidth = 320;
- b.maxheight = 240;
- b.minwidth = 80;
- b.minheight = 60;
- if(copy_to_user(arg, &b,sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGCHAN:
- {
- struct video_channel v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.channel!=0)
- return -EINVAL;
- v.flags=0;
- v.tuners=0;
- /* Good question.. its composite or SVHS so.. */
- v.type = VIDEO_TYPE_CAMERA;
- strcpy(v.name, "Camera");
- if(copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSCHAN:
- {
- int v;
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- if(v!=0)
- return -EINVAL;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner)
- return -EINVAL;
- strcpy(v.name, "Format");
- v.rangelow=0;
- v.rangehigh=0;
- v.flags= 0;
- v.mode = VIDEO_MODE_AUTO;
- if(copy_to_user(arg,&v,sizeof(v))!=0)
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner)
- return -EINVAL;
- if(v.mode!=VIDEO_MODE_AUTO)
- return -EINVAL;
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture p;
- p.colour=0x8000;
- p.hue=0x8000;
- p.brightness=qcam->brightness<<8;
- p.contrast=qcam->contrast<<8;
- p.whiteness=qcam->whitebal<<8;
- p.depth=qcam->bpp;
- p.palette=VIDEO_PALETTE_GREY;
- if(copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture p;
- if(copy_from_user(&p, arg, sizeof(p)))
- return -EFAULT;
- if(p.palette!=VIDEO_PALETTE_GREY)
- return -EINVAL;
- if(p.depth!=4 && p.depth!=6)
- return -EINVAL;
-
- /*
- * Now load the camera.
- */
-
- qcam->brightness = p.brightness>>8;
- qcam->contrast = p.contrast>>8;
- qcam->whitebal = p.whiteness>>8;
- qcam->bpp = p.depth;
-
- down(&qcam->lock);
- qc_setscanmode(qcam);
- up(&qcam->lock);
- qcam->status |= QC_PARAM_CHANGE;
-
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- if(copy_from_user(&vw, arg,sizeof(vw)))
- return -EFAULT;
- if(vw.flags)
- return -EINVAL;
- if(vw.clipcount)
- return -EINVAL;
- if(vw.height<60||vw.height>240)
- return -EINVAL;
- if(vw.width<80||vw.width>320)
- return -EINVAL;
-
- qcam->width = 320;
- qcam->height = 240;
- qcam->transfer_scale = 4;
-
- if(vw.width>=160 && vw.height>=120)
- {
- qcam->transfer_scale = 2;
- }
- if(vw.width>=320 && vw.height>=240)
- {
- qcam->width = 320;
- qcam->height = 240;
- qcam->transfer_scale = 1;
- }
- down(&qcam->lock);
- qc_setscanmode(qcam);
- up(&qcam->lock);
-
- /* We must update the camera before we grab. We could
- just have changed the grab size */
- qcam->status |= QC_PARAM_CHANGE;
-
- /* Ok we figured out what to use from our wide choice */
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
- vw.x=0;
- vw.y=0;
- vw.width=qcam->width/qcam->transfer_scale;
- vw.height=qcam->height/qcam->transfer_scale;
- vw.chromakey=0;
- vw.flags=0;
- if(copy_to_user(arg, &vw, sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- return -EINVAL;
- case VIDIOCGFBUF:
- return -EINVAL;
- case VIDIOCSFBUF:
- return -EINVAL;
- case VIDIOCKEY:
- return 0;
- case VIDIOCGFREQ:
- return -EINVAL;
- case VIDIOCSFREQ:
- return -EINVAL;
- case VIDIOCGAUDIO:
- return -EINVAL;
- case VIDIOCSAUDIO:
- return -EINVAL;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static long qcam_read(struct video_device *v, char *buf, unsigned long count, int noblock)
-{
- struct qcam_device *qcam=(struct qcam_device *)v;
- int len;
- parport_claim_or_block(qcam->pdev);
-
- down(&qcam->lock);
-
- qc_reset(qcam);
-
- /* Update the camera parameters if we need to */
- if (qcam->status & QC_PARAM_CHANGE)
- qc_set(qcam);
-
- len=qc_capture(qcam, buf,count);
-
- up(&qcam->lock);
-
- parport_release(qcam->pdev);
- return len;
-}
-
-static struct video_device qcam_template=
-{
- "Connectix Quickcam",
- VID_TYPE_CAPTURE,
- VID_HARDWARE_QCAM_BW,
- qcam_open,
- qcam_close,
- qcam_read,
- qcam_write,
- NULL,
- qcam_ioctl,
- NULL,
- qcam_init_done,
- NULL,
- 0,
- 0
-};
-
-#define MAX_CAMS 4
-static struct qcam_device *qcams[MAX_CAMS];
-static unsigned int num_cams = 0;
-
-int init_bwqcam(struct parport *port)
-{
- struct qcam_device *qcam;
-
- if (num_cams == MAX_CAMS)
- {
- printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
- return -ENOSPC;
- }
-
- qcam=qcam_init(port);
- if(qcam==NULL)
- return -ENODEV;
-
- parport_claim_or_block(qcam->pdev);
-
- qc_reset(qcam);
-
- if(qc_detect(qcam)==0)
- {
- parport_release(qcam->pdev);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
- qc_calibrate(qcam);
-
- parport_release(qcam->pdev);
-
- printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
-
- if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1)
- {
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
-
- qcams[num_cams++] = qcam;
-
- return 0;
-}
-
-void close_bwqcam(struct qcam_device *qcam)
-{
- video_unregister_device(&qcam->vdev);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
-}
-
-/* The parport parameter controls which parports will be scanned.
- * Scanning all parports causes some printers to print a garbage page.
- * -- March 14, 1999 Billy Donahue <billy@escape.com> */
-#ifdef MODULE
-static char *parport[MAX_CAMS] = { NULL, };
-MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
-#endif
-
-#ifdef MODULE
-int init_module(void)
-{
- struct parport *port;
- int n;
- if(parport[0] && strncmp(parport[0], "auto", 4)){
- /* user gave parport parameters */
- for(n=0; parport[n] && n<MAX_CAMS; n++){
- char *ep;
- unsigned long r;
- r = simple_strtoul(parport[n], &ep, 0);
- if(ep == parport[n]){
- printk(KERN_ERR
- "bw-qcam: bad port specifier \"%s\"\n",
- parport[n]);
- continue;
- }
- for (port=parport_enumerate(); port; port=port->next){
- if(r!=port->number)
- continue;
- init_bwqcam(port);
- break;
- }
- }
- return (num_cams)?0:-ENODEV;
- }
- /* no parameter or "auto" */
- for (port = parport_enumerate(); port; port=port->next)
- init_bwqcam(port);
-
- /* Do some sanity checks on the module parameters. */
- if (maxpoll > 5000) {
- printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
- maxpoll = 5000;
- }
-
- if (yieldlines < 1) {
- printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
- yieldlines = 1;
- }
-
- return (num_cams)?0:-ENODEV;
-}
-
-void cleanup_module(void)
-{
- unsigned int i;
- for (i = 0; i < num_cams; i++)
- close_bwqcam(qcams[i]);
-}
-#else
-int __init init_bw_qcams(struct video_init *unused)
-{
- struct parport *port;
-
- for (port = parport_enumerate(); port; port=port->next)
- init_bwqcam(port);
- return 0;
-}
-#endif
diff --git a/drivers/char/bw-qcam.h b/drivers/char/bw-qcam.h
deleted file mode 100644
index 723e8ad9e..000000000
--- a/drivers/char/bw-qcam.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Video4Linux bw-qcam driver
- *
- * Derived from code..
- */
-
-/******************************************************************
-
-Copyright (C) 1996 by Scott Laird
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-******************************************************************/
-
-/* One from column A... */
-#define QC_NOTSET 0
-#define QC_UNIDIR 1
-#define QC_BIDIR 2
-#define QC_SERIAL 3
-
-/* ... and one from column B */
-#define QC_ANY 0x00
-#define QC_FORCE_UNIDIR 0x10
-#define QC_FORCE_BIDIR 0x20
-#define QC_FORCE_SERIAL 0x30
-/* in the port_mode member */
-
-#define QC_MODE_MASK 0x07
-#define QC_FORCE_MASK 0x70
-
-#define MAX_HEIGHT 243
-#define MAX_WIDTH 336
-
-/* Bit fields for status flags */
-#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
-
-struct qcam_device {
- struct video_device vdev;
- struct pardevice *pdev;
- struct parport *pport;
- struct semaphore lock;
- int width, height;
- int bpp;
- int mode;
- int contrast, brightness, whitebal;
- int port_mode;
- int transfer_scale;
- int top, left;
- int status;
- unsigned int saved_bits;
-};
diff --git a/drivers/char/c-qcam.c b/drivers/char/c-qcam.c
deleted file mode 100644
index fa96cc925..000000000
--- a/drivers/char/c-qcam.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Video4Linux Colour QuickCam driver
- * Copyright 1997-2000 Philip Blundell <philb@gnu.org>
- *
- * Module parameters:
- *
- * parport=auto -- probe all parports (default)
- * parport=0 -- parport0 becomes qcam1
- * parport=2,0,1 -- parports 2,0,1 are tried in that order
- *
- * probe=0 -- do no probing, assume camera is present
- * probe=1 -- use IEEE-1284 autoprobe data only (default)
- * probe=2 -- probe aggressively for cameras
- *
- * force_rgb=1 -- force data format to RGB (default is BGR)
- *
- * The parport parameter controls which parports will be scanned.
- * Scanning all parports causes some printers to print a garbage page.
- * -- March 14, 1999 Billy Donahue <billy@escape.com>
- *
- * Fixed data format to BGR, added force_rgb parameter. Added missing
- * parport_unregister_driver() on module removal.
- * -- May 28, 2000 Claudio Matsuoka <claudio@conectiva.com>
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/parport.h>
-#include <linux/sched.h>
-#include <linux/version.h>
-#include <linux/videodev.h>
-#include <asm/semaphore.h>
-#include <asm/uaccess.h>
-
-struct qcam_device {
- struct video_device vdev;
- struct pardevice *pdev;
- struct parport *pport;
- int width, height;
- int ccd_width, ccd_height;
- int mode;
- int contrast, brightness, whitebal;
- int top, left;
- unsigned int bidirectional;
- struct semaphore lock;
-};
-
-/* cameras maximum */
-#define MAX_CAMS 4
-
-/* The three possible QuickCam modes */
-#define QC_MILLIONS 0x18
-#define QC_BILLIONS 0x10
-#define QC_THOUSANDS 0x08 /* with VIDEC compression (not supported) */
-
-/* The three possible decimations */
-#define QC_DECIMATION_1 0
-#define QC_DECIMATION_2 2
-#define QC_DECIMATION_4 4
-
-#define BANNER "Colour QuickCam for Video4Linux v0.05"
-
-static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
-static int probe = 2;
-static int force_rgb = 0;
-
-static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
-{
- /* note: the QC specs refer to the PCAck pin by voltage, not
- software level. PC ports have builtin inverters. */
- parport_frob_control(qcam->pport, 8, i?8:0);
-}
-
-static inline unsigned int qcam_ready1(struct qcam_device *qcam)
-{
- return (parport_read_status(qcam->pport) & 0x8)?1:0;
-}
-
-static inline unsigned int qcam_ready2(struct qcam_device *qcam)
-{
- return (parport_read_data(qcam->pport) & 0x1)?1:0;
-}
-
-static unsigned int qcam_await_ready1(struct qcam_device *qcam,
- int value)
-{
- unsigned long oldjiffies = jiffies;
- unsigned int i;
-
- for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
- if (qcam_ready1(qcam) == value)
- return 0;
-
- /* If the camera didn't respond within 1/25 second, poll slowly
- for a while. */
- for (i = 0; i < 50; i++)
- {
- if (qcam_ready1(qcam) == value)
- return 0;
- current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
- }
-
- /* Probably somebody pulled the plug out. Not much we can do. */
- printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value,
- parport_read_status(qcam->pport),
- parport_read_control(qcam->pport));
- return 1;
-}
-
-static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
-{
- unsigned long oldjiffies = jiffies;
- unsigned int i;
-
- for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
- if (qcam_ready2(qcam) == value)
- return 0;
-
- /* If the camera didn't respond within 1/25 second, poll slowly
- for a while. */
- for (i = 0; i < 50; i++)
- {
- if (qcam_ready2(qcam) == value)
- return 0;
- current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
- }
-
- /* Probably somebody pulled the plug out. Not much we can do. */
- printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value,
- parport_read_status(qcam->pport),
- parport_read_control(qcam->pport),
- parport_read_data(qcam->pport));
- return 1;
-}
-
-static int qcam_read_data(struct qcam_device *qcam)
-{
- unsigned int idata;
- qcam_set_ack(qcam, 0);
- if (qcam_await_ready1(qcam, 1)) return -1;
- idata = parport_read_status(qcam->pport) & 0xf0;
- qcam_set_ack(qcam, 1);
- if (qcam_await_ready1(qcam, 0)) return -1;
- idata |= (parport_read_status(qcam->pport) >> 4);
- return idata;
-}
-
-static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
-{
- unsigned int idata;
- parport_write_data(qcam->pport, data);
- idata = qcam_read_data(qcam);
- if (data != idata)
- {
- printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
- idata);
- return 1;
- }
- return 0;
-}
-
-static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data)
-{
- if (qcam_write_data(qcam, cmd))
- return -1;
- if (qcam_write_data(qcam, data))
- return -1;
- return 0;
-}
-
-static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd)
-{
- if (qcam_write_data(qcam, cmd))
- return -1;
- return qcam_read_data(qcam);
-}
-
-static int qc_detect(struct qcam_device *qcam)
-{
- unsigned int stat, ostat, i, count = 0;
-
- /* The probe routine below is not very reliable. The IEEE-1284
- probe takes precedence. */
- /* XXX Currently parport provides no way to distinguish between
- "the IEEE probe was not done" and "the probe was done, but
- no device was found". Fix this one day. */
- if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
- && qcam->pport->probe_info[0].model
- && !strcmp(qcam->pdev->port->probe_info[0].model,
- "Color QuickCam 2.0")) {
- printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
- return 1;
- }
-
- if (probe < 2)
- return 0;
-
- parport_write_control(qcam->pport, 0xc);
-
- /* look for a heartbeat */
- ostat = stat = parport_read_status(qcam->pport);
- for (i=0; i<250; i++)
- {
- mdelay(1);
- stat = parport_read_status(qcam->pport);
- if (ostat != stat)
- {
- if (++count >= 3) return 1;
- ostat = stat;
- }
- }
-
- /* Reset the camera and try again */
- parport_write_control(qcam->pport, 0xc);
- parport_write_control(qcam->pport, 0x8);
- mdelay(1);
- parport_write_control(qcam->pport, 0xc);
- mdelay(1);
- count = 0;
-
- ostat = stat = parport_read_status(qcam->pport);
- for (i=0; i<250; i++)
- {
- mdelay(1);
- stat = parport_read_status(qcam->pport);
- if (ostat != stat)
- {
- if (++count >= 3) return 1;
- ostat = stat;
- }
- }
-
- /* no (or flatline) camera, give up */
- return 0;
-}
-
-static void qc_reset(struct qcam_device *qcam)
-{
- parport_write_control(qcam->pport, 0xc);
- parport_write_control(qcam->pport, 0x8);
- mdelay(1);
- parport_write_control(qcam->pport, 0xc);
- mdelay(1);
-}
-
-/* Reset the QuickCam and program for brightness, contrast,
- * white-balance, and resolution. */
-
-static void qc_setup(struct qcam_device *q)
-{
- qc_reset(q);
-
- /* Set the brightness. */
- qcam_set(q, 11, q->brightness);
-
- /* Set the height and width. These refer to the actual
- CCD area *before* applying the selected decimation. */
- qcam_set(q, 17, q->ccd_height);
- qcam_set(q, 19, q->ccd_width / 2);
-
- /* Set top and left. */
- qcam_set(q, 0xd, q->top);
- qcam_set(q, 0xf, q->left);
-
- /* Set contrast and white balance. */
- qcam_set(q, 0x19, q->contrast);
- qcam_set(q, 0x1f, q->whitebal);
-
- /* Set the speed. */
- qcam_set(q, 45, 2);
-}
-
-/* Read some bytes from the camera and put them in the buffer.
- nbytes should be a multiple of 3, because bidirectional mode gives
- us three bytes at a time. */
-
-static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
-{
- unsigned int bytes = 0;
-
- qcam_set_ack(q, 0);
- if (q->bidirectional)
- {
- /* It's a bidirectional port */
- while (bytes < nbytes)
- {
- unsigned int lo1, hi1, lo2, hi2;
- unsigned char r, g, b;
-
- if (qcam_await_ready2(q, 1)) return bytes;
- lo1 = parport_read_data(q->pport) >> 1;
- hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
- qcam_set_ack(q, 1);
- if (qcam_await_ready2(q, 0)) return bytes;
- lo2 = parport_read_data(q->pport) >> 1;
- hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
- qcam_set_ack(q, 0);
- r = (lo1 | ((hi1 & 1)<<7));
- g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
- b = (lo2 | ((hi2 & 1)<<7));
- if (force_rgb) {
- buf[bytes++] = r;
- buf[bytes++] = g;
- buf[bytes++] = b;
- } else {
- buf[bytes++] = b;
- buf[bytes++] = g;
- buf[bytes++] = r;
- }
- }
- }
- else
- {
- /* It's a unidirectional port */
- int i = 0, n = bytes;
- unsigned char rgb[3];
-
- while (bytes < nbytes)
- {
- unsigned int hi, lo;
-
- if (qcam_await_ready1(q, 1)) return bytes;
- hi = (parport_read_status(q->pport) & 0xf0);
- qcam_set_ack(q, 1);
- if (qcam_await_ready1(q, 0)) return bytes;
- lo = (parport_read_status(q->pport) & 0xf0);
- qcam_set_ack(q, 0);
- /* flip some bits */
- rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
- if (i >= 2) {
-get_fragment:
- if (force_rgb) {
- buf[n++] = rgb[0];
- buf[n++] = rgb[1];
- buf[n++] = rgb[2];
- } else {
- buf[n++] = rgb[2];
- buf[n++] = rgb[1];
- buf[n++] = rgb[0];
- }
- }
- }
- if (i) {
- i = 0;
- goto get_fragment;
- }
- }
- return bytes;
-}
-
-#define BUFSZ 150
-
-static long qc_capture(struct qcam_device *q, char *buf, unsigned long len)
-{
- unsigned lines, pixelsperline, bitsperxfer;
- unsigned int is_bi_dir = q->bidirectional;
- size_t wantlen, outptr = 0;
- char tmpbuf[BUFSZ];
-
- if (verify_area(VERIFY_WRITE, buf, len))
- return -EFAULT;
-
- /* Wait for camera to become ready */
- for (;;)
- {
- int i = qcam_get(q, 41);
- if (i == -1) {
- qc_setup(q);
- return -EIO;
- }
- if ((i & 0x80) == 0)
- break;
- else
- schedule();
- }
-
- if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
- return -EIO;
-
- lines = q->height;
- pixelsperline = q->width;
- bitsperxfer = (is_bi_dir) ? 24 : 8;
-
- if (is_bi_dir)
- {
- /* Turn the port around */
- parport_data_reverse(q->pport);
- mdelay(3);
- qcam_set_ack(q, 0);
- if (qcam_await_ready1(q, 1)) {
- qc_setup(q);
- return -EIO;
- }
- qcam_set_ack(q, 1);
- if (qcam_await_ready1(q, 0)) {
- qc_setup(q);
- return -EIO;
- }
- }
-
- wantlen = lines * pixelsperline * 24 / 8;
-
- while (wantlen)
- {
- size_t t, s;
- s = (wantlen > BUFSZ)?BUFSZ:wantlen;
- t = qcam_read_bytes(q, tmpbuf, s);
- if (outptr < len)
- {
- size_t sz = len - outptr;
- if (sz > t) sz = t;
- if (__copy_to_user(buf+outptr, tmpbuf, sz))
- break;
- outptr += sz;
- }
- wantlen -= t;
- if (t < s)
- break;
- if (current->need_resched)
- schedule();
- }
-
- len = outptr;
-
- if (wantlen)
- {
- printk("qcam: short read.\n");
- if (is_bi_dir)
- parport_data_forward(q->pport);
- qc_setup(q);
- return len;
- }
-
- if (is_bi_dir)
- {
- int l;
- do {
- l = qcam_read_bytes(q, tmpbuf, 3);
- if (current->need_resched)
- schedule();
- } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
- if (force_rgb) {
- if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
- printk("qcam: bad EOF\n");
- } else {
- if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
- printk("qcam: bad EOF\n");
- }
- qcam_set_ack(q, 0);
- if (qcam_await_ready1(q, 1))
- {
- printk("qcam: no ack after EOF\n");
- parport_data_forward(q->pport);
- qc_setup(q);
- return len;
- }
- parport_data_forward(q->pport);
- mdelay(3);
- qcam_set_ack(q, 1);
- if (qcam_await_ready1(q, 0))
- {
- printk("qcam: no ack to port turnaround\n");
- qc_setup(q);
- return len;
- }
- }
- else
- {
- int l;
- do {
- l = qcam_read_bytes(q, tmpbuf, 1);
- if (current->need_resched)
- schedule();
- } while (l && tmpbuf[0] == 0x7e);
- l = qcam_read_bytes(q, tmpbuf+1, 2);
- if (force_rgb) {
- if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
- printk("qcam: bad EOF\n");
- } else {
- if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
- printk("qcam: bad EOF\n");
- }
- }
-
- qcam_write_data(q, 0);
- return len;
-}
-
-/*
- * Video4linux interfacing
- */
-
-static int qcam_open(struct video_device *dev, int flags)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void qcam_close(struct video_device *dev)
-{
- MOD_DEC_USE_COUNT;
-}
-
-static int qcam_init_done(struct video_device *dev)
-{
- return 0;
-}
-
-static long qcam_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
-{
- return -EINVAL;
-}
-
-static int qcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct qcam_device *qcam=(struct qcam_device *)dev;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability b;
- strcpy(b.name, "Quickcam");
- b.type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
- b.channels = 1;
- b.audios = 0;
- b.maxwidth = 320;
- b.maxheight = 240;
- b.minwidth = 80;
- b.minheight = 60;
- if(copy_to_user(arg, &b,sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGCHAN:
- {
- struct video_channel v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.channel!=0)
- return -EINVAL;
- v.flags=0;
- v.tuners=0;
- /* Good question.. its composite or SVHS so.. */
- v.type = VIDEO_TYPE_CAMERA;
- strcpy(v.name, "Camera");
- if(copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSCHAN:
- {
- int v;
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- if(v!=0)
- return -EINVAL;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner)
- return -EINVAL;
- strcpy(v.name, "Format");
- v.rangelow=0;
- v.rangehigh=0;
- v.flags= 0;
- v.mode = VIDEO_MODE_AUTO;
- if(copy_to_user(arg,&v,sizeof(v))!=0)
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner)
- return -EINVAL;
- if(v.mode!=VIDEO_MODE_AUTO)
- return -EINVAL;
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture p;
- p.colour=0x8000;
- p.hue=0x8000;
- p.brightness=qcam->brightness<<8;
- p.contrast=qcam->contrast<<8;
- p.whiteness=qcam->whitebal<<8;
- p.depth=24;
- p.palette=VIDEO_PALETTE_RGB24;
- if(copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture p;
- if(copy_from_user(&p, arg, sizeof(p)))
- return -EFAULT;
-
- /*
- * Sanity check args
- */
- if (p.depth != 24 || p.palette != VIDEO_PALETTE_RGB24)
- return -EINVAL;
-
- /*
- * Now load the camera.
- */
- qcam->brightness = p.brightness>>8;
- qcam->contrast = p.contrast>>8;
- qcam->whitebal = p.whiteness>>8;
-
- down(&qcam->lock);
- parport_claim_or_block(qcam->pdev);
- qc_setup(qcam);
- parport_release(qcam->pdev);
- up(&qcam->lock);
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
-
- if(copy_from_user(&vw, arg,sizeof(vw)))
- return -EFAULT;
- if(vw.flags)
- return -EINVAL;
- if(vw.clipcount)
- return -EINVAL;
- if(vw.height<60||vw.height>240)
- return -EINVAL;
- if(vw.width<80||vw.width>320)
- return -EINVAL;
-
- qcam->width = 80;
- qcam->height = 60;
- qcam->mode = QC_DECIMATION_4;
-
- if(vw.width>=160 && vw.height>=120)
- {
- qcam->width = 160;
- qcam->height = 120;
- qcam->mode = QC_DECIMATION_2;
- }
- if(vw.width>=320 && vw.height>=240)
- {
- qcam->width = 320;
- qcam->height = 240;
- qcam->mode = QC_DECIMATION_1;
- }
- qcam->mode |= QC_MILLIONS;
-#if 0
- if(vw.width>=640 && vw.height>=480)
- {
- qcam->width = 640;
- qcam->height = 480;
- qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
- }
-#endif
- /* Ok we figured out what to use from our
- wide choice */
- down(&qcam->lock);
- parport_claim_or_block(qcam->pdev);
- qc_setup(qcam);
- parport_release(qcam->pdev);
- up(&qcam->lock);
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
- vw.x=0;
- vw.y=0;
- vw.width=qcam->width;
- vw.height=qcam->height;
- vw.chromakey=0;
- vw.flags=0;
- if(copy_to_user(arg, &vw, sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- return -EINVAL;
- case VIDIOCGFBUF:
- return -EINVAL;
- case VIDIOCSFBUF:
- return -EINVAL;
- case VIDIOCKEY:
- return 0;
- case VIDIOCGFREQ:
- return -EINVAL;
- case VIDIOCSFREQ:
- return -EINVAL;
- case VIDIOCGAUDIO:
- return -EINVAL;
- case VIDIOCSAUDIO:
- return -EINVAL;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static long qcam_read(struct video_device *v, char *buf, unsigned long count, int noblock)
-{
- struct qcam_device *qcam=(struct qcam_device *)v;
- int len;
-
- down(&qcam->lock);
- parport_claim_or_block(qcam->pdev);
- /* Probably should have a semaphore against multiple users */
- len = qc_capture(qcam, buf,count);
- parport_release(qcam->pdev);
- up(&qcam->lock);
- return len;
-}
-
-/* video device template */
-static struct video_device qcam_template=
-{
- "Colour QuickCam",
- VID_TYPE_CAPTURE,
- VID_HARDWARE_QCAM_C,
- qcam_open,
- qcam_close,
- qcam_read,
- qcam_write,
- NULL,
- qcam_ioctl,
- NULL,
- qcam_init_done,
- NULL,
- 0,
- 0
-};
-
-/* Initialize the QuickCam driver control structure. */
-
-static struct qcam_device *qcam_init(struct parport *port)
-{
- struct qcam_device *q;
-
- q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
- if(q==NULL)
- return NULL;
-
- q->pport = port;
- q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
- NULL, 0, NULL);
-
- q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
-
- if (q->pdev == NULL)
- {
- printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
- port->name);
- kfree(q);
- return NULL;
- }
-
- memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
-
- init_MUTEX(&q->lock);
- q->width = q->ccd_width = 320;
- q->height = q->ccd_height = 240;
- q->mode = QC_MILLIONS | QC_DECIMATION_1;
- q->contrast = 192;
- q->brightness = 240;
- q->whitebal = 128;
- q->top = 1;
- q->left = 14;
- return q;
-}
-
-static struct qcam_device *qcams[MAX_CAMS];
-static unsigned int num_cams = 0;
-
-int init_cqcam(struct parport *port)
-{
- struct qcam_device *qcam;
-
- if (parport[0] != -1)
- {
- /* The user gave specific instructions */
- int i, found = 0;
- for (i = 0; i < MAX_CAMS && parport[i] != -1; i++)
- {
- if (parport[0] == port->number)
- found = 1;
- }
- if (!found)
- return -ENODEV;
- }
-
- if (num_cams == MAX_CAMS)
- return -ENOSPC;
-
- qcam = qcam_init(port);
- if (qcam==NULL)
- return -ENODEV;
-
- parport_claim_or_block(qcam->pdev);
-
- qc_reset(qcam);
-
- if (probe && qc_detect(qcam)==0)
- {
- parport_release(qcam->pdev);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
-
- qc_setup(qcam);
-
- parport_release(qcam->pdev);
-
- if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1)
- {
- printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
- qcam->pport->name);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
-
- printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
- qcam->vdev.minor, qcam->pport->name);
-
- qcams[num_cams++] = qcam;
-
- return 0;
-}
-
-void close_cqcam(struct qcam_device *qcam)
-{
- video_unregister_device(&qcam->vdev);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
-}
-
-static void cq_attach(struct parport *port)
-{
- init_cqcam(port);
-}
-
-static void cq_detach(struct parport *port)
-{
- /* Write this some day. */
-}
-
-static struct parport_driver cqcam_driver = {
- "cqcam",
- cq_attach,
- cq_detach,
- NULL
-};
-
-static int __init cqcam_init (void)
-{
- printk(BANNER "\n");
-
- return parport_register_driver(&cqcam_driver);
-}
-
-static void __exit cqcam_cleanup (void)
-{
- unsigned int i;
-
- for (i = 0; i < num_cams; i++)
- close_cqcam(qcams[i]);
-
- parport_unregister_driver(&cqcam_driver);
-}
-
-MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
-MODULE_DESCRIPTION(BANNER);
-MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
-probe=<0|1|2> for camera detection method\n\
-force_rgb=<0|1> for RGB data format (default BGR)");
-MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i");
-MODULE_PARM(probe, "i");
-MODULE_PARM(force_rgb, "i");
-
-module_init(cqcam_init);
-module_exit(cqcam_cleanup);
diff --git a/drivers/char/cpia.c b/drivers/char/cpia.c
deleted file mode 100644
index d7d007f01..000000000
--- a/drivers/char/cpia.c
+++ /dev/null
@@ -1,3324 +0,0 @@
-/*
- * cpia CPiA driver
- *
- * Supports CPiA based Video Camera's.
- *
- * (C) Copyright 1999-2000 Peter Pregler,
- * (C) Copyright 1999-2000 Scott J. Bertin,
- * (C) Copyright 1999-2000 Johannes Erdfelt, jerdfelt@valinux.com
- *
- * 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 of the License, 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.
- */
-
-/* #define _CPIA_DEBUG_ define for verbose debug output */
-#include <linux/config.h>
-
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ctype.h>
-#include <linux/pagemap.h>
-#include <asm/io.h>
-#include <asm/semaphore.h>
-#include <linux/wrapper.h>
-
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
-#include "cpia.h"
-
-#ifdef CONFIG_VIDEO_CPIA_PP
-extern int cpia_pp_init(void);
-#endif
-#ifdef CONFIG_VIDEO_CPIA_USB
-extern int cpia_usb_init(void);
-#endif
-
-#ifdef MODULE
-MODULE_AUTHOR("Scott J. Bertin <sbertin@mindspring.com> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <jerdfelt@valinux.com>");
-MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
-MODULE_SUPPORTED_DEVICE("video");
-#endif
-
-#define ABOUT "V4L-Driver for Vision CPiA based cameras"
-
-#ifndef VID_HARDWARE_CPIA
-#define VID_HARDWARE_CPIA 24 /* FIXME -> from linux/videodev.h */
-#endif
-
-#define CPIA_MODULE_CPIA (0<<5)
-#define CPIA_MODULE_SYSTEM (1<<5)
-#define CPIA_MODULE_VP_CTRL (5<<5)
-#define CPIA_MODULE_CAPTURE (6<<5)
-#define CPIA_MODULE_DEBUG (7<<5)
-
-#define INPUT (DATA_IN << 8)
-#define OUTPUT (DATA_OUT << 8)
-
-#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
-#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
-#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
-#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
-#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
-#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
-#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
-#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
-
-#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
-#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
-#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
-#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
-#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
-#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
-#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
-#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
-#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
-#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
-#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
-#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
-#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
-
-#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
-#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
-#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
-#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
-#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
-#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
-#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
-#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
-#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
-#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
-#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
-#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
-#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
-#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
-#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
-#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
-
-#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
-#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
-#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
-#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
-#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
-#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
-#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
-#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
-#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
-#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
-#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
-#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
-#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
-#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
-
-#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
-#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
-#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
-#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
-#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
-#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
-#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
-
-enum {
- FRAME_READY, /* Ready to grab into */
- FRAME_GRABBING, /* In the process of being grabbed into */
- FRAME_DONE, /* Finished grabbing, but not been synced yet */
- FRAME_UNUSED, /* Unused (no MCAPTURE) */
-};
-
-#define COMMAND_NONE 0x0000
-#define COMMAND_SETCOMPRESSION 0x0001
-#define COMMAND_SETCOMPRESSIONTARGET 0x0002
-#define COMMAND_SETCOLOURPARAMS 0x0004
-#define COMMAND_SETFORMAT 0x0008
-#define COMMAND_PAUSE 0x0010
-#define COMMAND_RESUME 0x0020
-#define COMMAND_SETYUVTHRESH 0x0040
-#define COMMAND_SETECPTIMING 0x0080
-#define COMMAND_SETCOMPRESSIONPARAMS 0x0100
-#define COMMAND_SETEXPOSURE 0x0200
-#define COMMAND_SETCOLOURBALANCE 0x0400
-#define COMMAND_SETSENSORFPS 0x0800
-#define COMMAND_SETAPCOR 0x1000
-#define COMMAND_SETFLICKERCTRL 0x2000
-#define COMMAND_SETVLOFFSET 0x4000
-
-/* Developer's Guide Table 5 p 3-34
- * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
-static u8 flicker_jumps[2][2][4] =
-{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
- { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
-};
-
-/* forward declaration of local function */
-static void reset_camera_struct(struct cam_data *cam);
-
-/**********************************************************************
- *
- * Memory management
- *
- * This is a shameless copy from the USB-cpia driver (linux kernel
- * version 2.3.29 or so, I have no idea what this code actually does ;).
- * Actually it seems to be a copy of a shameless copy of the bttv-driver.
- * Or that is a copy of a shameless copy of ... (To the powers: is there
- * no generic kernel-function to do this sort of stuff?)
- *
- * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
- * there will be one, but apparentely not yet - jerdfelt
- *
- **********************************************************************/
-
-/* Given PGD from the address space's page table, return the kernel
- * virtual mapping of the physical memory mapped at ADR.
- */
-static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
-{
- unsigned long ret = 0UL;
- pmd_t *pmd;
- pte_t *ptep, pte;
-
- if (!pgd_none(*pgd)) {
- pmd = pmd_offset(pgd, adr);
- if (!pmd_none(*pmd)) {
- ptep = pte_offset(pmd, adr);
- pte = *ptep;
- if (pte_present(pte)) {
- ret = (unsigned long) page_address(pte_page(pte));
- ret |= (adr & (PAGE_SIZE-1));
- }
- }
- }
- return ret;
-}
-
-/* Here we want the physical address of the memory.
- * This is used when initializing the contents of the
- * area and marking the pages as reserved.
- */
-static inline unsigned long kvirt_to_pa(unsigned long adr)
-{
- unsigned long va, kva, ret;
-
- va = VMALLOC_VMADDR(adr);
- kva = uvirt_to_kva(pgd_offset_k(va), va);
- ret = __pa(kva);
- return ret;
-}
-
-static void *rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr, page;
-
- /* Round it off to PAGE_SIZE */
- size += (PAGE_SIZE - 1);
- size &= ~(PAGE_SIZE - 1);
-
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
-
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
- adr = (unsigned long) mem;
- while (size > 0) {
- page = kvirt_to_pa(adr);
- mem_map_reserve(virt_to_page(__va(page)));
- adr += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- return mem;
-}
-
-static void rvfree(void *mem, unsigned long size)
-{
- unsigned long adr, page;
-
- if (!mem)
- return;
-
- size += (PAGE_SIZE - 1);
- size &= ~(PAGE_SIZE - 1);
-
- adr = (unsigned long) mem;
- while (size > 0) {
- page = kvirt_to_pa(adr);
- mem_map_unreserve(virt_to_page(__va(page)));
- adr += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
- vfree(mem);
-}
-
-/**********************************************************************
- *
- * /proc interface
- *
- **********************************************************************/
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *cpia_proc_root=NULL;
-
-static int cpia_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *out = page;
- int len, tmp;
- struct cam_data *cam = data;
- char tmpstr[20];
-
- /* IMPORTANT: This output MUST be kept under PAGE_SIZE
- * or we need to get more sophisticated. */
-
- out += sprintf(out, "read-only\n-----------------------\n");
- out += sprintf(out, "V4L Driver version: %d.%d.%d\n",
- CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
- out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n",
- cam->params.version.firmwareVersion,
- cam->params.version.firmwareRevision,
- cam->params.version.vcVersion,
- cam->params.version.vcRevision);
- out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n",
- cam->params.pnpID.vendor, cam->params.pnpID.product,
- cam->params.pnpID.deviceRevision);
- out += sprintf(out, "VP-Version: %d.%d %04x\n",
- cam->params.vpVersion.vpVersion,
- cam->params.vpVersion.vpRevision,
- cam->params.vpVersion.cameraHeadID);
-
- out += sprintf(out, "system_state: %#04x\n",
- cam->params.status.systemState);
- out += sprintf(out, "grab_state: %#04x\n",
- cam->params.status.grabState);
- out += sprintf(out, "stream_state: %#04x\n",
- cam->params.status.streamState);
- out += sprintf(out, "fatal_error: %#04x\n",
- cam->params.status.fatalError);
- out += sprintf(out, "cmd_error: %#04x\n",
- cam->params.status.cmdError);
- out += sprintf(out, "debug_flags: %#04x\n",
- cam->params.status.debugFlags);
- out += sprintf(out, "vp_status: %#04x\n",
- cam->params.status.vpStatus);
- out += sprintf(out, "error_code: %#04x\n",
- cam->params.status.errorCode);
- out += sprintf(out, "video_size: %s\n",
- cam->params.format.videoSize == VIDEOSIZE_CIF ?
- "CIF " : "QCIF");
- out += sprintf(out, "sub_sample: %s\n",
- cam->params.format.subSample == SUBSAMPLE_420 ?
- "420" : "422");
- out += sprintf(out, "yuv_order: %s\n",
- cam->params.format.yuvOrder == YUVORDER_YUYV ?
- "YUYV" : "UYVY");
- out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n",
- cam->params.roi.colStart*8,
- cam->params.roi.rowStart*4,
- cam->params.roi.colEnd*8,
- cam->params.roi.rowEnd*4);
- out += sprintf(out, "actual_fps: %3d\n", cam->fps);
- out += sprintf(out, "transfer_rate: %4dkB/s\n",
- cam->transfer_rate);
-
- out += sprintf(out, "\nread-write\n");
- out += sprintf(out, "----------------------- current min"
- " max default comment\n");
- out += sprintf(out, "brightness: %8d %8d %8d %8d\n",
- cam->params.colourParams.brightness, 0, 100, 50);
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits contrast to 80 */
- tmp = 80;
- else
- tmp = 96;
-
- out += sprintf(out, "contrast: %8d %8d %8d %8d"
- " steps of 8\n",
- cam->params.colourParams.contrast, 0, tmp, 48);
- out += sprintf(out, "saturation: %8d %8d %8d %8d\n",
- cam->params.colourParams.saturation, 0, 100, 50);
- tmp = (25000+5000*cam->params.sensorFps.baserate)/
- (1<<cam->params.sensorFps.divisor);
- out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n",
- tmp/1000, tmp%1000, 3, 30, 15);
- out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n",
- 2*cam->params.streamStartLine, 0,
- cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
- cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
- out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n",
- cam->params.ecpTiming ? "slow" : "normal", "slow",
- "normal", "normal");
-
- if (cam->params.colourBalance.balanceModeIsAuto) {
- sprintf(tmpstr, "auto");
- } else {
- sprintf(tmpstr, "manual");
- }
- out += sprintf(out, "color_balance_mode: %8s %8s %8s"
- " %8s\n", tmpstr, "manual", "auto", "auto");
- out += sprintf(out, "red_gain: %8d %8d %8d %8d\n",
- cam->params.colourBalance.redGain, 0, 212, 32);
- out += sprintf(out, "green_gain: %8d %8d %8d %8d\n",
- cam->params.colourBalance.greenGain, 0, 212, 6);
- out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n",
- cam->params.colourBalance.blueGain, 0, 212, 92);
-
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits gain to 2 */
- sprintf(tmpstr, "%8d %8d", 1, 2);
- else
- sprintf(tmpstr, "1,2,4,8");
-
- if (cam->params.exposure.gainMode == 0)
- out += sprintf(out, "max_gain: unknown %18s"
- " %8d\n", tmpstr, 2);
- else
- out += sprintf(out, "max_gain: %8d %18s %8d\n",
- 1<<(cam->params.exposure.gainMode-1), tmpstr, 2);
-
- switch(cam->params.exposure.expMode) {
- case 1:
- case 3:
- sprintf(tmpstr, "manual");
- break;
- case 2:
- sprintf(tmpstr, "auto");
- break;
- default:
- sprintf(tmpstr, "unknown");
- break;
- }
- out += sprintf(out, "exposure_mode: %8s %8s %8s"
- " %8s\n", tmpstr, "manual", "auto", "auto");
- out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n",
- (2-cam->params.exposure.centreWeight) ? "on" : "off",
- "off", "on", "on");
- out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
- 1<<cam->params.exposure.gain, 1, 1);
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits fineExp to 127 */
- tmp = 255;
- else
- tmp = 511;
-
- out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n",
- cam->params.exposure.fineExp*2, 0, tmp, 0);
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2)
- /* 1-02 firmware limits coarseExpHi to 0 */
- tmp = 255;
- else
- tmp = 65535;
-
- out += sprintf(out, "coarse_exp: %8d %8d %8d"
- " %8d\n", cam->params.exposure.coarseExpLo+
- 256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
- out += sprintf(out, "red_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.redComp, 220, 255, 220);
- out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.green1Comp, 214, 255, 214);
- out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.green2Comp, 214, 255, 214);
- out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n",
- cam->params.exposure.blueComp, 230, 255, 230);
-
- out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain1, 0, 0xff, 0x1c);
- out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain2, 0, 0xff, 0x1a);
- out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain4, 0, 0xff, 0x2d);
- out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
- cam->params.apcor.gain8, 0, 0xff, 0x2a);
- out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain1, 0, 255, 24);
- out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain2, 0, 255, 28);
- out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain4, 0, 255, 30);
- out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n",
- cam->params.vlOffset.gain8, 0, 255, 30);
- out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n",
- cam->params.flickerControl.flickerMode ? "on" : "off",
- "off", "on", "off");
- out += sprintf(out, "mains_frequency: %8d %8d %8d %8d"
- " only 50/60\n",
- cam->mainsFreq ? 60 : 50, 50, 60, 50);
- out += sprintf(out, "allowable_overexposure: %8d %8d %8d %8d\n",
- cam->params.flickerControl.allowableOverExposure, 0,
- 255, 0);
- out += sprintf(out, "compression_mode: ");
- switch(cam->params.compression.mode) {
- case CPIA_COMPRESSION_NONE:
- out += sprintf(out, "%8s", "none");
- break;
- case CPIA_COMPRESSION_AUTO:
- out += sprintf(out, "%8s", "auto");
- break;
- case CPIA_COMPRESSION_MANUAL:
- out += sprintf(out, "%8s", "manual");
- break;
- default:
- out += sprintf(out, "%8s", "unknown");
- break;
- }
- out += sprintf(out, " none,auto,manual auto\n");
- out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n",
- cam->params.compression.decimation ==
- DECIMATION_ENAB ? "on":"off", "off", "off",
- "off");
- out += sprintf(out, "compression_target: %9s %9s %9s %9s\n",
- cam->params.compressionTarget.frTargeting ==
- CPIA_COMPRESSION_TARGET_FRAMERATE ?
- "framerate":"quality",
- "framerate", "quality", "quality");
- out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n",
- cam->params.compressionTarget.targetFR, 0, 30, 7);
- out += sprintf(out, "target_quality: %8d %8d %8d %8d\n",
- cam->params.compressionTarget.targetQ, 0, 255, 10);
- out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n",
- cam->params.yuvThreshold.yThreshold, 0, 31, 15);
- out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n",
- cam->params.yuvThreshold.uvThreshold, 0, 31, 15);
- out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n",
- cam->params.compressionParams.hysteresis, 0, 255, 3);
- out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n",
- cam->params.compressionParams.threshMax, 0, 255, 11);
- out += sprintf(out, "small_step: %8d %8d %8d %8d\n",
- cam->params.compressionParams.smallStep, 0, 255, 1);
- out += sprintf(out, "large_step: %8d %8d %8d %8d\n",
- cam->params.compressionParams.largeStep, 0, 255, 3);
- out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n",
- cam->params.compressionParams.decimationHysteresis,
- 0, 255, 2);
- out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
- cam->params.compressionParams.frDiffStepThresh,
- 0, 255, 5);
- out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n",
- cam->params.compressionParams.qDiffStepThresh,
- 0, 255, 3);
- out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n",
- cam->params.compressionParams.decimationThreshMod,
- 0, 255, 2);
-
- len = out - page;
- len -= off;
- if (len < count) {
- *eof = 1;
- if (len <= 0) return 0;
- } else
- len = count;
-
- *start = page + off;
- return len;
-}
-
-static int cpia_write_proc(struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- struct cam_data *cam = data;
- struct cam_params new_params;
- int retval, find_colon;
- int size = count;
- unsigned long val;
- u32 command_flags = 0;
- u8 new_mains;
-
- if (down_interruptible(&cam->param_lock))
- return -ERESTARTSYS;
-
- /*
- * Skip over leading whitespace
- */
- while (count && isspace(*buffer)) {
- --count;
- ++buffer;
- }
-
- memcpy(&new_params, &cam->params, sizeof(struct cam_params));
- new_mains = cam->mainsFreq;
-
-#define MATCH(x) \
- ({ \
- int _len = strlen(x), _ret, _colon_found; \
- _ret = (_len <= count && strncmp(buffer, x, _len) == 0); \
- if (_ret) { \
- buffer += _len; \
- count -= _len; \
- if (find_colon) { \
- _colon_found = 0; \
- while (count && (*buffer == ' ' || *buffer == '\t' || \
- (!_colon_found && *buffer == ':'))) { \
- if (*buffer == ':') \
- _colon_found = 1; \
- --count; \
- ++buffer; \
- } \
- if (!count || !_colon_found) \
- retval = -EINVAL; \
- find_colon = 0; \
- } \
- } \
- _ret; \
- })
-#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
- new_params.version.firmwareRevision == (y))
-#define VALUE \
- ({ \
- char *_p; \
- unsigned long int _ret; \
- _ret = simple_strtoul(buffer, &_p, 0); \
- if (_p == buffer) \
- retval = -EINVAL; \
- else { \
- count -= _p - buffer; \
- buffer = _p; \
- } \
- _ret; \
- })
-
- retval = 0;
- while (count && !retval) {
- find_colon = 1;
- if (MATCH("brightness")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 100)
- new_params.colourParams.brightness = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURPARAMS;
- } else if (MATCH("contrast")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 100) {
- /* contrast is in steps of 8, so round*/
- val = ((val + 3) / 8) * 8;
- /* 1-02 firmware limits contrast to 80*/
- if (FIRMWARE_VERSION(1,2) && val > 80)
- val = 80;
-
- new_params.colourParams.contrast = val;
- } else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURPARAMS;
- } else if (MATCH("saturation")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 100)
- new_params.colourParams.saturation = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURPARAMS;
- } else if (MATCH("sensor_fps")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- /* find values so that sensorFPS is minimized,
- * but >= val */
- if (val > 30)
- retval = -EINVAL;
- else if (val > 25) {
- new_params.sensorFps.divisor = 0;
- new_params.sensorFps.baserate = 1;
- } else if (val > 15) {
- new_params.sensorFps.divisor = 0;
- new_params.sensorFps.baserate = 0;
- } else if (val > 12) {
- new_params.sensorFps.divisor = 1;
- new_params.sensorFps.baserate = 1;
- } else if (val > 7) {
- new_params.sensorFps.divisor = 1;
- new_params.sensorFps.baserate = 0;
- } else if (val > 6) {
- new_params.sensorFps.divisor = 2;
- new_params.sensorFps.baserate = 1;
- } else if (val > 3) {
- new_params.sensorFps.divisor = 2;
- new_params.sensorFps.baserate = 0;
- } else {
- new_params.sensorFps.divisor = 3;
- /* Either base rate would work here */
- new_params.sensorFps.baserate = 1;
- }
- new_params.flickerControl.coarseJump =
- flicker_jumps[new_mains]
- [new_params.sensorFps.baserate]
- [new_params.sensorFps.divisor];
- if (new_params.flickerControl.flickerMode)
- command_flags |= COMMAND_SETFLICKERCTRL;
- }
- command_flags |= COMMAND_SETSENSORFPS;
- } else if (MATCH("stream_start_line")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- int max_line = 288;
-
- if (new_params.format.videoSize == VIDEOSIZE_QCIF)
- max_line = 144;
- if (val <= max_line)
- new_params.streamStartLine = val/2;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("ecp_timing")) {
- if (!retval && MATCH("normal"))
- new_params.ecpTiming = 0;
- else if (!retval && MATCH("slow"))
- new_params.ecpTiming = 1;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETECPTIMING;
- } else if (MATCH("color_balance_mode")) {
- if (!retval && MATCH("manual"))
- new_params.colourBalance.balanceModeIsAuto = 0;
- else if (!retval && MATCH("auto"))
- new_params.colourBalance.balanceModeIsAuto = 1;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("red_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 212)
- new_params.colourBalance.redGain = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("green_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 212)
- new_params.colourBalance.greenGain = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("blue_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 212)
- new_params.colourBalance.blueGain = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOLOURBALANCE;
- } else if (MATCH("max_gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- /* 1-02 firmware limits gain to 2 */
- if (FIRMWARE_VERSION(1,2) && val > 2)
- val = 2;
- switch(val) {
- case 1:
- new_params.exposure.gainMode = 1;
- break;
- case 2:
- new_params.exposure.gainMode = 2;
- break;
- case 4:
- new_params.exposure.gainMode = 3;
- break;
- case 8:
- new_params.exposure.gainMode = 4;
- break;
- default:
- retval = -EINVAL;
- break;
- }
- }
- command_flags |= COMMAND_SETEXPOSURE;
- } else if (MATCH("exposure_mode")) {
- if (!retval && MATCH("auto"))
- new_params.exposure.expMode = 2;
- else if (!retval && MATCH("manual")) {
- if (new_params.exposure.expMode == 2)
- new_params.exposure.expMode = 3;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETEXPOSURE;
- } else if (MATCH("centre_weight")) {
- if (!retval && MATCH("on"))
- new_params.exposure.centreWeight = 1;
- else if (!retval && MATCH("off"))
- new_params.exposure.centreWeight = 2;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETEXPOSURE;
- } else if (MATCH("gain")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- switch(val) {
- case 1:
- new_params.exposure.gain = 0;
- new_params.exposure.expMode = 1;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- break;
- case 2:
- new_params.exposure.gain = 1;
- new_params.exposure.expMode = 1;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- break;
- case 4:
- new_params.exposure.gain = 2;
- new_params.exposure.expMode = 1;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- break;
- case 8:
- new_params.exposure.gain = 3;
- new_params.exposure.expMode = 1;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- break;
- default:
- retval = -EINVAL;
- break;
- }
- command_flags |= COMMAND_SETEXPOSURE;
- if (new_params.exposure.gain >
- new_params.exposure.gainMode-1)
- retval = -EINVAL;
- }
- } else if (MATCH("fine_exp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val < 256) {
- /* 1-02 firmware limits fineExp to 127*/
- if (FIRMWARE_VERSION(1,2) && val > 127)
- val = 127;
- new_params.exposure.fineExp = val;
- new_params.exposure.expMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("coarse_exp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val < 65536) {
- /* 1-02 firmware limits
- * coarseExp to 255 */
- if (FIRMWARE_VERSION(1,2) && val > 255)
- val = 255;
- new_params.exposure.coarseExpLo =
- val & 0xff;
- new_params.exposure.coarseExpHi =
- val >> 8;
- new_params.exposure.expMode = 1;
- command_flags |= COMMAND_SETEXPOSURE;
- new_params.flickerControl.flickerMode = 0;
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("red_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= 220 && val <= 255) {
- new_params.exposure.redComp = val;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("green1_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= 214 && val <= 255) {
- new_params.exposure.green1Comp = val;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("green2_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= 214 && val <= 255) {
- new_params.exposure.green2Comp = val;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("blue_comp")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val >= 230 && val <= 255) {
- new_params.exposure.blueComp = val;
- command_flags |= COMMAND_SETEXPOSURE;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain1")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain1 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain2")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain2 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain4")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain4 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("apcor_gain8")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- command_flags |= COMMAND_SETAPCOR;
- if (val <= 0xff)
- new_params.apcor.gain8 = val;
- else
- retval = -EINVAL;
- }
- } else if (MATCH("vl_offset_gain1")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain1 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("vl_offset_gain2")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain2 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("vl_offset_gain4")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain4 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("vl_offset_gain8")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.vlOffset.gain8 = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETVLOFFSET;
- } else if (MATCH("flicker_control")) {
- if (!retval && MATCH("on")) {
- new_params.flickerControl.flickerMode = 1;
- new_params.exposure.expMode = 2;
- command_flags |= COMMAND_SETEXPOSURE;
- } else if (!retval && MATCH("off"))
- new_params.flickerControl.flickerMode = 0;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else if (MATCH("mains_frequency")) {
- if (!retval && MATCH("50")) {
- new_mains = 0;
- new_params.flickerControl.coarseJump =
- flicker_jumps[new_mains]
- [new_params.sensorFps.baserate]
- [new_params.sensorFps.divisor];
- if (new_params.flickerControl.flickerMode)
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else if (!retval && MATCH("60")) {
- new_mains = 1;
- new_params.flickerControl.coarseJump =
- flicker_jumps[new_mains]
- [new_params.sensorFps.baserate]
- [new_params.sensorFps.divisor];
- if (new_params.flickerControl.flickerMode)
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- } else if (MATCH("allowable_overexposure")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff) {
- new_params.flickerControl.
- allowableOverExposure = val;
- command_flags |= COMMAND_SETFLICKERCTRL;
- } else
- retval = -EINVAL;
- }
- } else if (MATCH("compression_mode")) {
- if (!retval && MATCH("none"))
- new_params.compression.mode =
- CPIA_COMPRESSION_NONE;
- else if (!retval && MATCH("auto"))
- new_params.compression.mode =
- CPIA_COMPRESSION_AUTO;
- else if (!retval && MATCH("manual"))
- new_params.compression.mode =
- CPIA_COMPRESSION_MANUAL;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOMPRESSION;
- } else if (MATCH("decimation_enable")) {
- if (!retval && MATCH("off"))
- new_params.compression.decimation = 0;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOMPRESSION;
- } else if (MATCH("compression_target")) {
- if (!retval && MATCH("quality"))
- new_params.compressionTarget.frTargeting =
- CPIA_COMPRESSION_TARGET_QUALITY;
- else if (!retval && MATCH("framerate"))
- new_params.compressionTarget.frTargeting =
- CPIA_COMPRESSION_TARGET_FRAMERATE;
- else
- retval = -EINVAL;
-
- command_flags |= COMMAND_SETCOMPRESSIONTARGET;
- } else if (MATCH("target_framerate")) {
- if (!retval)
- val = VALUE;
-
- if (!retval)
- new_params.compressionTarget.targetFR = val;
- command_flags |= COMMAND_SETCOMPRESSIONTARGET;
- } else if (MATCH("target_quality")) {
- if (!retval)
- val = VALUE;
-
- if (!retval)
- new_params.compressionTarget.targetQ = val;
-
- command_flags |= COMMAND_SETCOMPRESSIONTARGET;
- } else if (MATCH("y_threshold")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val < 32)
- new_params.yuvThreshold.yThreshold = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETYUVTHRESH;
- } else if (MATCH("uv_threshold")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val < 32)
- new_params.yuvThreshold.uvThreshold = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETYUVTHRESH;
- } else if (MATCH("hysteresis")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.hysteresis = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("threshold_max")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.threshMax = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("small_step")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.smallStep = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("large_step")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.largeStep = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("decimation_hysteresis")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.decimationHysteresis = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("fr_diff_step_thresh")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.frDiffStepThresh = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("q_diff_step_thresh")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.qDiffStepThresh = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else if (MATCH("decimation_thresh_mod")) {
- if (!retval)
- val = VALUE;
-
- if (!retval) {
- if (val <= 0xff)
- new_params.compressionParams.decimationThreshMod = val;
- else
- retval = -EINVAL;
- }
- command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
- } else {
- DBG("No match found\n");
- retval = -EINVAL;
- }
-
- if (!retval) {
- while (count && isspace(*buffer) && *buffer != '\n') {
- --count;
- ++buffer;
- }
- if (count) {
- if (*buffer != '\n' && *buffer != ';')
- retval = -EINVAL;
- else {
- --count;
- ++buffer;
- }
- }
- }
- }
-#undef MATCH
-#undef FIRMWARE_VERSION
-#undef VALUE
-#undef FIND_VALUE
-#undef FIND_END
- if (!retval) {
- if (command_flags & COMMAND_SETCOLOURPARAMS) {
- /* Adjust cam->vp to reflect these changes */
- cam->vp.brightness =
- new_params.colourParams.brightness*65535/100;
- cam->vp.contrast =
- new_params.colourParams.contrast*65535/100;
- cam->vp.colour =
- new_params.colourParams.saturation*65535/100;
- }
-
- memcpy(&cam->params, &new_params, sizeof(struct cam_params));
- cam->mainsFreq = new_mains;
- cam->cmd_queue |= command_flags;
- retval = size;
- } else
- DBG("error: %d\n", retval);
-
- up(&cam->param_lock);
-
- return retval;
-}
-
-static void create_proc_cpia_cam(struct cam_data *cam)
-{
- char name[7];
- struct proc_dir_entry *ent;
-
- if (!cpia_proc_root || !cam)
- return;
-
- sprintf(name, "video%d", cam->vdev.minor);
-
- ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root);
- if (!ent)
- return;
-
- ent->data = cam;
- ent->read_proc = cpia_read_proc;
- ent->write_proc = cpia_write_proc;
- ent->size = 3626;
- cam->proc_entry = ent;
-}
-
-static void destroy_proc_cpia_cam(struct cam_data *cam)
-{
- char name[7];
-
- if (!cam || !cam->proc_entry)
- return;
-
- sprintf(name, "video%d", cam->vdev.minor);
- remove_proc_entry(name, cpia_proc_root);
- cam->proc_entry = NULL;
-}
-
-static void proc_cpia_create(void)
-{
- cpia_proc_root = create_proc_entry("cpia", S_IFDIR, 0);
-
- if (cpia_proc_root)
- cpia_proc_root->owner = THIS_MODULE;
- else
- LOG("Unable to initialise /proc/cpia\n");
-}
-
-static void proc_cpia_destroy(void)
-{
- remove_proc_entry("cpia", 0);
-}
-#endif /* CONFIG_PROC_FS */
-
-/* ----------------------- debug functions ---------------------- */
-
-#define printstatus(cam) \
- DBG("%02x %02x %02x %02x %02x %02x %02x %02x\n",\
- cam->params.status.systemState, cam->params.status.grabState, \
- cam->params.status.streamState, cam->params.status.fatalError, \
- cam->params.status.cmdError, cam->params.status.debugFlags, \
- cam->params.status.vpStatus, cam->params.status.errorCode);
-
-/* ----------------------- v4l helpers -------------------------- */
-
-/* supported frame palettes and depths */
-static inline int valid_mode(u16 palette, u16 depth)
-{
- return (palette == VIDEO_PALETTE_GREY && depth == 8) ||
- (palette == VIDEO_PALETTE_RGB555 && depth == 16) ||
- (palette == VIDEO_PALETTE_RGB565 && depth == 16) ||
- (palette == VIDEO_PALETTE_RGB24 && depth == 24) ||
- (palette == VIDEO_PALETTE_RGB32 && depth == 32) ||
- (palette == VIDEO_PALETTE_YUV422 && depth == 16) ||
- (palette == VIDEO_PALETTE_YUYV && depth == 16) ||
- (palette == VIDEO_PALETTE_UYVY && depth == 16);
-}
-
-static int match_videosize( int width, int height )
-{
- /* return the best match, where 'best' is as always
- * the largest that is not bigger than what is requested. */
- if (width>=352 && height>=288)
- return VIDEOSIZE_352_288; /* CIF */
-
- if (width>=320 && height>=240)
- return VIDEOSIZE_320_240; /* SIF */
-
- if (width>=288 && height>=216)
- return VIDEOSIZE_288_216;
-
- if (width>=256 && height>=192)
- return VIDEOSIZE_256_192;
-
- if (width>=224 && height>=168)
- return VIDEOSIZE_224_168;
-
- if (width>=192 && height>=144)
- return VIDEOSIZE_192_144;
-
- if (width>=176 && height>=144)
- return VIDEOSIZE_176_144; /* QCIF */
-
- if (width>=160 && height>=120)
- return VIDEOSIZE_160_120; /* QSIF */
-
- if (width>=128 && height>=96)
- return VIDEOSIZE_128_96;
-
- if (width>=88 && height>=72)
- return VIDEOSIZE_88_72;
-
- if (width>=64 && height>=48)
- return VIDEOSIZE_64_48;
-
- if (width>=48 && height>=48)
- return VIDEOSIZE_48_48;
-
- return -1;
-}
-
-/* these are the capture sizes we support */
-static void set_vw_size(struct cam_data *cam)
-{
- /* the col/row/start/end values are the result of simple math */
- /* study the SetROI-command in cpia developers guide p 2-22 */
- /* streamStartLine is set to the recommended value in the cpia */
- /* developers guide p 3-37 */
- switch(cam->video_size) {
- case VIDEOSIZE_CIF:
- cam->vw.width = 352;
- cam->vw.height = 288;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=0;
- cam->params.roi.colEnd=44;
- cam->params.roi.rowStart=0;
- cam->params.roi.rowEnd=72;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_SIF:
- cam->vw.width = 320;
- cam->vw.height = 240;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=2;
- cam->params.roi.colEnd=42;
- cam->params.roi.rowStart=6;
- cam->params.roi.rowEnd=66;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_288_216:
- cam->vw.width = 288;
- cam->vw.height = 216;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=4;
- cam->params.roi.colEnd=40;
- cam->params.roi.rowStart=9;
- cam->params.roi.rowEnd=63;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_256_192:
- cam->vw.width = 256;
- cam->vw.height = 192;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=6;
- cam->params.roi.colEnd=38;
- cam->params.roi.rowStart=12;
- cam->params.roi.rowEnd=60;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_224_168:
- cam->vw.width = 224;
- cam->vw.height = 168;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=8;
- cam->params.roi.colEnd=36;
- cam->params.roi.rowStart=15;
- cam->params.roi.rowEnd=57;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_192_144:
- cam->vw.width = 192;
- cam->vw.height = 144;
- cam->params.format.videoSize=VIDEOSIZE_CIF;
- cam->params.roi.colStart=10;
- cam->params.roi.colEnd=34;
- cam->params.roi.rowStart=18;
- cam->params.roi.rowEnd=54;
- cam->params.streamStartLine = 120;
- break;
- case VIDEOSIZE_QCIF:
- cam->vw.width = 176;
- cam->vw.height = 144;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=0;
- cam->params.roi.colEnd=22;
- cam->params.roi.rowStart=0;
- cam->params.roi.rowEnd=36;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_QSIF:
- cam->vw.width = 160;
- cam->vw.height = 120;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=1;
- cam->params.roi.colEnd=21;
- cam->params.roi.rowStart=3;
- cam->params.roi.rowEnd=33;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_128_96:
- cam->vw.width = 128;
- cam->vw.height = 96;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=3;
- cam->params.roi.colEnd=19;
- cam->params.roi.rowStart=6;
- cam->params.roi.rowEnd=30;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_88_72:
- cam->vw.width = 88;
- cam->vw.height = 72;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=5;
- cam->params.roi.colEnd=16;
- cam->params.roi.rowStart=9;
- cam->params.roi.rowEnd=27;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_64_48:
- cam->vw.width = 64;
- cam->vw.height = 48;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=7;
- cam->params.roi.colEnd=15;
- cam->params.roi.rowStart=12;
- cam->params.roi.rowEnd=24;
- cam->params.streamStartLine = 60;
- break;
- case VIDEOSIZE_48_48:
- cam->vw.width = 48;
- cam->vw.height = 48;
- cam->params.format.videoSize=VIDEOSIZE_QCIF;
- cam->params.roi.colStart=8;
- cam->params.roi.colEnd=14;
- cam->params.roi.rowStart=6;
- cam->params.roi.rowEnd=30;
- cam->params.streamStartLine = 60;
- break;
- default:
- LOG("bad videosize value: %d\n", cam->video_size);
- }
-
- return;
-}
-
-static int allocate_frame_buf(struct cam_data *cam)
-{
- int i;
-
- cam->frame_buf = rvmalloc(FRAME_NUM * CPIA_MAX_FRAME_SIZE);
- if (!cam->frame_buf)
- return -ENOBUFS;
-
- for (i = 0; i < FRAME_NUM; i++)
- cam->frame[i].data = cam->frame_buf + i * CPIA_MAX_FRAME_SIZE;
-
- return 0;
-}
-
-static int free_frame_buf(struct cam_data *cam)
-{
- int i;
-
- rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE);
- cam->frame_buf = 0;
- for (i=0; i < FRAME_NUM; i++)
- cam->frame[i].data = NULL;
-
- return 0;
-}
-
-
-static void inline free_frames(struct cpia_frame frame[FRAME_NUM])
-{
- int i;
-
- for (i=0; i < FRAME_NUM; i++)
- frame[i].state = FRAME_UNUSED;
- return;
-}
-
-/**********************************************************************
- *
- * General functions
- *
- **********************************************************************/
-/* send an arbitrary command to the camera */
-static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
-{
- int retval, datasize;
- u8 cmd[8], data[8];
-
- switch(command) {
- case CPIA_COMMAND_GetCPIAVersion:
- case CPIA_COMMAND_GetPnPID:
- case CPIA_COMMAND_GetCameraStatus:
- case CPIA_COMMAND_GetVPVersion:
- datasize=8;
- break;
- case CPIA_COMMAND_GetColourParams:
- case CPIA_COMMAND_GetColourBalance:
- case CPIA_COMMAND_GetExposure:
- down(&cam->param_lock);
- datasize=8;
- break;
- default:
- datasize=0;
- break;
- }
-
- cmd[0] = command>>8;
- cmd[1] = command&0xff;
- cmd[2] = a;
- cmd[3] = b;
- cmd[4] = c;
- cmd[5] = d;
- cmd[6] = datasize;
- cmd[7] = 0;
-
- retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
- if (retval) {
- DBG("%x - failed, retval=%d\n", command, retval);
- if (command == CPIA_COMMAND_GetColourParams ||
- command == CPIA_COMMAND_GetColourBalance ||
- command == CPIA_COMMAND_GetExposure)
- up(&cam->param_lock);
- } else {
- switch(command) {
- case CPIA_COMMAND_GetCPIAVersion:
- cam->params.version.firmwareVersion = data[0];
- cam->params.version.firmwareRevision = data[1];
- cam->params.version.vcVersion = data[2];
- cam->params.version.vcRevision = data[3];
- break;
- case CPIA_COMMAND_GetPnPID:
- cam->params.pnpID.vendor = data[0]+(((u16)data[1])<<8);
- cam->params.pnpID.product = data[2]+(((u16)data[3])<<8);
- cam->params.pnpID.deviceRevision =
- data[4]+(((u16)data[5])<<8);
- break;
- case CPIA_COMMAND_GetCameraStatus:
- cam->params.status.systemState = data[0];
- cam->params.status.grabState = data[1];
- cam->params.status.streamState = data[2];
- cam->params.status.fatalError = data[3];
- cam->params.status.cmdError = data[4];
- cam->params.status.debugFlags = data[5];
- cam->params.status.vpStatus = data[6];
- cam->params.status.errorCode = data[7];
- break;
- case CPIA_COMMAND_GetVPVersion:
- cam->params.vpVersion.vpVersion = data[0];
- cam->params.vpVersion.vpRevision = data[1];
- cam->params.vpVersion.cameraHeadID =
- data[2]+(((u16)data[3])<<8);
- break;
- case CPIA_COMMAND_GetColourParams:
- cam->params.colourParams.brightness = data[0];
- cam->params.colourParams.contrast = data[1];
- cam->params.colourParams.saturation = data[2];
- up(&cam->param_lock);
- break;
- case CPIA_COMMAND_GetColourBalance:
- cam->params.colourBalance.redGain = data[0];
- cam->params.colourBalance.greenGain = data[1];
- cam->params.colourBalance.blueGain = data[2];
- up(&cam->param_lock);
- break;
- case CPIA_COMMAND_GetExposure:
- cam->params.exposure.gain = data[0];
- cam->params.exposure.fineExp = data[1];
- cam->params.exposure.coarseExpLo = data[2];
- cam->params.exposure.coarseExpHi = data[3];
- cam->params.exposure.redComp = data[4];
- cam->params.exposure.green1Comp = data[5];
- cam->params.exposure.green2Comp = data[6];
- cam->params.exposure.blueComp = data[7];
- /* If the *Comp parameters are wacko, generate
- * a warning, and reset them back to default
- * values. - rich@annexia.org
- */
- if (cam->params.exposure.redComp < 220 ||
- cam->params.exposure.redComp > 255 ||
- cam->params.exposure.green1Comp < 214 ||
- cam->params.exposure.green1Comp > 255 ||
- cam->params.exposure.green2Comp < 214 ||
- cam->params.exposure.green2Comp > 255 ||
- cam->params.exposure.blueComp < 230 ||
- cam->params.exposure.blueComp > 255)
- {
- printk (KERN_WARNING "*_comp parameters have gone AWOL (%d/%d/%d/%d) - reseting them\n",
- cam->params.exposure.redComp,
- cam->params.exposure.green1Comp,
- cam->params.exposure.green2Comp,
- cam->params.exposure.blueComp);
- cam->params.exposure.redComp = 220;
- cam->params.exposure.green1Comp = 214;
- cam->params.exposure.green2Comp = 214;
- cam->params.exposure.blueComp = 230;
- }
- up(&cam->param_lock);
- break;
- default:
- break;
- }
- }
- return retval;
-}
-
-/* send a command to the camera with an additional data transaction */
-static int do_command_extended(struct cam_data *cam, u16 command,
- u8 a, u8 b, u8 c, u8 d,
- u8 e, u8 f, u8 g, u8 h,
- u8 i, u8 j, u8 k, u8 l)
-{
- int retval;
- u8 cmd[8], data[8];
-
- cmd[0] = command>>8;
- cmd[1] = command&0xff;
- cmd[2] = a;
- cmd[3] = b;
- cmd[4] = c;
- cmd[5] = d;
- cmd[6] = 8;
- cmd[7] = 0;
- data[0] = e;
- data[1] = f;
- data[2] = g;
- data[3] = h;
- data[4] = i;
- data[5] = j;
- data[6] = k;
- data[7] = l;
-
- retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
- if (retval)
- LOG("%x - failed\n", command);
-
- return retval;
-}
-
-/**********************************************************************
- *
- * Colorspace conversion
- *
- **********************************************************************/
-#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
-
-static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt,
- int in_uyvy, int mmap_kludge)
-{
- int y, u, v, r, g, b, y1;
-
- switch(out_fmt) {
- case VIDEO_PALETTE_RGB555:
- case VIDEO_PALETTE_RGB565:
- case VIDEO_PALETTE_RGB24:
- case VIDEO_PALETTE_RGB32:
- if (in_uyvy) {
- u = *yuv++ - 128;
- y = (*yuv++ - 16) * 76310;
- v = *yuv++ - 128;
- y1 = (*yuv - 16) * 76310;
- } else {
- y = (*yuv++ - 16) * 76310;
- u = *yuv++ - 128;
- y1 = (*yuv++ - 16) * 76310;
- v = *yuv - 128;
- }
- r = 104635 * v;
- g = -25690 * u + -53294 * v;
- b = 132278 * u;
- break;
- default:
- y = *yuv++;
- u = *yuv++;
- y1 = *yuv++;
- v = *yuv;
- /* Just to avoid compiler warnings */
- r = 0;
- g = 0;
- b = 0;
- break;
- }
- switch(out_fmt) {
- case VIDEO_PALETTE_RGB555:
- *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
- *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
- *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
- *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
- return 4;
- case VIDEO_PALETTE_RGB565:
- *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
- *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
- *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
- *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
- return 4;
- case VIDEO_PALETTE_RGB24:
- if (mmap_kludge) {
- *rgb++ = LIMIT(b+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(r+y);
- *rgb++ = LIMIT(b+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(r+y1);
- } else {
- *rgb++ = LIMIT(r+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(b+y);
- *rgb++ = LIMIT(r+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(b+y1);
- }
- return 6;
- case VIDEO_PALETTE_RGB32:
- if (mmap_kludge) {
- *rgb++ = LIMIT(b+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(r+y);
- rgb++;
- *rgb++ = LIMIT(b+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(r+y1);
- } else {
- *rgb++ = LIMIT(r+y);
- *rgb++ = LIMIT(g+y);
- *rgb++ = LIMIT(b+y);
- rgb++;
- *rgb++ = LIMIT(r+y1);
- *rgb++ = LIMIT(g+y1);
- *rgb = LIMIT(b+y1);
- }
- return 8;
- case VIDEO_PALETTE_GREY:
- *rgb++ = y;
- *rgb = y1;
- return 2;
- case VIDEO_PALETTE_YUV422:
- case VIDEO_PALETTE_YUYV:
- *rgb++ = y;
- *rgb++ = u;
- *rgb++ = y1;
- *rgb = v;
- return 4;
- case VIDEO_PALETTE_UYVY:
- *rgb++ = u;
- *rgb++ = y;
- *rgb++ = v;
- *rgb = y1;
- return 4;
- default:
- DBG("Empty: %d\n", out_fmt);
- return 0;
- }
-}
-
-static int skipcount(int count, int fmt)
-{
- switch(fmt) {
- case VIDEO_PALETTE_GREY:
- case VIDEO_PALETTE_RGB555:
- case VIDEO_PALETTE_RGB565:
- case VIDEO_PALETTE_YUV422:
- case VIDEO_PALETTE_YUYV:
- case VIDEO_PALETTE_UYVY:
- return 2*count;
- case VIDEO_PALETTE_RGB24:
- return 3*count;
- case VIDEO_PALETTE_RGB32:
- return 4*count;
- default:
- return 0;
- }
-}
-
-static int parse_picture(struct cam_data *cam, int size)
-{
- u8 *obuf, *ibuf, *end_obuf;
- int ll, in_uyvy, compressed, origsize, out_fmt;
-
- /* make sure params don't change while we are decoding */
- down(&cam->param_lock);
-
- obuf = cam->decompressed_frame.data;
- end_obuf = obuf+CPIA_MAX_FRAME_SIZE;
- ibuf = cam->raw_image;
- origsize = size;
- out_fmt = cam->vp.palette;
-
- if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) {
- LOG("header not found\n");
- up(&cam->param_lock);
- return -1;
- }
-
- if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) {
- LOG("wrong video size\n");
- up(&cam->param_lock);
- return -1;
- }
-
- if (ibuf[17] != SUBSAMPLE_422) {
- LOG("illegal subtype %d\n",ibuf[17]);
- up(&cam->param_lock);
- return -1;
- }
-
- if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) {
- LOG("illegal yuvorder %d\n",ibuf[18]);
- up(&cam->param_lock);
- return -1;
- }
- in_uyvy = ibuf[18] == YUVORDER_UYVY;
-
-#if 0
- /* FIXME: ROI mismatch occurs when switching capture sizes */
- if ((ibuf[24] != cam->params.roi.colStart) ||
- (ibuf[25] != cam->params.roi.colEnd) ||
- (ibuf[26] != cam->params.roi.rowStart) ||
- (ibuf[27] != cam->params.roi.rowEnd)) {
- LOG("ROI mismatch\n");
- up(&cam->param_lock);
- return -1;
- }
-#endif
-
- if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) {
- LOG("illegal compression %d\n",ibuf[28]);
- up(&cam->param_lock);
- return -1;
- }
- compressed = (ibuf[28] == COMPRESSED);
-
- if (ibuf[29] != NO_DECIMATION) {
- LOG("decimation not supported\n");
- up(&cam->param_lock);
- return -1;
- }
-
- cam->params.yuvThreshold.yThreshold = ibuf[30];
- cam->params.yuvThreshold.uvThreshold = ibuf[31];
- cam->params.status.systemState = ibuf[32];
- cam->params.status.grabState = ibuf[33];
- cam->params.status.streamState = ibuf[34];
- cam->params.status.fatalError = ibuf[35];
- cam->params.status.cmdError = ibuf[36];
- cam->params.status.debugFlags = ibuf[37];
- cam->params.status.vpStatus = ibuf[38];
- cam->params.status.errorCode = ibuf[39];
- cam->fps = ibuf[41];
- up(&cam->param_lock);
-
- ibuf += FRAME_HEADER_SIZE;
- size -= FRAME_HEADER_SIZE;
- ll = ibuf[0] | (ibuf[1] << 8);
- ibuf += 2;
-
- while (size > 0) {
- size -= (ll+2);
- if (size < 0) {
- LOG("Insufficient data in buffer\n");
- return -1;
- }
-
- while (ll > 1) {
- if (!compressed || (compressed && !(*ibuf & 1))) {
- obuf += yuvconvert(ibuf, obuf, out_fmt,
- in_uyvy, cam->mmap_kludge);
- ibuf += 4;
- ll -= 4;
- } else {
- /*skip compressed interval from previous frame*/
- int skipsize = skipcount(*ibuf >> 1, out_fmt);
- obuf += skipsize;
- if (obuf > end_obuf) {
- LOG("Insufficient data in buffer\n");
- return -1;
- }
- ++ibuf;
- ll--;
- }
- }
- if (ll == 1) {
- if (*ibuf != EOL) {
- LOG("EOL not found giving up after %d/%d"
- " bytes\n", origsize-size, origsize);
- return -1;
- }
-
- ibuf++; /* skip over EOL */
-
- if ((size > 3) && (ibuf[0] == EOI) && (ibuf[1] == EOI) &&
- (ibuf[2] == EOI) && (ibuf[3] == EOI)) {
- size -= 4;
- break;
- }
-
- if (size > 1) {
- ll = ibuf[0] | (ibuf[1] << 8);
- ibuf += 2; /* skip over line length */
- }
- } else {
- LOG("line length was not 1 but %d after %d/%d bytes\n",
- ll, origsize-size, origsize);
- return -1;
- }
- }
-
- cam->decompressed_frame.count = obuf-cam->decompressed_frame.data;
-
- return cam->decompressed_frame.count;
-}
-
-/* InitStreamCap wrapper to select correct start line */
-static inline int init_stream_cap(struct cam_data *cam)
-{
- return do_command(cam, CPIA_COMMAND_InitStreamCap,
- 0, cam->params.streamStartLine, 0, 0);
-}
-
-/* update various camera modes and settings */
-static void dispatch_commands(struct cam_data *cam)
-{
- down(&cam->param_lock);
- if (cam->cmd_queue==COMMAND_NONE) {
- up(&cam->param_lock);
- return;
- }
- DEB_BYTE(cam->cmd_queue);
- DEB_BYTE(cam->cmd_queue>>8);
- if (cam->cmd_queue & COMMAND_SETCOLOURPARAMS)
- do_command(cam, CPIA_COMMAND_SetColourParams,
- cam->params.colourParams.brightness,
- cam->params.colourParams.contrast,
- cam->params.colourParams.saturation, 0);
-
- if (cam->cmd_queue & COMMAND_SETCOMPRESSION)
- do_command(cam, CPIA_COMMAND_SetCompression,
- cam->params.compression.mode,
- cam->params.compression.decimation, 0, 0);
-
- if (cam->cmd_queue & COMMAND_SETFORMAT) {
- do_command(cam, CPIA_COMMAND_SetFormat,
- cam->params.format.videoSize,
- cam->params.format.subSample,
- cam->params.format.yuvOrder, 0);
- do_command(cam, CPIA_COMMAND_SetROI,
- cam->params.roi.colStart, cam->params.roi.colEnd,
- cam->params.roi.rowStart, cam->params.roi.rowEnd);
- cam->first_frame = 1;
- }
-
- if (cam->cmd_queue & COMMAND_SETCOMPRESSIONTARGET)
- do_command(cam, CPIA_COMMAND_SetCompressionTarget,
- cam->params.compressionTarget.frTargeting,
- cam->params.compressionTarget.targetFR,
- cam->params.compressionTarget.targetQ, 0);
-
- if (cam->cmd_queue & COMMAND_SETYUVTHRESH)
- do_command(cam, CPIA_COMMAND_SetYUVThresh,
- cam->params.yuvThreshold.yThreshold,
- cam->params.yuvThreshold.uvThreshold, 0, 0);
-
- if (cam->cmd_queue & COMMAND_SETECPTIMING)
- do_command(cam, CPIA_COMMAND_SetECPTiming,
- cam->params.ecpTiming, 0, 0, 0);
-
- if (cam->cmd_queue & COMMAND_SETCOMPRESSIONPARAMS)
- do_command_extended(cam, CPIA_COMMAND_SetCompressionParams,
- 0, 0, 0, 0,
- cam->params.compressionParams.hysteresis,
- cam->params.compressionParams.threshMax,
- cam->params.compressionParams.smallStep,
- cam->params.compressionParams.largeStep,
- cam->params.compressionParams.decimationHysteresis,
- cam->params.compressionParams.frDiffStepThresh,
- cam->params.compressionParams.qDiffStepThresh,
- cam->params.compressionParams.decimationThreshMod);
-
- if (cam->cmd_queue & COMMAND_SETEXPOSURE)
- do_command_extended(cam, CPIA_COMMAND_SetExposure,
- cam->params.exposure.gainMode,
- cam->params.exposure.expMode,
- cam->params.exposure.compMode,
- cam->params.exposure.centreWeight,
- cam->params.exposure.gain,
- cam->params.exposure.fineExp,
- cam->params.exposure.coarseExpLo,
- cam->params.exposure.coarseExpHi,
- cam->params.exposure.redComp,
- cam->params.exposure.green1Comp,
- cam->params.exposure.green2Comp,
- cam->params.exposure.blueComp);
-
- if (cam->cmd_queue & COMMAND_SETCOLOURBALANCE) {
- if (cam->params.colourBalance.balanceModeIsAuto) {
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 2, 0, 0, 0);
- } else {
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 1,
- cam->params.colourBalance.redGain,
- cam->params.colourBalance.greenGain,
- cam->params.colourBalance.blueGain);
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 3, 0, 0, 0);
- }
- }
-
- if (cam->cmd_queue & COMMAND_SETSENSORFPS)
- do_command(cam, CPIA_COMMAND_SetSensorFPS,
- cam->params.sensorFps.divisor,
- cam->params.sensorFps.baserate, 0, 0);
-
- if (cam->cmd_queue & COMMAND_SETAPCOR)
- do_command(cam, CPIA_COMMAND_SetApcor,
- cam->params.apcor.gain1,
- cam->params.apcor.gain2,
- cam->params.apcor.gain4,
- cam->params.apcor.gain8);
-
- if (cam->cmd_queue & COMMAND_SETFLICKERCTRL)
- do_command(cam, CPIA_COMMAND_SetFlickerCtrl,
- cam->params.flickerControl.flickerMode,
- cam->params.flickerControl.coarseJump,
- cam->params.flickerControl.allowableOverExposure, 0);
-
- if (cam->cmd_queue & COMMAND_SETVLOFFSET)
- do_command(cam, CPIA_COMMAND_SetVLOffset,
- cam->params.vlOffset.gain1,
- cam->params.vlOffset.gain2,
- cam->params.vlOffset.gain4,
- cam->params.vlOffset.gain8);
-
- if (cam->cmd_queue & COMMAND_PAUSE)
- do_command(cam, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
-
- if (cam->cmd_queue & COMMAND_RESUME)
- init_stream_cap(cam);
-
- up(&cam->param_lock);
- cam->cmd_queue = COMMAND_NONE;
- return;
-}
-
-/* kernel thread function to read image from camera */
-static void fetch_frame(void *data)
-{
- int image_size, retry;
- struct cam_data *cam = (struct cam_data *)data;
- unsigned long oldjif, rate, diff;
-
- /* Allow up to two bad images in a row to be read and
- * ignored before an error is reported */
- for (retry = 0; retry < 3; ++retry) {
- if (retry)
- DBG("retry=%d\n", retry);
-
- if (!cam->ops)
- continue;
-
- /* load first frame always uncompressed */
- if (cam->first_frame &&
- cam->params.compression.mode != CPIA_COMPRESSION_NONE)
- do_command(cam, CPIA_COMMAND_SetCompression,
- CPIA_COMPRESSION_NONE,
- NO_DECIMATION, 0, 0);
-
- /* init camera upload */
- if (do_command(cam, CPIA_COMMAND_SetGrabMode,
- CPIA_GRAB_CONTINUOUS, 0, 0, 0))
- continue;
-
- if (do_command(cam, CPIA_COMMAND_GrabFrame, 0,
- cam->params.streamStartLine, 0, 0))
- continue;
-
- if (cam->ops->wait_for_stream_ready) {
- /* loop until image ready */
- do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
- while (cam->params.status.streamState != STREAM_READY) {
- if (current->need_resched)
- schedule();
-
- current->state = TASK_INTERRUPTIBLE;
-
- /* sleep for 10 ms, hopefully ;) */
- schedule_timeout(10*HZ/1000);
- if (signal_pending(current))
- return;
-
- do_command(cam, CPIA_COMMAND_GetCameraStatus,
- 0, 0, 0, 0);
- }
- }
-
- /* grab image from camera */
- if (current->need_resched)
- schedule();
-
- oldjif = jiffies;
- image_size = cam->ops->streamRead(cam->lowlevel_data,
- cam->raw_image, 0);
- if (image_size <= 0) {
- DBG("streamRead failed: %d\n", image_size);
- continue;
- }
-
- rate = image_size * HZ / 1024;
- diff = jiffies-oldjif;
- cam->transfer_rate = diff==0 ? rate : rate/diff;
- /* diff==0 ? unlikely but possible */
-
- /* camera idle now so dispatch queued commands */
- dispatch_commands(cam);
-
- /* Update our knowledge of the camera state - FIXME: necessary? */
- do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
- do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
-
- /* decompress and convert image to by copying it from
- * raw_image to decompressed_frame
- */
- if (current->need_resched)
- schedule();
-
- cam->image_size = parse_picture(cam, image_size);
- if (cam->image_size <= 0)
- DBG("parse_picture failed %d\n", cam->image_size);
- else
- break;
- }
-
- if (retry < 3) {
- /* FIXME: this only works for double buffering */
- if (cam->frame[cam->curframe].state == FRAME_READY) {
- memcpy(cam->frame[cam->curframe].data,
- cam->decompressed_frame.data,
- cam->decompressed_frame.count);
- cam->frame[cam->curframe].state = FRAME_DONE;
- } else
- cam->decompressed_frame.state = FRAME_DONE;
-
-#if 0
- if (cam->first_frame &&
- cam->params.compression.mode != CPIA_COMPRESSION_NONE) {
- cam->first_frame = 0;
- cam->cmd_queue |= COMMAND_SETCOMPRESSION;
- }
-#else
- if (cam->first_frame) {
- cam->first_frame = 0;
- cam->cmd_queue |= COMMAND_SETCOMPRESSION;
- cam->cmd_queue |= COMMAND_SETEXPOSURE;
- }
-#endif
- }
-}
-
-static int capture_frame(struct cam_data *cam, struct video_mmap *vm)
-{
- int retval = 0;
-
- if (!cam->frame_buf) {
- /* we do lazy allocation */
- if ((retval = allocate_frame_buf(cam)))
- return retval;
- }
-
- /* FIXME: the first frame seems to be captured by the camera
- without regards to any initial settings, so we throw away
- that one, the next one is generated with our settings
- (exposure, color balance, ...)
- */
- if (cam->first_frame) {
- cam->curframe = vm->frame;
- cam->frame[cam->curframe].state = FRAME_READY;
- fetch_frame(cam);
- if (cam->frame[cam->curframe].state != FRAME_DONE)
- retval = -EIO;
- }
- cam->curframe = vm->frame;
- cam->frame[cam->curframe].state = FRAME_READY;
- fetch_frame(cam);
- if (cam->frame[cam->curframe].state != FRAME_DONE)
- retval=-EIO;
-
- return retval;
-}
-
-static int goto_high_power(struct cam_data *cam)
-{
- if (do_command(cam, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0))
- return -1;
- mdelay(100); /* windows driver does it too */
- if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
- return -1;
- if (cam->params.status.systemState == HI_POWER_STATE) {
- DBG("camera now in HIGH power state\n");
- return 0;
- }
- printstatus(cam);
- return -1;
-}
-
-static int goto_low_power(struct cam_data *cam)
-{
- if (do_command(cam, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0))
- return -1;
- if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
- return -1;
- if (cam->params.status.systemState == LO_POWER_STATE) {
- DBG("camera now in LOW power state\n");
- return 0;
- }
- printstatus(cam);
- return -1;
-}
-
-static void save_camera_state(struct cam_data *cam)
-{
- do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
- do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
-
- DBG("%d/%d/%d/%d/%d/%d/%d/%d\n",
- cam->params.exposure.gain,
- cam->params.exposure.fineExp,
- cam->params.exposure.coarseExpLo,
- cam->params.exposure.coarseExpHi,
- cam->params.exposure.redComp,
- cam->params.exposure.green1Comp,
- cam->params.exposure.green2Comp,
- cam->params.exposure.blueComp);
- DBG("%d/%d/%d\n",
- cam->params.colourBalance.redGain,
- cam->params.colourBalance.greenGain,
- cam->params.colourBalance.blueGain);
-}
-
-static void set_camera_state(struct cam_data *cam)
-{
- if(cam->params.colourBalance.balanceModeIsAuto) {
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 2, 0, 0, 0);
- } else {
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 1,
- cam->params.colourBalance.redGain,
- cam->params.colourBalance.greenGain,
- cam->params.colourBalance.blueGain);
- do_command(cam, CPIA_COMMAND_SetColourBalance,
- 3, 0, 0, 0);
- }
-
-
- do_command_extended(cam, CPIA_COMMAND_SetExposure,
- cam->params.exposure.gainMode, 1, 1,
- cam->params.exposure.centreWeight,
- cam->params.exposure.gain,
- cam->params.exposure.fineExp,
- cam->params.exposure.coarseExpLo,
- cam->params.exposure.coarseExpHi,
- cam->params.exposure.redComp,
- cam->params.exposure.green1Comp,
- cam->params.exposure.green2Comp,
- cam->params.exposure.blueComp);
- do_command_extended(cam, CPIA_COMMAND_SetExposure,
- 0, 3, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0);
-
- if (!cam->params.exposure.gainMode)
- cam->params.exposure.gainMode = 2;
- if (!cam->params.exposure.expMode)
- cam->params.exposure.expMode = 2;
- if (!cam->params.exposure.centreWeight)
- cam->params.exposure.centreWeight = 1;
-
- cam->cmd_queue = COMMAND_SETCOMPRESSION |
- COMMAND_SETCOMPRESSIONTARGET |
- COMMAND_SETCOLOURPARAMS |
- COMMAND_SETFORMAT |
- COMMAND_SETYUVTHRESH |
- COMMAND_SETECPTIMING |
- COMMAND_SETCOMPRESSIONPARAMS |
-#if 0
- COMMAND_SETEXPOSURE |
-#endif
- COMMAND_SETCOLOURBALANCE |
- COMMAND_SETSENSORFPS |
- COMMAND_SETAPCOR |
- COMMAND_SETFLICKERCTRL |
- COMMAND_SETVLOFFSET;
- dispatch_commands(cam);
- save_camera_state(cam);
-
- return;
-}
-
-static void get_version_information(struct cam_data *cam)
-{
- /* GetCPIAVersion */
- do_command(cam, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
-
- /* GetPnPID */
- do_command(cam, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
-}
-
-/* initialize camera */
-static int reset_camera(struct cam_data *cam)
-{
- /* Start the camera in low power mode */
- if (goto_low_power(cam)) {
- if (cam->params.status.systemState != WARM_BOOT_STATE)
- return -ENODEV;
-
- /* FIXME: this is just dirty trial and error */
- reset_camera_struct(cam);
- goto_high_power(cam);
- do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
- if (goto_low_power(cam))
- return -NODEV;
- }
-
- /* procedure described in developer's guide p3-28 */
-
- /* Check the firmware version FIXME: should we check PNPID? */
- cam->params.version.firmwareVersion = 0;
- get_version_information(cam);
- if (cam->params.version.firmwareVersion != 1)
- return -ENODEV;
-
- /* The fatal error checking should be done after
- * the camera powers up (developer's guide p 3-38) */
-
- /* Set streamState before transition to high power to avoid bug
- * in firmware 1-02 */
- do_command(cam, CPIA_COMMAND_ModifyCameraStatus, STREAMSTATE, 0,
- STREAM_NOT_READY, 0);
-
- /* GotoHiPower */
- if (goto_high_power(cam))
- return -ENODEV;
-
- /* Check the camera status */
- if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
- return -EIO;
-
- if (cam->params.status.fatalError) {
- DBG("fatal_error: %#04x\n",
- cam->params.status.fatalError);
- DBG("vp_status: %#04x\n",
- cam->params.status.vpStatus);
- if (cam->params.status.fatalError & ~(COM_FLAG|CPIA_FLAG)) {
- /* Fatal error in camera */
- return -EIO;
- } else if (cam->params.status.fatalError & (COM_FLAG|CPIA_FLAG)) {
- /* Firmware 1-02 may do this for parallel port cameras,
- * just clear the flags (developer's guide p 3-38) */
- do_command(cam, CPIA_COMMAND_ModifyCameraStatus,
- FATALERROR, ~(COM_FLAG|CPIA_FLAG), 0, 0);
- }
- }
-
- /* Check the camera status again */
- if (cam->params.status.fatalError) {
- if (cam->params.status.fatalError)
- return -EIO;
- }
-
- /* VPVersion can't be retrieved before the camera is in HiPower,
- * so get it here instead of in get_version_information. */
- do_command(cam, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
-
- /* set camera to a known state */
- set_camera_state(cam);
-
- return 0;
-}
-
-/* ------------------------- V4L interface --------------------- */
-static int cpia_open(struct video_device *dev, int flags)
-{
- int i;
- struct cam_data *cam = dev->priv;
-
- if (!cam) {
- DBG("Internal error, cam_data not found!\n");
- return -EBUSY;
- }
-
- if (cam->open_count > 0) {
- DBG("Camera already open\n");
- return -EBUSY;
- }
-
- if (!cam->raw_image) {
- cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE);
- if (!cam->raw_image)
- return -ENOMEM;
- }
-
- if (!cam->decompressed_frame.data) {
- cam->decompressed_frame.data = rvmalloc(CPIA_MAX_FRAME_SIZE);
- if (!cam->decompressed_frame.data) {
- rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
- cam->raw_image = NULL;
- return -ENOMEM;
- }
- }
-
- /* open cpia */
- if (cam->ops->open(cam->lowlevel_data)) {
- rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
- cam->decompressed_frame.data = NULL;
- rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
- cam->raw_image = NULL;
- return -ENODEV;
- }
-
- /* reset the camera */
- if ((i = reset_camera(cam)) != 0) {
- cam->ops->close(cam->lowlevel_data);
- rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
- cam->decompressed_frame.data = NULL;
- rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
- cam->raw_image = NULL;
- return i;
- }
-
- /* Set ownership of /proc/cpia/videoX to current user */
- if(cam->proc_entry)
- cam->proc_entry->uid = current->uid;
-
- /* set mark for loading first frame uncompressed */
- cam->first_frame = 1;
-
- /* init it to something */
- cam->mmap_kludge = 0;
-
- ++cam->open_count;
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
- return 0;
-}
-
-static void cpia_close(struct video_device *dev)
-{
- struct cam_data *cam;
-
- cam = dev->priv;
-
- if (cam->ops) {
- /* Return ownership of /proc/cpia/videoX to root */
- if(cam->proc_entry)
- cam->proc_entry->uid = 0;
-
- /* save camera state for later open (developers guide ch 3.5.3) */
- save_camera_state(cam);
-
- /* GotoLoPower */
- goto_low_power(cam);
-
- /* Update the camera ststus */
- do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
-
- /* cleanup internal state stuff */
- free_frames(cam->frame);
-
- /* close cpia */
- cam->ops->close(cam->lowlevel_data);
- }
-
- if (--cam->open_count == 0) {
- /* clean up capture-buffers */
- if (cam->raw_image) {
- rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
- cam->raw_image = NULL;
- }
-
- if (cam->decompressed_frame.data) {
- rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
- cam->decompressed_frame.data = NULL;
- }
-
- if (cam->frame_buf)
- free_frame_buf(cam);
-
- if (!cam->ops) {
- video_unregister_device(dev);
- kfree(cam);
- }
- }
-
-
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
- return;
-}
-
-static long cpia_read(struct video_device *dev, char *buf,
- unsigned long count, int noblock)
-{
- struct cam_data *cam = dev->priv;
-
- /* make this _really_ smp and multithredi-safe */
- if (down_interruptible(&cam->busy_lock))
- return -EINTR;
-
- if (!buf) {
- DBG("buf NULL\n");
- up(&cam->busy_lock);
- return -EINVAL;
- }
-
- if (!count) {
- DBG("count 0\n");
- up(&cam->busy_lock);
- return 0;
- }
-
- if (!cam->ops) {
- DBG("ops NULL\n");
- up(&cam->busy_lock);
- return -ENODEV;
- }
-
- /* upload frame */
- cam->decompressed_frame.state = FRAME_READY;
- cam->mmap_kludge=0;
- fetch_frame(cam);
- if (cam->decompressed_frame.state != FRAME_DONE) {
- DBG("upload failed %d/%d\n", cam->decompressed_frame.count,
- cam->decompressed_frame.state);
- up(&cam->busy_lock);
- return -EIO;
- }
- cam->decompressed_frame.state = FRAME_UNUSED;
-
- /* copy data to user space */
- if (cam->decompressed_frame.count > count) {
- DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count,
- count);
- up(&cam->busy_lock);
- return -EFAULT;
- }
- if (copy_to_user(buf, cam->decompressed_frame.data,
- cam->decompressed_frame.count)) {
- DBG("copy_to_user failed\n");
- up(&cam->busy_lock);
- return -EFAULT;
- }
-
- up(&cam->busy_lock);
- return cam->decompressed_frame.count;
-}
-
-static int cpia_ioctl(struct video_device *dev, unsigned int ioctlnr, void *arg)
-{
- struct cam_data *cam = dev->priv;
- int retval = 0;
-
- if (!cam || !cam->ops)
- return -ENODEV;
-
- /* make this _really_ smp-safe */
- if (down_interruptible(&cam->busy_lock))
- return -EINTR;
-
- //DBG("cpia_ioctl: %u\n", ioctlnr);
-
- switch (ioctlnr) {
- /* query capabilites */
- case VIDIOCGCAP:
- {
- struct video_capability b;
-
- DBG("VIDIOCGCAP\n");
- strcpy(b.name, "CPiA Camera");
- b.type = VID_TYPE_CAPTURE;
- b.channels = 1;
- b.audios = 0;
- b.maxwidth = 352; /* VIDEOSIZE_CIF */
- b.maxheight = 288;
- b.minwidth = 48; /* VIDEOSIZE_48_48 */
- b.minheight = 48;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- retval = -EFAULT;
-
- break;
- }
-
- /* get/set video source - we are a camera and nothing else */
- case VIDIOCGCHAN:
- {
- struct video_channel v;
-
- DBG("VIDIOCGCHAN\n");
- if (copy_from_user(&v, arg, sizeof(v))) {
- retval = -EFAULT;
- break;
- }
- if (v.channel != 0) {
- retval = -EINVAL;
- break;
- }
-
- v.channel = 0;
- strcpy(v.name, "Camera");
- v.tuners = 0;
- v.flags = 0;
- v.type = VIDEO_TYPE_CAMERA;
- v.norm = 0;
-
- if (copy_to_user(arg, &v, sizeof(v)))
- retval = -EFAULT;
- break;
- }
-
- case VIDIOCSCHAN:
- {
- int v;
-
- DBG("VIDIOCSCHAN\n");
- if (copy_from_user(&v, arg, sizeof(v)))
- retval = -EFAULT;
-
- if (retval == 0 && v != 0)
- retval = -EINVAL;
-
- break;
- }
-
- /* image properties */
- case VIDIOCGPICT:
- DBG("VIDIOCGPICT\n");
- if (copy_to_user(arg, &cam->vp, sizeof(struct video_picture)))
- retval = -EFAULT;
- break;
-
- case VIDIOCSPICT:
- {
- struct video_picture vp;
-
- DBG("VIDIOCSPICT\n");
-
- /* copy_from_user */
- if (copy_from_user(&vp, arg, sizeof(vp))) {
- retval = -EFAULT;
- break;
- }
-
- /* check validity */
- DBG("palette: %d\n", vp.palette);
- DBG("depth: %d\n", vp.depth);
- if (!valid_mode(vp.palette, vp.depth)) {
- retval = -EINVAL;
- break;
- }
-
- down(&cam->param_lock);
- /* brightness, colour, contrast need no check 0-65535 */
- memcpy( &cam->vp, &vp, sizeof(vp) );
- /* update cam->params.colourParams */
- cam->params.colourParams.brightness = vp.brightness*100/65535;
- cam->params.colourParams.contrast = vp.contrast*100/65535;
- cam->params.colourParams.saturation = vp.colour*100/65535;
- /* contrast is in steps of 8, so round */
- cam->params.colourParams.contrast =
- ((cam->params.colourParams.contrast + 3) / 8) * 8;
- if (cam->params.version.firmwareVersion == 1 &&
- cam->params.version.firmwareRevision == 2 &&
- cam->params.colourParams.contrast > 80) {
- /* 1-02 firmware limits contrast to 80 */
- cam->params.colourParams.contrast = 80;
- }
-
- /* queue command to update camera */
- cam->cmd_queue |= COMMAND_SETCOLOURPARAMS;
- up(&cam->param_lock);
- DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n",
- vp.depth, vp.palette, vp.brightness, vp.hue, vp.colour,
- vp.contrast);
- break;
- }
-
- /* get/set capture window */
- case VIDIOCGWIN:
- DBG("VIDIOCGWIN\n");
-
- if (copy_to_user(arg, &cam->vw, sizeof(struct video_window)))
- retval = -EFAULT;
- break;
-
- case VIDIOCSWIN:
- {
- /* copy_from_user, check validity, copy to internal structure */
- struct video_window vw;
- DBG("VIDIOCSWIN\n");
- if (copy_from_user(&vw, arg, sizeof(vw))) {
- retval = -EFAULT;
- break;
- }
-
- if (vw.clipcount != 0) { /* clipping not supported */
- retval = -EINVAL;
- break;
- }
- if (vw.clips != NULL) { /* clipping not supported */
- retval = -EINVAL;
- break;
- }
-
- /* we set the video window to something smaller or equal to what
- * is requested by the user???
- */
- down(&cam->param_lock);
- if (vw.width != cam->vw.width || vw.height != cam->vw.height) {
- int video_size = match_videosize(vw.width, vw.height);
-
- if (video_size < 0) {
- retval = -EINVAL;
- up(&cam->param_lock);
- break;
- }
- cam->video_size = video_size;
- set_vw_size(cam);
- DBG("%d / %d\n", cam->vw.width, cam->vw.height);
- cam->cmd_queue |= COMMAND_SETFORMAT;
- }
-
- // FIXME needed??? memcpy(&cam->vw, &vw, sizeof(vw));
- up(&cam->param_lock);
-
- /* setformat ignored by camera during streaming,
- * so stop/dispatch/start */
- if (cam->cmd_queue & COMMAND_SETFORMAT) {
- DBG("\n");
- dispatch_commands(cam);
- }
- DBG("%d/%d:%d\n", cam->video_size,
- cam->vw.width, cam->vw.height);
- break;
- }
-
- /* mmap interface */
- case VIDIOCGMBUF:
- {
- struct video_mbuf vm;
- int i;
-
- DBG("VIDIOCGMBUF\n");
- memset(&vm, 0, sizeof(vm));
- vm.size = CPIA_MAX_FRAME_SIZE*FRAME_NUM;
- vm.frames = FRAME_NUM;
- for (i = 0; i < FRAME_NUM; i++)
- vm.offsets[i] = CPIA_MAX_FRAME_SIZE * i;
-
- if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
- retval = -EFAULT;
-
- break;
- }
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap vm;
- int video_size;
-
- if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) {
- retval = -EFAULT;
- break;
- }
-#if 1
- DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm.format, vm.frame,
- vm.width, vm.height);
-#endif
- if (vm.frame<0||vm.frame>FRAME_NUM) {
- retval = -EINVAL;
- break;
- }
-
- /* set video format */
- cam->vp.palette = vm.format;
- switch(vm.format) {
- case VIDEO_PALETTE_GREY:
- case VIDEO_PALETTE_RGB555:
- case VIDEO_PALETTE_RGB565:
- case VIDEO_PALETTE_YUV422:
- case VIDEO_PALETTE_YUYV:
- case VIDEO_PALETTE_UYVY:
- cam->vp.depth = 16;
- break;
- case VIDEO_PALETTE_RGB24:
- cam->vp.depth = 24;
- break;
- case VIDEO_PALETTE_RGB32:
- cam->vp.depth = 32;
- break;
- default:
- retval = -EINVAL;
- break;
- }
- if (retval)
- break;
-
- /* set video size */
- video_size = match_videosize(vm.width, vm.height);
- if (cam->video_size < 0) {
- retval = -EINVAL;
- break;
- }
- if (video_size != cam->video_size) {
- cam->video_size = video_size;
- set_vw_size(cam);
- cam->cmd_queue |= COMMAND_SETFORMAT;
- dispatch_commands(cam);
- }
-#if 0
- DBG("VIDIOCMCAPTURE: %d / %d/%d\n", cam->video_size,
- cam->vw.width, cam->vw.height);
-#endif
- /* according to v4l-spec we must start streaming here */
- cam->mmap_kludge = 1;
- retval = capture_frame(cam, &vm);
-
- break;
- }
-
- case VIDIOCSYNC:
- {
- int frame;
-
- if (copy_from_user((void *)&frame, arg, sizeof(int))) {
- retval = -EFAULT;
- break;
- }
- //DBG("VIDIOCSYNC: %d\n", frame);
-
- if (frame<0 || frame >= FRAME_NUM) {
- retval = -EINVAL;
- break;
- }
-
- switch (cam->frame[frame].state) {
- case FRAME_UNUSED:
- case FRAME_READY:
- case FRAME_GRABBING:
- DBG("sync to unused frame %d\n", frame);
- retval = -EINVAL;
- break;
-
- case FRAME_DONE:
- cam->frame[frame].state = FRAME_UNUSED;
- //DBG("VIDIOCSYNC: %d synced\n", frame);
- break;
- }
- if (retval == -EINTR) {
- /* FIXME - xawtv does not handle this nice */
- retval = 0;
- }
- break;
- }
-
- /* pointless to implement overlay with this camera */
- case VIDIOCCAPTURE:
- retval = -EINVAL;
- break;
- case VIDIOCGFBUF:
- retval = -EINVAL;
- break;
- case VIDIOCSFBUF:
- retval = -EINVAL;
- break;
- case VIDIOCKEY:
- retval = -EINVAL;
- break;
-
- /* tuner interface - we have none */
- case VIDIOCGTUNER:
- retval = -EINVAL;
- break;
- case VIDIOCSTUNER:
- retval = -EINVAL;
- break;
- case VIDIOCGFREQ:
- retval = -EINVAL;
- break;
- case VIDIOCSFREQ:
- retval = -EINVAL;
- break;
-
- /* audio interface - we have none */
- case VIDIOCGAUDIO:
- retval = -EINVAL;
- break;
- case VIDIOCSAUDIO:
- retval = -EINVAL;
- break;
- default:
- retval = -ENOIOCTLCMD;
- break;
- }
-
- up(&cam->param_lock);
- up(&cam->busy_lock);
- return retval;
-}
-
-/* FIXME */
-static int cpia_mmap(struct video_device *dev, const char *adr,
- unsigned long size)
-{
- unsigned long start = (unsigned long)adr;
- unsigned long page, pos;
- struct cam_data *cam = dev->priv;
- int retval;
-
- if (!cam || !cam->ops)
- return -ENODEV;
-
- DBG("cpia_mmap: %ld\n", size);
-
- if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
- return -EINVAL;
-
- if (!cam || !cam->ops)
- return -ENODEV;
-
- /* make this _really_ smp-safe */
- if (down_interruptible(&cam->busy_lock))
- return -EINTR;
-
- if (!cam->frame_buf) { /* we do lazy allocation */
- if ((retval = allocate_frame_buf(cam))) {
- up(&cam->busy_lock);
- return retval;
- }
- }
-
- pos = (unsigned long)(cam->frame_buf);
- while (size > 0) {
- page = kvirt_to_pa(pos);
- if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
- up(&cam->busy_lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- DBG("cpia_mmap: %ld\n", size);
- up(&cam->busy_lock);
-
- return 0;
-}
-
-int cpia_video_init(struct video_device *vdev)
-{
-#ifdef CONFIG_PROC_FS
- create_proc_cpia_cam(vdev->priv);
-#endif
- return 0;
-}
-
-static struct video_device cpia_template = {
- "CPiA Camera",
- VID_TYPE_CAPTURE,
- VID_HARDWARE_CPIA, /* FIXME */
- cpia_open, /* open */
- cpia_close, /* close */
- cpia_read, /* read */
- NULL, /* no write */
- NULL, /* no poll */
- cpia_ioctl, /* ioctl */
- cpia_mmap, /* mmap */
- cpia_video_init, /* initialize */
- NULL, /* priv */
- 0, /* busy */
- -1 /* minor - unset */
-};
-
-/* initialise cam_data structure */
-static void reset_camera_struct(struct cam_data *cam)
-{
- /* The following parameter values are the defaults from
- * "Software Developer's Guide for CPiA Cameras". Any changes
- * to the defaults are noted in comments. */
- cam->params.colourParams.brightness = 50;
- cam->params.colourParams.contrast = 48;
- cam->params.colourParams.saturation = 50;
- cam->params.exposure.gainMode = 2;
- cam->params.exposure.expMode = 2; /* AEC */
- cam->params.exposure.compMode = 1;
- cam->params.exposure.centreWeight = 1;
- cam->params.exposure.gain = 0;
- cam->params.exposure.fineExp = 0;
- cam->params.exposure.coarseExpLo = 185;
- cam->params.exposure.coarseExpHi = 0;
- cam->params.exposure.redComp = 220;
- cam->params.exposure.green1Comp = 214;
- cam->params.exposure.green2Comp = 214;
- cam->params.exposure.blueComp = 230;
- cam->params.colourBalance.balanceModeIsAuto = 1;
- cam->params.colourBalance.redGain = 32;
- cam->params.colourBalance.greenGain = 6;
- cam->params.colourBalance.blueGain = 92;
- cam->params.apcor.gain1 = 0x1c;
- cam->params.apcor.gain2 = 0x1a;
- cam->params.apcor.gain4 = 0x2d;
- cam->params.apcor.gain8 = 0x2a;
- cam->params.flickerControl.flickerMode = 0;
- cam->params.flickerControl.coarseJump =
- flicker_jumps[cam->mainsFreq]
- [cam->params.sensorFps.baserate]
- [cam->params.sensorFps.divisor];
- cam->params.vlOffset.gain1 = 24;
- cam->params.vlOffset.gain2 = 28;
- cam->params.vlOffset.gain4 = 30;
- cam->params.vlOffset.gain8 = 30;
- cam->params.compressionParams.hysteresis = 3;
- cam->params.compressionParams.threshMax = 11;
- cam->params.compressionParams.smallStep = 1;
- cam->params.compressionParams.largeStep = 3;
- cam->params.compressionParams.decimationHysteresis = 2;
- cam->params.compressionParams.frDiffStepThresh = 5;
- cam->params.compressionParams.qDiffStepThresh = 3;
- cam->params.compressionParams.decimationThreshMod = 2;
- /* End of default values from Software Developer's Guide */
-
- cam->transfer_rate = 0;
-
- /* Set Sensor FPS to 15fps. This seems better than 30fps
- * for indoor lighting. */
- cam->params.sensorFps.divisor = 1;
- cam->params.sensorFps.baserate = 1;
-
- cam->params.yuvThreshold.yThreshold = 15; /* FIXME? */
- cam->params.yuvThreshold.uvThreshold = 15; /* FIXME? */
-
- cam->params.format.subSample = SUBSAMPLE_422;
- cam->params.format.yuvOrder = YUVORDER_YUYV;
-
- cam->params.compression.mode = CPIA_COMPRESSION_AUTO;
- cam->params.compressionTarget.frTargeting =
- CPIA_COMPRESSION_TARGET_QUALITY;
- cam->params.compressionTarget.targetFR = 7; /* FIXME? */
- cam->params.compressionTarget.targetQ = 10; /* FIXME? */
-
- cam->video_size = VIDEOSIZE_CIF;
-
- cam->vp.colour = 32768; /* 50% */
- cam->vp.hue = 32768; /* 50% */
- cam->vp.brightness = 32768; /* 50% */
- cam->vp.contrast = 32768; /* 50% */
- cam->vp.whiteness = 0; /* not used -> grayscale only */
- cam->vp.depth = 0; /* FIXME: to be set by user? */
- cam->vp.palette = VIDEO_PALETTE_RGB24; /* FIXME: to be set by user? */
-
- cam->vw.x = 0;
- cam->vw.y = 0;
- set_vw_size(cam);
- cam->vw.chromakey = 0;
- /* PP NOTE: my extension to use vw.flags for this, bear it! */
- cam->vw.flags = 0;
- cam->vw.clipcount = 0;
- cam->vw.clips = NULL;
-
- cam->cmd_queue = COMMAND_NONE;
- cam->first_frame = 0;
-
- return;
-}
-
-/* initialize cam_data structure */
-static void init_camera_struct(struct cam_data *cam,
- struct cpia_camera_ops *ops )
-{
- int i;
-
- /* Default everything to 0 */
- memset(cam, 0, sizeof(struct cam_data));
-
- cam->ops = ops;
- init_MUTEX(&cam->param_lock);
- init_MUTEX(&cam->busy_lock);
-
- reset_camera_struct(cam);
-
- cam->proc_entry = NULL;
-
- memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template));
- cam->vdev.priv = cam;
-
- cam->curframe = 0;
- for (i = 0; i < FRAME_NUM; i++) {
- cam->frame[i].width = 0;
- cam->frame[i].height = 0;
- cam->frame[i].state = FRAME_UNUSED;
- cam->frame[i].data = NULL;
- }
- cam->decompressed_frame.width = 0;
- cam->decompressed_frame.height = 0;
- cam->decompressed_frame.state = FRAME_UNUSED;
- cam->decompressed_frame.data = NULL;
-}
-
-struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel)
-{
- struct cam_data *camera;
-
- /* Need a lock when adding/removing cameras. This doesn't happen
- * often and doesn't take very long, so grabbing the kernel lock
- * should be OK. */
-
- if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL) {
- unlock_kernel();
- return NULL;
- }
-
- init_camera_struct( camera, ops );
- camera->lowlevel_data = lowlevel;
-
- /* register v4l device */
- if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER) == -1) {
- kfree(camera);
- unlock_kernel();
- printk(KERN_DEBUG "video_register_device failed\n");
- return NULL;
- }
-
- /* get version information from camera: open/reset/close */
-
- /* open cpia */
- if (camera->ops->open(camera->lowlevel_data))
- return camera;
-
- /* reset the camera */
- if (reset_camera(camera) != 0) {
- camera->ops->close(camera->lowlevel_data);
- return camera;
- }
-
- /* close cpia */
- camera->ops->close(camera->lowlevel_data);
-
-/* Eh? Feeling happy? - jerdfelt */
-/*
- camera->ops->open(camera->lowlevel_data);
- camera->ops->close(camera->lowlevel_data);
-*/
-
- printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n",
- camera->params.version.firmwareVersion,
- camera->params.version.firmwareRevision,
- camera->params.version.vcVersion,
- camera->params.version.vcRevision);
- printk(KERN_INFO " CPiA PnP-ID: %04x:%04x:%04x\n",
- camera->params.pnpID.vendor,
- camera->params.pnpID.product,
- camera->params.pnpID.deviceRevision);
- printk(KERN_INFO " VP-Version: %d.%d %04x\n",
- camera->params.vpVersion.vpVersion,
- camera->params.vpVersion.vpRevision,
- camera->params.vpVersion.cameraHeadID);
-
- return camera;
-}
-
-void cpia_unregister_camera(struct cam_data *cam)
-{
- if (!cam->open_count) {
- DBG("unregistering video\n");
- video_unregister_device(&cam->vdev);
- } else {
- LOG("/dev/video%d removed while open, "
- "deferring video_unregister_device\n", cam->vdev.minor);
- DBG("camera open -- setting ops to NULL\n");
- cam->ops = NULL;
- }
-
-#ifdef CONFIG_PROC_FS
- DBG("destroying /proc/cpia/video%d\n", cam->vdev.minor);
- destroy_proc_cpia_cam(cam);
-#endif
- if (!cam->open_count) {
- DBG("freeing camera\n");
- kfree(cam);
- }
-}
-
-/****************************************************************************
- *
- * Module routines
- *
- ***************************************************************************/
-
-#ifdef MODULE
-int init_module(void)
-{
- printk(KERN_INFO "%s v%d.%d.%d\n", ABOUT,
- CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
-#ifdef CONFIG_PROC_FS
- proc_cpia_create();
-#endif
-#ifdef CONFIG_KMOD
-#ifdef CONFIG_VIDEO_CPIA_PP_MODULE
- request_module("cpia_pp");
-#endif
-#ifdef CONFIG_VIDEO_CPIA_USB_MODULE
- request_module("cpia_usb");
-#endif
-#endif
-return 0;
-}
-
-void cleanup_module(void)
-{
-#ifdef CONFIG_PROC_FS
- proc_cpia_destroy();
-#endif
-}
-
-#else
-
-int cpia_init(struct video_init *unused)
-{
- printk(KERN_INFO "%s v%d.%d.%d\n", ABOUT,
- CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
-#ifdef CONFIG_PROC_FS
- proc_cpia_create();
-#endif
-
-#ifdef CONFIG_VIDEO_CPIA_PP
- cpia_pp_init();
-#endif
-#ifdef CONFIG_KMOD
-#ifdef CONFIG_VIDEO_CPIA_PP_MODULE
- request_module("cpia_pp");
-#endif
-
-#ifdef CONFIG_VIDEO_CPIA_USB_MODULE
- request_module("cpia_usb");
-#endif
-#endif /* CONFIG_KMOD */
-#ifdef CONFIG_VIDEO_CPIA_USB
- cpia_usb_init();
-#endif
- return 0;
-}
-
-/* Exported symbols for modules. */
-
-EXPORT_SYMBOL(cpia_register_camera);
-EXPORT_SYMBOL(cpia_unregister_camera);
-
-#endif
diff --git a/drivers/char/cpia.h b/drivers/char/cpia.h
deleted file mode 100644
index 579b5e153..000000000
--- a/drivers/char/cpia.h
+++ /dev/null
@@ -1,421 +0,0 @@
-#ifndef cpia_h
-#define cpia_h
-
-/*
- * CPiA Parallel Port Video4Linux driver
- *
- * Supports CPiA based parallel port Video Camera's.
- *
- * (C) Copyright 1999 Bas Huisman,
- * Peter Pregler,
- * Scott J. Bertin,
- * VLSI Vision Ltd.
- *
- * 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 of the License, 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.
- */
-
-#define CPIA_MAJ_VER 0
-#define CPIA_MIN_VER 7
-#define CPIA_PATCH_VER 4
-
-#define CPIA_PP_MAJ_VER 0
-#define CPIA_PP_MIN_VER 7
-#define CPIA_PP_PATCH_VER 4
-
-#define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4) /* CIF at RGB32 */
-#define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */
-
-#ifdef __KERNEL__
-
-#include <asm/uaccess.h>
-#include <linux/videodev.h>
-#include <linux/smp_lock.h>
-
-struct cpia_camera_ops
-{
- /* open sets privdata to point to structure for this camera.
- * Returns negative value on error, otherwise 0.
- */
- int (*open)(void *privdata);
-
- /* Registers callback function cb to be called with cbdata
- * when an image is ready. If cb is NULL, only single image grabs
- * should be used. cb should immediately call streamRead to read
- * the data or data may be lost. Returns negative value on error,
- * otherwise 0.
- */
- int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
- void *cbdata);
-
- /* transferCmd sends commands to the camera. command MUST point to
- * an 8 byte buffer in kernel space. data can be NULL if no extra
- * data is needed. The size of the data is given by the last 2
- * bytes of comand. data must also point to memory in kernel space.
- * Returns negative value on error, otherwise 0.
- */
- int (*transferCmd)(void *privdata, u8 *command, u8 *data);
-
- /* streamStart initiates stream capture mode.
- * Returns negative value on error, otherwise 0.
- */
- int (*streamStart)(void *privdata);
-
- /* streamStop terminates stream capture mode.
- * Returns negative value on error, otherwise 0.
- */
- int (*streamStop)(void *privdata);
-
- /* streamRead reads a frame from the camera. buffer points to a
- * buffer large enough to hold a complete frame in kernel space.
- * noblock indicates if this should be a non blocking read.
- * Returns the number of bytes read, or negative value on error.
- */
- int (*streamRead)(void *privdata, u8 *buffer, int noblock);
-
- /* close disables the device until open() is called again.
- * Returns negative value on error, otherwise 0.
- */
- int (*close)(void *privdata);
-
- /* If wait_for_stream_ready is non-zero, wait until the streamState
- * is STREAM_READY before calling streamRead.
- */
- int wait_for_stream_ready;
-};
-
-struct cpia_frame {
- u8 *data;
- int count;
- int width;
- int height;
- volatile int state;
-};
-
-struct cam_params {
- struct {
- u8 firmwareVersion;
- u8 firmwareRevision;
- u8 vcVersion;
- u8 vcRevision;
- } version;
- struct {
- u16 vendor;
- u16 product;
- u16 deviceRevision;
- } pnpID;
- struct {
- u8 vpVersion;
- u8 vpRevision;
- u16 cameraHeadID;
- } vpVersion;
- struct {
- u8 systemState;
- u8 grabState;
- u8 streamState;
- u8 fatalError;
- u8 cmdError;
- u8 debugFlags;
- u8 vpStatus;
- u8 errorCode;
- } status;
- struct {
- u8 brightness;
- u8 contrast;
- u8 saturation;
- } colourParams;
- struct {
- u8 gainMode;
- u8 expMode;
- u8 compMode;
- u8 centreWeight;
- u8 gain;
- u8 fineExp;
- u8 coarseExpLo;
- u8 coarseExpHi;
- u8 redComp;
- u8 green1Comp;
- u8 green2Comp;
- u8 blueComp;
- } exposure;
- struct {
- u8 balanceModeIsAuto;
- u8 redGain;
- u8 greenGain;
- u8 blueGain;
- } colourBalance;
- struct {
- u8 divisor;
- u8 baserate;
- } sensorFps;
- struct {
- u8 gain1;
- u8 gain2;
- u8 gain4;
- u8 gain8;
- } apcor;
- struct {
- u8 flickerMode;
- u8 coarseJump;
- u8 allowableOverExposure;
- } flickerControl;
- struct {
- u8 gain1;
- u8 gain2;
- u8 gain4;
- u8 gain8;
- } vlOffset;
- struct {
- u8 mode;
- u8 decimation;
- } compression;
- struct {
- u8 frTargeting;
- u8 targetFR;
- u8 targetQ;
- } compressionTarget;
- struct {
- u8 yThreshold;
- u8 uvThreshold;
- } yuvThreshold;
- struct {
- u8 hysteresis;
- u8 threshMax;
- u8 smallStep;
- u8 largeStep;
- u8 decimationHysteresis;
- u8 frDiffStepThresh;
- u8 qDiffStepThresh;
- u8 decimationThreshMod;
- } compressionParams;
- struct {
- u8 videoSize; /* CIF/QCIF */
- u8 subSample;
- u8 yuvOrder;
- } format;
- struct {
- u8 colStart; /* skip first 8*colStart pixels */
- u8 colEnd; /* finish at 8*colEnd pixels */
- u8 rowStart; /* skip first 4*rowStart lines */
- u8 rowEnd; /* finish at 4*rowEnd lines */
- } roi;
- u8 ecpTiming;
- u8 streamStartLine;
-};
-
-enum v4l_camstates {
- CPIA_V4L_IDLE = 0,
- CPIA_V4L_ERROR,
- CPIA_V4L_COMMAND,
- CPIA_V4L_GRABBING,
- CPIA_V4L_STREAMING,
- CPIA_V4L_STREAMING_PAUSED,
-};
-
-#define FRAME_NUM 2 /* double buffering for now */
-
-struct cam_data {
- struct cam_data **previous;
- struct cam_data *next;
-
- struct semaphore busy_lock; /* guard against SMP multithreading */
- struct cpia_camera_ops *ops; /* lowlevel driver operations */
- void *lowlevel_data; /* private data for lowlevel driver */
- u8 *raw_image; /* buffer for raw image data */
- struct cpia_frame decompressed_frame;
- /* buffer to hold decompressed frame */
- int image_size; /* sizeof last decompressed image */
- int open_count; /* # of process that have camera open */
-
- /* camera status */
- int fps; /* actual fps reported by the camera */
- int transfer_rate; /* transfer rate from camera in kB/s */
- u8 mainsFreq; /* for flicker control */
-
- /* proc interface */
- struct semaphore param_lock; /* params lock for this camera */
- struct cam_params params; /* camera settings */
- struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
-
- /* v4l */
- int video_size; /* VIDEO_SIZE_ */
- volatile enum v4l_camstates camstate; /* v4l layer status */
- struct video_device vdev; /* v4l videodev */
- struct video_picture vp; /* v4l camera settings */
- struct video_window vw; /* v4l capture area */
-
- /* mmap interface */
- int curframe; /* the current frame to grab into */
- u8 *frame_buf; /* frame buffer data */
- struct cpia_frame frame[FRAME_NUM];
- /* FRAME_NUM-buffering, so we need a array */
-
- int first_frame;
- int mmap_kludge; /* 'wrong' byte order for mmap */
- volatile u32 cmd_queue; /* queued commands */
-};
-
-/* cpia_register_camera is called by low level driver for each camera.
- * A unique camera number is returned, or a negative value on error */
-struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel);
-
-/* cpia_unregister_camera is called by low level driver when a camera
- * is removed. This must not fail. */
-void cpia_unregister_camera(struct cam_data *cam);
-
-/* raw CIF + 64 byte header + (2 bytes line_length + EOL) per line + 4*EOI +
- * one byte 16bit DMA alignment
- */
-#define CPIA_MAX_IMAGE_SIZE ((352*288*2)+64+(288*3)+5)
-
-/* constant value's */
-#define MAGIC_0 0x19
-#define MAGIC_1 0x68
-#define DATA_IN 0xC0
-#define DATA_OUT 0x40
-#define VIDEOSIZE_QCIF 0 /* 176x144 */
-#define VIDEOSIZE_CIF 1 /* 352x288 */
-#define VIDEOSIZE_SIF 2 /* 320x240 */
-#define VIDEOSIZE_QSIF 3 /* 160x120 */
-#define VIDEOSIZE_48_48 4 /* where no one has gone before, iconsize! */
-#define VIDEOSIZE_64_48 5
-#define VIDEOSIZE_128_96 6
-#define VIDEOSIZE_160_120 VIDEOSIZE_QSIF
-#define VIDEOSIZE_176_144 VIDEOSIZE_QCIF
-#define VIDEOSIZE_192_144 7
-#define VIDEOSIZE_224_168 8
-#define VIDEOSIZE_256_192 9
-#define VIDEOSIZE_288_216 10
-#define VIDEOSIZE_320_240 VIDEOSIZE_SIF
-#define VIDEOSIZE_352_288 VIDEOSIZE_CIF
-#define VIDEOSIZE_88_72 11 /* quarter CIF */
-#define SUBSAMPLE_420 0
-#define SUBSAMPLE_422 1
-#define YUVORDER_YUYV 0
-#define YUVORDER_UYVY 1
-#define NOT_COMPRESSED 0
-#define COMPRESSED 1
-#define NO_DECIMATION 0
-#define DECIMATION_ENAB 1
-#define EOI 0xff /* End Of Image */
-#define EOL 0xfd /* End Of Line */
-#define FRAME_HEADER_SIZE 64
-
-/* Image grab modes */
-#define CPIA_GRAB_SINGLE 0
-#define CPIA_GRAB_CONTINUOUS 1
-
-/* Compression parameters */
-#define CPIA_COMPRESSION_NONE 0
-#define CPIA_COMPRESSION_AUTO 1
-#define CPIA_COMPRESSION_MANUAL 2
-#define CPIA_COMPRESSION_TARGET_QUALITY 0
-#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
-
-/* Return offsets for GetCameraState */
-#define SYSTEMSTATE 0
-#define GRABSTATE 1
-#define STREAMSTATE 2
-#define FATALERROR 3
-#define CMDERROR 4
-#define DEBUGFLAGS 5
-#define VPSTATUS 6
-#define ERRORCODE 7
-
-/* SystemState */
-#define UNINITIALISED_STATE 0
-#define PASS_THROUGH_STATE 1
-#define LO_POWER_STATE 2
-#define HI_POWER_STATE 3
-#define WARM_BOOT_STATE 4
-
-/* GrabState */
-#define GRAB_IDLE 0
-#define GRAB_ACTIVE 1
-#define GRAB_DONE 2
-
-/* StreamState */
-#define STREAM_NOT_READY 0
-#define STREAM_READY 1
-#define STREAM_OPEN 2
-#define STREAM_PAUSED 3
-#define STREAM_FINISHED 4
-
-/* Fatal Error, CmdError, and DebugFlags */
-#define CPIA_FLAG 1
-#define SYSTEM_FLAG 2
-#define INT_CTRL_FLAG 4
-#define PROCESS_FLAG 8
-#define COM_FLAG 16
-#define VP_CTRL_FLAG 32
-#define CAPTURE_FLAG 64
-#define DEBUG_FLAG 128
-
-/* VPStatus */
-#define VP_STATE_OK 0x00
-
-#define VP_STATE_FAILED_VIDEOINIT 0x01
-#define VP_STATE_FAILED_AECACBINIT 0x02
-#define VP_STATE_AEC_MAX 0x04
-#define VP_STATE_ACB_BMAX 0x08
-
-#define VP_STATE_ACB_RMIN 0x10
-#define VP_STATE_ACB_GMIN 0x20
-#define VP_STATE_ACB_RMAX 0x40
-#define VP_STATE_ACB_GMAX 0x80
-
-/* ErrorCode */
-#define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */
-
-#define ALOG(lineno,fmt,args...) printk(fmt,lineno,##args)
-#define LOG(fmt,args...) ALOG((__LINE__),KERN_INFO __FILE__":"__FUNCTION__"(%d):"fmt,##args)
-
-#ifdef _CPIA_DEBUG_
-#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, lineno, ##args)
-#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):"__FUNCTION__"(%d):"fmt,##args)
-#else
-#define DBG(fmn,args...) do {} while(0)
-#endif
-
-#define DEB_BYTE(p)\
- DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
- (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
- (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
-
-#define ADD_TO_LIST(l, drv) \
- {\
- lock_kernel();\
- (drv)->next = l;\
- (drv)->previous = &(l);\
- (l) = drv;\
- unlock_kernel();\
- } while(0)
-
-#define REMOVE_FROM_LIST(drv) \
- {\
- if ((drv)->previous != NULL) {\
- lock_kernel();\
- if ((drv)->next != NULL)\
- (drv)->next->previous = (drv)->previous;\
- *((drv)->previous) = (drv)->next;\
- (drv)->previous = NULL;\
- (drv)->next = NULL;\
- unlock_kernel();\
- }\
- } while (0)
-
-
-#endif /* __KERNEL__ */
-
-#endif /* cpia_h */
diff --git a/drivers/char/cpia_pp.c b/drivers/char/cpia_pp.c
deleted file mode 100644
index 7d4be2744..000000000
--- a/drivers/char/cpia_pp.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * cpia_pp CPiA Parallel Port driver
- *
- * Supports CPiA based parallel port Video Camera's.
- *
- * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl>
- * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@mindspring.com>,
- * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com>
- *
- * 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 of the License, 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.
- */
-
-#include <linux/config.h>
-#include <linux/version.h>
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h>
-#include <linux/parport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/smp_lock.h>
-
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
-/* #define _CPIA_DEBUG_ define for verbose debug output */
-#include "cpia.h"
-
-static int cpia_pp_open(void *privdata);
-static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
- void *cbdata);
-static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
-static int cpia_pp_streamStart(void *privdata);
-static int cpia_pp_streamStop(void *privdata);
-static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
-static int cpia_pp_close(void *privdata);
-
-#define ABOUT "Parallel port driver for Vision CPiA based cameras"
-
-/* IEEE 1284 Compatiblity Mode signal names */
-#define nStrobe PARPORT_CONTROL_STROBE /* inverted */
-#define nAutoFd PARPORT_CONTROL_AUTOFD /* inverted */
-#define nInit PARPORT_CONTROL_INIT
-#define nSelectIn PARPORT_CONTROL_SELECT
-#define IntrEnable PARPORT_CONTROL_INTEN /* normally zero for no IRQ */
-#define DirBit PARPORT_CONTROL_DIRECTION /* 0 = Forward, 1 = Reverse */
-
-#define nFault PARPORT_STATUS_ERROR
-#define Select PARPORT_STATUS_SELECT
-#define PError PARPORT_STATUS_PAPEROUT
-#define nAck PARPORT_STATUS_ACK
-#define Busy PARPORT_STATUS_BUSY /* inverted */
-
-/* some more */
-#define HostClk nStrobe
-#define HostAck nAutoFd
-#define nReverseRequest nInit
-#define Active_1284 nSelectIn
-#define nPeriphRequest nFault
-#define XFlag Select
-#define nAckReverse PError
-#define PeriphClk nAck
-#define PeriphAck Busy
-
-/* these can be used to correct for the inversion on some bits */
-#define STATUS_INVERSION_MASK (Busy)
-#define CONTROL_INVERSION_MASK (nStrobe|nAutoFd|nSelectIn)
-
-#define ECR_empty 0x01
-#define ECR_full 0x02
-#define ECR_serviceIntr 0x04
-#define ECR_dmaEn 0x08
-#define ECR_nErrIntrEn 0x10
-
-#define ECR_mode_mask 0xE0
-#define ECR_SPP_mode 0x00
-#define ECR_PS2_mode 0x20
-#define ECR_FIFO_mode 0x40
-#define ECR_ECP_mode 0x60
-
-#define ECP_FIFO_SIZE 16
-#define DMA_BUFFER_SIZE PAGE_SIZE
- /* for 16bit DMA make sure DMA_BUFFER_SIZE is 16 bit aligned */
-#define PARPORT_CHUNK_SIZE PAGE_SIZE/* >=2.3.x */
- /* we read this many bytes at once */
-
-#define GetECRMasked(port,mask) (parport_read_econtrol(port) & (mask))
-#define GetStatus(port) ((parport_read_status(port)^STATUS_INVERSION_MASK)&(0xf8))
-#define SetStatus(port,val) parport_write_status(port,(val)^STATUS_INVERSION_MASK)
-#define GetControl(port) ((parport_read_control(port)^CONTROL_INVERSION_MASK)&(0x3f))
-#define SetControl(port,val) parport_write_control(port,(val)^CONTROL_INVERSION_MASK)
-
-#define GetStatusMasked(port,mask) (GetStatus(port) & (mask))
-#define GetControlMasked(port,mask) (GetControl(port) & (mask))
-#define SetControlMasked(port,mask) SetControl(port,GetControl(port) | (mask));
-#define ClearControlMasked(port,mask) SetControl(port,GetControl(port)&~(mask));
-#define FrobControlBit(port,mask,value) SetControl(port,(GetControl(port)&~(mask))|((value)&(mask)));
-
-#define PACKET_LENGTH 8
-
-/* Magic numbers for defining port-device mappings */
-#define PPCPIA_PARPORT_UNSPEC -4
-#define PPCPIA_PARPORT_AUTO -3
-#define PPCPIA_PARPORT_OFF -2
-#define PPCPIA_PARPORT_NONE -1
-
-#ifdef MODULE
-static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
-static char *parport[PARPORT_MAX] = {NULL,};
-
-MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
-MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
-MODULE_PARM(parport, "1-" __MODULE_STRING(PARPORT_MAX) "s");
-MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
-#else
-static int parport_nr[PARPORT_MAX] __initdata =
- {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
-static int parport_ptr = 0;
-#endif
-
-struct pp_cam_entry {
- struct pardevice *pdev;
- struct parport *port;
- struct tq_struct cb_task;
- int open_count;
- wait_queue_head_t wq_stream;
- /* image state flags */
- int image_ready; /* we got an interrupt */
- int image_complete; /* we have seen 4 EOI */
-
- int streaming; /* we are in streaming mode */
- int stream_irq;
-};
-
-static struct cpia_camera_ops cpia_pp_ops =
-{
- cpia_pp_open,
- cpia_pp_registerCallback,
- cpia_pp_transferCmd,
- cpia_pp_streamStart,
- cpia_pp_streamStop,
- cpia_pp_streamRead,
- cpia_pp_close,
- 1
-};
-
-static struct cam_data *cam_list;
-
-#ifdef _CPIA_DEBUG_
-#define DEB_PORT(port) { \
-u8 controll = GetControl(port); \
-u8 statusss = GetStatus(port); \
-DBG("nsel %c per %c naut %c nstrob %c nak %c busy %c nfaul %c sel %c init %c dir %c\n",\
-((controll & nSelectIn) ? 'U' : 'D'), \
-((statusss & PError) ? 'U' : 'D'), \
-((controll & nAutoFd) ? 'U' : 'D'), \
-((controll & nStrobe) ? 'U' : 'D'), \
-((statusss & nAck) ? 'U' : 'D'), \
-((statusss & Busy) ? 'U' : 'D'), \
-((statusss & nFault) ? 'U' : 'D'), \
-((statusss & Select) ? 'U' : 'D'), \
-((controll & nInit) ? 'U' : 'D'), \
-((controll & DirBit) ? 'R' : 'F') \
-); }
-#else
-#define DEB_PORT(port) {}
-#endif
-
-#define WHILE_OUT_TIMEOUT (HZ/10)
-#define DMA_TIMEOUT 10*HZ
-
-/* FIXME */
-static void cpia_parport_enable_irq( struct parport *port ) {
- parport_enable_irq(port);
- mdelay(10);
- return;
-}
-
-static void cpia_parport_disable_irq( struct parport *port ) {
- parport_disable_irq(port);
- mdelay(10);
- return;
-}
-
-/****************************************************************************
- *
- * EndTransferMode
- *
- ***************************************************************************/
-static void EndTransferMode(struct pp_cam_entry *cam)
-{
- parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
-}
-
-/****************************************************************************
- *
- * ForwardSetup
- *
- ***************************************************************************/
-static int ForwardSetup(struct pp_cam_entry *cam)
-{
- int retry;
-
- /* After some commands the camera needs extra time before
- * it will respond again, so we try up to 3 times */
- for(retry=0; retry<3; ++retry) {
- if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
- break;
- }
- }
- if(retry == 3) {
- DBG("Unable to negotiate ECP mode\n");
- return -1;
- }
- return 0;
-}
-
-/****************************************************************************
- *
- * ReverseSetup
- *
- ***************************************************************************/
-static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
-{
- int retry;
- int mode = IEEE1284_MODE_ECP;
- if(extensibility) mode = 8|3|IEEE1284_EXT_LINK;
-
- /* After some commands the camera needs extra time before
- * it will respond again, so we try up to 3 times */
- for(retry=0; retry<3; ++retry) {
- if(!parport_negotiate(cam->port, mode)) {
- break;
- }
- }
- if(retry == 3) {
- if(extensibility)
- DBG("Unable to negotiate extensibility mode\n");
- else
- DBG("Unable to negotiate ECP mode\n");
- return -1;
- }
- if(extensibility) cam->port->ieee1284.mode = IEEE1284_MODE_ECP;
- return 0;
-}
-
-/****************************************************************************
- *
- * WritePacket
- *
- ***************************************************************************/
-static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
-{
- int retval=0;
- int size_written;
-
- if (packet == NULL) {
- return -EINVAL;
- }
- if (ForwardSetup(cam)) {
- DBG("Write failed in setup\n");
- return -EIO;
- }
- size_written = parport_write(cam->port, packet, size);
- if(size_written != size) {
- DBG("Write failed, wrote %d/%d\n", size_written, size);
- retval = -EIO;
- }
- EndTransferMode(cam);
- return retval;
-}
-
-/****************************************************************************
- *
- * ReadPacket
- *
- ***************************************************************************/
-static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
-{
- int retval=0;
- if (packet == NULL) {
- return -EINVAL;
- }
- if (ReverseSetup(cam, 0)) {
- return -EIO;
- }
- if(parport_read(cam->port, packet, size) != size) {
- retval = -EIO;
- }
- EndTransferMode(cam);
- return retval;
-}
-
-/****************************************************************************
- *
- * cpia_pp_streamStart
- *
- ***************************************************************************/
-static int cpia_pp_streamStart(void *privdata)
-{
- struct pp_cam_entry *cam = privdata;
- DBG("\n");
- cam->streaming=1;
- cam->image_ready=0;
- //if (ReverseSetup(cam,1)) return -EIO;
- if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
- return 0;
-}
-
-/****************************************************************************
- *
- * cpia_pp_streamStop
- *
- ***************************************************************************/
-static int cpia_pp_streamStop(void *privdata)
-{
- struct pp_cam_entry *cam = privdata;
-
- DBG("\n");
- cam->streaming=0;
- cpia_parport_disable_irq(cam->port);
- //EndTransferMode(cam);
-
- return 0;
-}
-
-static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
-{
- int bytes_read, new_bytes;
- for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
- new_bytes = parport_read(port, buffer+bytes_read,
- len-bytes_read);
- if(new_bytes < 0) break;
- }
- return bytes_read;
-}
-
-/****************************************************************************
- *
- * cpia_pp_streamRead
- *
- ***************************************************************************/
-static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
-{
- struct pp_cam_entry *cam = privdata;
- int read_bytes = 0;
- int i, endseen, block_size, new_bytes;
-
- if(cam == NULL) {
- DBG("Internal driver error: cam is NULL\n");
- return -EINVAL;
- }
- if(buffer == NULL) {
- DBG("Internal driver error: buffer is NULL\n");
- return -EINVAL;
- }
- //if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
- if( cam->stream_irq ) {
- DBG("%d\n", cam->image_ready);
- cam->image_ready--;
- }
- cam->image_complete=0;
- if (0/*cam->streaming*/) {
- if(!cam->image_ready) {
- if(noblock) return -EWOULDBLOCK;
- interruptible_sleep_on(&cam->wq_stream);
- if( signal_pending(current) ) return -EINTR;
- DBG("%d\n", cam->image_ready);
- }
- } else {
- if (ReverseSetup(cam, 1)) {
- DBG("unable to ReverseSetup\n");
- return -EIO;
- }
- }
- endseen = 0;
- block_size = PARPORT_CHUNK_SIZE;
- while( !cam->image_complete ) {
- if(current->need_resched) schedule();
-
- new_bytes = cpia_pp_read(cam->port, buffer, block_size );
- if( new_bytes <= 0 ) {
- break;
- }
- i=-1;
- while(++i<new_bytes && endseen<4) {
- if(*buffer==EOI) {
- endseen++;
- } else {
- endseen=0;
- }
- buffer++;
- }
- read_bytes += i;
- if( endseen==4 ) {
- cam->image_complete=1;
- break;
- }
- if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
- block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
- }
- }
- EndTransferMode(cam);
- return cam->image_complete ? read_bytes : -EIO;
-}
-
-/****************************************************************************
- *
- * cpia_pp_transferCmd
- *
- ***************************************************************************/
-static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
-{
- int err;
- int retval=0;
- int databytes;
- struct pp_cam_entry *cam = privdata;
-
- if(cam == NULL) {
- DBG("Internal driver error: cam is NULL\n");
- return -EINVAL;
- }
- if(command == NULL) {
- DBG("Internal driver error: command is NULL\n");
- return -EINVAL;
- }
- databytes = (((int)command[7])<<8) | command[6];
- if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
- DBG("Error writing command\n");
- return err;
- }
- if(command[0] == DATA_IN) {
- u8 buffer[8];
- if(data == NULL) {
- DBG("Internal driver error: data is NULL\n");
- return -EINVAL;
- }
- if((err = ReadPacket(cam, buffer, 8)) < 0) {
- return err;
- DBG("Error reading command result\n");
- }
- memcpy(data, buffer, databytes);
- } else if(command[0] == DATA_OUT) {
- if(databytes > 0) {
- if(data == NULL) {
- DBG("Internal driver error: data is NULL\n");
- retval = -EINVAL;
- } else {
- if((err=WritePacket(cam, data, databytes)) < 0){
- DBG("Error writing command data\n");
- return err;
- }
- }
- }
- } else {
- DBG("Unexpected first byte of command: %x\n", command[0]);
- retval = -EINVAL;
- }
- return retval;
-}
-
-/****************************************************************************
- *
- * cpia_pp_open
- *
- ***************************************************************************/
-static int cpia_pp_open(void *privdata)
-{
- struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
-
- if (cam == NULL)
- return -EINVAL;
-
- if(cam->open_count == 0) {
- if (parport_claim(cam->pdev)) {
- DBG("failed to claim the port\n");
- return -EBUSY;
- }
- parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
- parport_data_forward(cam->port);
- parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
- udelay(50);
- parport_write_control(cam->port,
- PARPORT_CONTROL_SELECT
- | PARPORT_CONTROL_INIT);
- }
-
- ++cam->open_count;
-
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
- return 0;
-}
-
-/****************************************************************************
- *
- * cpia_pp_registerCallback
- *
- ***************************************************************************/
-static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
-{
- struct pp_cam_entry *cam = privdata;
- int retval = 0;
-
- if(cam->port->irq != PARPORT_IRQ_NONE) {
- cam->cb_task.routine = cb;
- cam->cb_task.data = cbdata;
- } else {
- retval = -1;
- }
- return retval;
-}
-
-/****************************************************************************
- *
- * cpia_pp_close
- *
- ***************************************************************************/
-static int cpia_pp_close(void *privdata)
-{
- struct pp_cam_entry *cam = privdata;
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
- if (--cam->open_count == 0) {
- parport_release(cam->pdev);
- }
- return 0;
-}
-
-/****************************************************************************
- *
- * cpia_pp_register
- *
- ***************************************************************************/
-static int cpia_pp_register(struct parport *port)
-{
- struct pardevice *pdev = NULL;
- struct pp_cam_entry *cam;
- struct cam_data *cpia;
-
- if (!(port->modes & PARPORT_MODE_ECP) &&
- !(port->modes & PARPORT_MODE_TRISTATE)) {
- LOG("port is not ECP capable\n");
- return -ENXIO;
- }
-
- cam = kmalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
- if (cam == NULL) {
- LOG("failed to allocate camera structure\n");
- return -ENOMEM;
- }
- memset(cam,0,sizeof(struct pp_cam_entry));
-
- pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
- NULL, 0, cam);
-
- if (!pdev) {
- LOG("failed to parport_register_device\n");
- kfree(cam);
- return -ENXIO;
- }
-
- cam->pdev = pdev;
- cam->port = port;
- init_waitqueue_head(&cam->wq_stream);
-
- cam->streaming = 0;
- cam->stream_irq = 0;
-
- if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
- LOG("failed to cpia_register_camera\n");
- parport_unregister_device(pdev);
- kfree(cam);
- return -ENXIO;
- }
- ADD_TO_LIST(cam_list, cpia);
-
- return 0;
-}
-
-static void cpia_pp_detach (struct parport *port)
-{
- struct cam_data *cpia;
-
- for(cpia = cam_list; cpia != NULL; cpia = cpia->next) {
- struct pp_cam_entry *cam = cpia->lowlevel_data;
- if (cam && cam->port->number == port->number) {
- REMOVE_FROM_LIST(cpia);
-
- cpia_unregister_camera(cpia);
-
- if(cam->open_count > 0) {
- cpia_pp_close(cam);
- }
-
- parport_unregister_device(cam->pdev);
-
- kfree(cam);
- cpia->lowlevel_data = NULL;
- break;
- }
- }
-}
-
-static void cpia_pp_attach (struct parport *port)
-{
- unsigned int i;
-
- switch (parport_nr[0])
- {
- case PPCPIA_PARPORT_UNSPEC:
- case PPCPIA_PARPORT_AUTO:
- if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
- port->probe_info[0].cmdset == NULL ||
- strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
- return;
-
- cpia_pp_register(port);
-
- break;
-
- default:
- for (i = 0; i < PARPORT_MAX; ++i) {
- if (port->number == parport_nr[i]) {
- cpia_pp_register(port);
- break;
- }
- }
- break;
- }
-}
-
-static struct parport_driver cpia_pp_driver = {
- "cpia_pp",
- cpia_pp_attach,
- cpia_pp_detach,
- NULL
-};
-
-int cpia_pp_init(void)
-{
- printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
- CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
-
- if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
- printk(" disabled\n");
- return 0;
- }
-
- if (parport_register_driver (&cpia_pp_driver)) {
- LOG ("unable to register with parport\n");
- return -EIO;
- }
-
- return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
- if (parport[0]) {
- /* The user gave some parameters. Let's see what they were. */
- if (!strncmp(parport[0], "auto", 4)) {
- parport_nr[0] = PPCPIA_PARPORT_AUTO;
- } else {
- int n;
- for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
- if (!strncmp(parport[n], "none", 4)) {
- parport_nr[n] = PPCPIA_PARPORT_NONE;
- } else {
- char *ep;
- unsigned long r = simple_strtoul(parport[n], &ep, 0);
- if (ep != parport[n]) {
- parport_nr[n] = r;
- } else {
- LOG("bad port specifier `%s'\n", parport[n]);
- return -ENODEV;
- }
- }
- }
- }
- }
-#if defined(CONFIG_KMOD) && defined(CONFIG_PNP_PARPORT_MODULE)
- if(parport_enumerate() && !parport_enumerate()->probe_info.model) {
- request_module("parport_probe");
- }
-#endif
- return cpia_pp_init();
-}
-
-void cleanup_module(void)
-{
- parport_unregister_driver (&cpia_pp_driver);
- return;
-}
-
-#else /* !MODULE */
-
-static int __init cpia_pp_setup(char *str)
-{
-#if 0
- /* Is this only a 2.2ism? -jerdfelt */
- if (!str) {
- if (ints[0] == 0 || ints[1] == 0) {
- /* disable driver on "cpia_pp=" or "cpia_pp=0" */
- parport_nr[0] = PPCPIA_PARPORT_OFF;
- }
- } else
-#endif
- if (!strncmp(str, "parport", 7)) {
- int n = simple_strtoul(str + 7, NULL, 10);
- if (parport_ptr < PARPORT_MAX) {
- parport_nr[parport_ptr++] = n;
- } else {
- LOG("too many ports, %s ignored.\n", str);
- }
- } else if (!strcmp(str, "auto")) {
- parport_nr[0] = PPCPIA_PARPORT_AUTO;
- } else if (!strcmp(str, "none")) {
- parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
- }
-
- return 0;
-}
-
-__setup("cpia_pp=", cpia_pp_setup);
-
-#endif /* !MODULE */
diff --git a/drivers/char/cpia_usb.c b/drivers/char/cpia_usb.c
deleted file mode 100644
index 6b67fbc81..000000000
--- a/drivers/char/cpia_usb.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * cpia_usb CPiA USB driver
- *
- * Supports CPiA based parallel port Video Camera's.
- *
- * Copyright (C) 1999 Jochen Scharrlach <Jochen.Scharrlach@schwaben.de>
- * Copyright (C) 1999, 2000 Johannes Erdfelt <jerdfelt@valinux.com>
- *
- * 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 of the License, 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.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/usb.h>
-
-#include "cpia.h"
-
-#define USB_REQ_CPIA_GRAB_FRAME 0xC1
-#define USB_REQ_CPIA_UPLOAD_FRAME 0xC2
-#define WAIT_FOR_NEXT_FRAME 0
-#define FORCE_FRAME_UPLOAD 1
-
-#define FRAMES_PER_DESC 10
-#define FRAME_SIZE_PER_DESC 960 /* Shouldn't be hardcoded */
-#define CPIA_NUMSBUF 2
-#define STREAM_BUF_SIZE (PAGE_SIZE * 4)
-#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2)
-
-struct cpia_sbuf {
- char *data;
- urb_t *urb;
-};
-
-#define FRAMEBUF_LEN (CPIA_MAX_FRAME_SIZE+100)
-enum framebuf_status {
- FRAME_EMPTY,
- FRAME_READING,
- FRAME_READY,
- FRAME_ERROR,
-};
-
-struct framebuf {
- int length;
- enum framebuf_status status;
- u8 data[FRAMEBUF_LEN];
- struct framebuf *next;
-};
-
-struct usb_cpia {
- /* Device structure */
- struct usb_device *dev;
-
- unsigned char iface;
- wait_queue_head_t wq_stream;
-
- int cursbuf; /* Current receiving sbuf */
- struct cpia_sbuf sbuf[CPIA_NUMSBUF]; /* Double buffering */
-
- int streaming;
- int open;
- int present;
- struct framebuf *buffers[3];
- struct framebuf *curbuff, *workbuff;
-};
-
-static int cpia_usb_open(void *privdata);
-static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
- void *cbdata);
-static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data);
-static int cpia_usb_streamStart(void *privdata);
-static int cpia_usb_streamStop(void *privdata);
-static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock);
-static int cpia_usb_close(void *privdata);
-
-#define ABOUT "USB driver for Vision CPiA based cameras"
-
-static struct cpia_camera_ops cpia_usb_ops = {
- cpia_usb_open,
- cpia_usb_registerCallback,
- cpia_usb_transferCmd,
- cpia_usb_streamStart,
- cpia_usb_streamStop,
- cpia_usb_streamRead,
- cpia_usb_close,
- 0
-};
-
-static struct cam_data *cam_list;
-
-static void cpia_usb_complete(struct urb *urb)
-{
- int i;
- char *cdata;
- struct usb_cpia *ucpia;
-
- if (!urb || !urb->context)
- return;
-
- ucpia = (struct usb_cpia *) urb->context;
-
- if (!ucpia->dev || !ucpia->streaming || !ucpia->present || !ucpia->open)
- return;
-
- if (ucpia->workbuff->status == FRAME_EMPTY) {
- ucpia->workbuff->status = FRAME_READING;
- ucpia->workbuff->length = 0;
- }
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int n = urb->iso_frame_desc[i].actual_length;
- int st = urb->iso_frame_desc[i].status;
-
- cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- if (st)
- printk(KERN_DEBUG "cpia data error: [%d] len=%d, status=%X\n", i, n, st);
-
- if (FRAMEBUF_LEN < ucpia->workbuff->length + n) {
- printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n", ucpia->workbuff->length, n);
- return;
- }
-
- if (n) {
- if ((ucpia->workbuff->length > 0) ||
- (0x19 == cdata[0] && 0x68 == cdata[1])) {
- memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, n);
- ucpia->workbuff->length += n;
- } else
- DBG("Ignoring packet!\n");
- } else {
- if (ucpia->workbuff->length > 4 &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-1] &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-2] &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-3] &&
- 0xff == ucpia->workbuff->data[ucpia->workbuff->length-4]) {
- ucpia->workbuff->status = FRAME_READY;
- ucpia->curbuff = ucpia->workbuff;
- ucpia->workbuff = ucpia->workbuff->next;
- ucpia->workbuff->status = FRAME_EMPTY;
- ucpia->workbuff->length = 0;
-
- if (waitqueue_active(&ucpia->wq_stream))
- wake_up_interruptible(&ucpia->wq_stream);
- }
- }
- }
-}
-
-static int cpia_usb_open(void *privdata)
-{
- struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
- urb_t *urb;
- int ret, retval = 0, fx, err;
-
- if (!ucpia)
- return -EINVAL;
-
- ucpia->sbuf[0].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!ucpia->sbuf[0].data)
- return -EINVAL;
-
- ucpia->sbuf[1].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!ucpia->sbuf[1].data) {
- retval = -EINVAL;
- goto error_0;
- }
-
- ret = usb_set_interface(ucpia->dev, ucpia->iface, 3);
- if (ret < 0) {
- printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
- retval = -EBUSY;
- goto error_all;
- }
-
- ucpia->buffers[0]->status = FRAME_EMPTY;
- ucpia->buffers[0]->length = 0;
- ucpia->buffers[1]->status = FRAME_EMPTY;
- ucpia->buffers[1]->length = 0;
- ucpia->buffers[2]->status = FRAME_EMPTY;
- ucpia->buffers[2]->length = 0;
- ucpia->curbuff = ucpia->buffers[0];
- ucpia->workbuff = ucpia->buffers[1];
-
- /* We double buffer the Iso lists */
- urb = usb_alloc_urb(FRAMES_PER_DESC);
- if (!urb) {
- printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n");
- retval = -ENOMEM;
- goto error_all;
- }
-
- ucpia->sbuf[0].urb = urb;
- urb->dev = ucpia->dev;
- urb->context = ucpia;
- urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
- urb->transfer_flags = USB_ISO_ASAP;
- urb->transfer_buffer = ucpia->sbuf[0].data;
- urb->complete = cpia_usb_complete;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
- for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
- urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
- }
-
- urb = usb_alloc_urb(FRAMES_PER_DESC);
- if (!urb) {
- printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n");
- retval = -ENOMEM;
- goto error_all;
- }
-
- ucpia->sbuf[1].urb = urb;
- urb->dev = ucpia->dev;
- urb->context = ucpia;
- urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
- urb->transfer_flags = USB_ISO_ASAP;
- urb->transfer_buffer = ucpia->sbuf[1].data;
- urb->complete = cpia_usb_complete;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
- for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
- urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
- }
-
- ucpia->sbuf[1].urb->next = ucpia->sbuf[0].urb;
- ucpia->sbuf[0].urb->next = ucpia->sbuf[1].urb;
-
- err = usb_submit_urb(ucpia->sbuf[0].urb);
- if (err)
- printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n",
- err);
- err = usb_submit_urb(ucpia->sbuf[1].urb);
- if (err)
- printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n",
- err);
-
- ucpia->streaming = 1;
- ucpia->open = 1;
-
- return 0;
-
-error_all:
- kfree (ucpia->sbuf[1].data);
-error_0:
- kfree (ucpia->sbuf[0].data);
-
- return retval;
-}
-
-//
-// convenience functions
-//
-
-/****************************************************************************
- *
- * WritePacket
- *
- ***************************************************************************/
-static int WritePacket(struct usb_device *udev, const u8 *packet, u8 *buf, size_t size)
-{
- if (!packet)
- return -EINVAL;
-
- return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- packet[1] + (packet[0] << 8),
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- packet[2] + (packet[3] << 8),
- packet[4] + (packet[5] << 8), buf, size, HZ);
-}
-
-/****************************************************************************
- *
- * ReadPacket
- *
- ***************************************************************************/
-static int ReadPacket(struct usb_device *udev, u8 *packet, u8 *buf, size_t size)
-{
- if (!packet || size <= 0)
- return -EINVAL;
-
- return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- packet[1] + (packet[0] << 8),
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- packet[2] + (packet[3] << 8),
- packet[4] + (packet[5] << 8), buf, size, HZ);
-}
-
-static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data)
-{
- int err = 0;
- int databytes;
- struct usb_cpia *ucpia = (struct usb_cpia *)privdata;
- struct usb_device *udev = ucpia->dev;
-
- if (!udev) {
- DBG("Internal driver error: udev is NULL\n");
- return -EINVAL;
- }
-
- if (!command) {
- DBG("Internal driver error: command is NULL\n");
- return -EINVAL;
- }
-
- databytes = (((int)command[7])<<8) | command[6];
-
- if (command[0] == DATA_IN) {
- u8 buffer[8];
-
- if (!data) {
- DBG("Internal driver error: data is NULL\n");
- return -EINVAL;
- }
-
- err = ReadPacket(udev, command, buffer, 8);
- if (err < 0)
- return err;
-
- memcpy(data, buffer, databytes);
- } else if(command[0] == DATA_OUT)
- WritePacket(udev, command, data, databytes);
- else {
- DBG("Unexpected first byte of command: %x\n", command[0]);
- err = -EINVAL;
- }
-
- return 0;
-}
-
-static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
- void *cbdata)
-{
- return -ENODEV;
-}
-
-static int cpia_usb_streamStart(void *privdata)
-{
- return -ENODEV;
-}
-
-static int cpia_usb_streamStop(void *privdata)
-{
- return -ENODEV;
-}
-
-static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
-{
- struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
- struct framebuf *mybuff;
-
- if (!ucpia || !ucpia->present)
- return -1;
-
- if (ucpia->curbuff->status != FRAME_READY)
- interruptible_sleep_on(&ucpia->wq_stream);
- else
- DBG("Frame already waiting!\n");
-
- mybuff = ucpia->curbuff;
-
- if (!mybuff)
- return -1;
-
- if (mybuff->status != FRAME_READY || mybuff->length < 4) {
- DBG("Something went wrong!\n");
- return -1;
- }
-
- memcpy(frame, mybuff->data, mybuff->length);
- mybuff->status = FRAME_EMPTY;
-
-/* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */
-/* mybuff->length, frame[0], frame[1], */
-/* frame[mybuff->length-4], frame[mybuff->length-3], */
-/* frame[mybuff->length-2], frame[mybuff->length-1]); */
-
- return mybuff->length;
-}
-
-static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try)
-{
- if (!ucpia->streaming)
- return;
-
- ucpia->streaming = 0;
-
- /* Set packet size to 0 */
- if (try) {
- int ret;
-
- ret = usb_set_interface(ucpia->dev, ucpia->iface, 0);
- if (ret < 0) {
- printk(KERN_ERR "usb_set_interface error (ret = %d)\n", ret);
- return;
- }
- }
-
- /* Unschedule all of the iso td's */
- if (ucpia->sbuf[1].urb) {
- usb_unlink_urb(ucpia->sbuf[1].urb);
- usb_free_urb(ucpia->sbuf[1].urb);
- ucpia->sbuf[1].urb = NULL;
- }
-
- if (ucpia->sbuf[0].urb) {
- usb_unlink_urb(ucpia->sbuf[0].urb);
- usb_free_urb(ucpia->sbuf[0].urb);
- ucpia->sbuf[0].urb = NULL;
- }
-}
-
-static int cpia_usb_close(void *privdata)
-{
- struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
-
- ucpia->open = 0;
-
- cpia_usb_free_resources(ucpia, 1);
-
- if (!ucpia->present)
- kfree(ucpia);
-
- return 0;
-}
-
-int cpia_usb_init(void)
-{
- /* return -ENODEV; */
- return 0;
-}
-
-/* Probing and initializing */
-
-static void *cpia_probe(struct usb_device *udev, unsigned int ifnum)
-{
- struct usb_interface_descriptor *interface;
- struct usb_cpia *ucpia;
- struct cam_data *cam;
- int ret;
-
- /* A multi-config CPiA camera? */
- if (udev->descriptor.bNumConfigurations != 1)
- return NULL;
-
- interface = &udev->actconfig->interface[ifnum].altsetting[0];
-
- /* Is it a CPiA? */
- if (udev->descriptor.idVendor != 0x0553)
- return NULL;
- if (udev->descriptor.idProduct != 0x0002)
- return NULL;
-
- /* We found a CPiA */
- printk(KERN_INFO "USB CPiA camera found\n");
-
- ucpia = kmalloc(sizeof(*ucpia), GFP_KERNEL);
- if (!ucpia) {
- printk(KERN_ERR "couldn't kmalloc cpia struct\n");
- return NULL;
- }
-
- memset(ucpia, 0, sizeof(*ucpia));
-
- ucpia->dev = udev;
- ucpia->iface = interface->bInterfaceNumber;
- init_waitqueue_head(&ucpia->wq_stream);
-
- ucpia->buffers[0] = vmalloc(sizeof(*ucpia->buffers[0]));
- if (!ucpia->buffers[0]) {
- printk(KERN_ERR "couldn't vmalloc frame buffer 0\n");
- goto fail_alloc_0;
- }
-
- ucpia->buffers[1] = vmalloc(sizeof(*ucpia->buffers[1]));
- if (!ucpia->buffers[1]) {
- printk(KERN_ERR "couldn't vmalloc frame buffer 1\n");
- goto fail_alloc_1;
- }
-
- ucpia->buffers[2] = vmalloc(sizeof(*ucpia->buffers[2]));
- if (!ucpia->buffers[2]) {
- printk(KERN_ERR "couldn't vmalloc frame buffer 2\n");
- goto fail_alloc_2;
- }
-
- ucpia->buffers[0]->next = ucpia->buffers[1];
- ucpia->buffers[1]->next = ucpia->buffers[2];
- ucpia->buffers[2]->next = ucpia->buffers[0];
-
- ret = usb_set_interface(udev, ucpia->iface, 0);
- if (ret < 0) {
- printk(KERN_ERR "cpia_probe: usb_set_interface error (ret = %d)\n", ret);
- /* goto fail_all; */
- }
-
- /* Before register_camera, important */
- ucpia->present = 1;
-
- cam = cpia_register_camera(&cpia_usb_ops, ucpia);
- if (!cam) {
- LOG("failed to cpia_register_camera\n");
- goto fail_all;
- }
-
- ADD_TO_LIST(cam_list, cam);
-
- return cam;
-
-fail_all:
- vfree(ucpia->buffers[2]);
- ucpia->buffers[2] = NULL;
-fail_alloc_2:
- vfree(ucpia->buffers[1]);
- ucpia->buffers[1] = NULL;
-fail_alloc_1:
- vfree(ucpia->buffers[0]);
- ucpia->buffers[0] = NULL;
-fail_alloc_0:
-
- return NULL;
-}
-
-static void cpia_disconnect(struct usb_device *dev, void *ptr);
-
-static struct usb_driver cpia_driver = {
- "cpia",
- cpia_probe,
- cpia_disconnect,
- { NULL, NULL }
-};
-
-/* don't use dev, it may be NULL! (see usb_cpia_cleanup) */
-/* _disconnect from usb_cpia_cleanup is not necessary since usb_deregister */
-/* will do it for us as well as passing a udev structure - jerdfelt */
-static void cpia_disconnect(struct usb_device *udev, void *ptr)
-{
- struct cam_data *cam = (struct cam_data *) ptr;
- struct usb_cpia *ucpia = (struct usb_cpia *) cam->lowlevel_data;
-
- REMOVE_FROM_LIST(cam);
-
- /* Don't even try to reset the altsetting if we're disconnected */
- cpia_usb_free_resources(ucpia, 0);
-
- ucpia->present = 0;
-
- cpia_unregister_camera(cam);
-
- ucpia->curbuff->status = FRAME_ERROR;
-
- if (waitqueue_active(&ucpia->wq_stream))
- wake_up_interruptible(&ucpia->wq_stream);
-
- usb_driver_release_interface(&cpia_driver,
- &udev->actconfig->interface[0]);
-
- ucpia->curbuff = ucpia->workbuff = NULL;
-
- if (ucpia->buffers[2]) {
- vfree(ucpia->buffers[2]);
- ucpia->buffers[2] = NULL;
- }
-
- if (ucpia->buffers[1]) {
- vfree(ucpia->buffers[1]);
- ucpia->buffers[1] = NULL;
- }
-
- if (ucpia->buffers[0]) {
- vfree(ucpia->buffers[0]);
- ucpia->buffers[0] = NULL;
- }
-
- if (!ucpia->open)
- kfree(ucpia);
-}
-
-int usb_cpia_init(void)
-{
- cam_list = NULL;
-
- return usb_register(&cpia_driver);
-}
-
-void usb_cpia_cleanup(void)
-{
-/*
- struct cam_data *cam;
-
- while ((cam = cam_list) != NULL)
- cpia_disconnect(NULL, cam);
-*/
-
- usb_deregister(&cpia_driver);
-}
-
-#ifdef MODULE
-int init_module(void)
-{
- return usb_cpia_init();
-}
-
-void cleanup_module(void)
-{
- usb_cpia_cleanup();
-}
-#endif /* !MODULE */
diff --git a/drivers/char/cs8420.h b/drivers/char/cs8420.h
deleted file mode 100644
index 2b22f3a38..000000000
--- a/drivers/char/cs8420.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* cs8420.h - cs8420 initializations
- Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
-
- 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 of the License, 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.
-
- */
-#ifndef __CS8420_H__
-#define __CS8420_H__
-
-/* Initialization Sequence */
-
-static __u8 init8420[] = {
- 1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46,
- 5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13,
-};
-
-#define INIT8420LEN (sizeof(init8420)/2)
-
-static __u8 mode8420pro[] = { /* professional output mode */
- 32, 0xa1, 33, 0x00, 34, 0x00, 35, 0x00,
- 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
- 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
- 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
- 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
- 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
-};
-#define MODE8420LEN (sizeof(mode8420pro)/2)
-
-static __u8 mode8420con[] = { /* consumer output mode */
- 32, 0x20, 33, 0x00, 34, 0x00, 35, 0x48,
- 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
- 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
- 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
- 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
- 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
-};
-
-#endif
diff --git a/drivers/char/drm/agpsupport.c b/drivers/char/drm/agpsupport.c
index 7ed234e15..42a1bc2f6 100644
--- a/drivers/char/drm/agpsupport.c
+++ b/drivers/char/drm/agpsupport.c
@@ -309,7 +309,9 @@ drm_agp_head_t *drm_agp_init(void)
#if LINUX_VERSION_CODE >= 0x020400
case VIA_MVP4: head->chipset = "VIA MVP4"; break;
- case VIA_APOLLO_SUPER: head->chipset = "VIA Apollo Super";
+ case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133";
+ break;
+ case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133";
break;
#endif
@@ -322,7 +324,7 @@ drm_agp_head_t *drm_agp_init(void)
case ALI_M1541: head->chipset = "ALi M1541"; break;
default: head->chipset = "Unknown"; break;
}
- DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
+ DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
head->agp_info.version.major,
head->agp_info.version.minor,
head->chipset,
diff --git a/drivers/char/drm/auth.c b/drivers/char/drm/auth.c
index 9f81c5391..4556bd966 100644
--- a/drivers/char/drm/auth.c
+++ b/drivers/char/drm/auth.c
@@ -126,12 +126,12 @@ int drm_getmagic(struct inode *inode, struct file *filp, unsigned int cmd,
if (priv->magic) {
auth.magic = priv->magic;
} else {
- spin_lock(&lock);
do {
+ spin_lock(&lock);
if (!sequence) ++sequence; /* reserve 0 */
auth.magic = sequence++;
+ spin_unlock(&lock);
} while (drm_find_file(dev, auth.magic));
- spin_unlock(&lock);
priv->magic = auth.magic;
drm_add_magic(dev, priv, auth.magic);
}
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 0fa205717..e8ec9bdbc 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -328,6 +328,7 @@ typedef struct drm_freelist {
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
atomic_t wfh; /* If waiting for high mark */
+ spinlock_t lock;
} drm_freelist_t;
typedef struct drm_buf_entry {
@@ -450,6 +451,11 @@ typedef struct {
extern drm_agp_func_t drm_agp;
#endif
+typedef struct drm_sigdata {
+ int context;
+ drm_hw_lock_t *lock;
+} drm_sigdata_t;
+
typedef struct drm_device {
const char *name; /* Simple driver name */
char *unique; /* Unique identifier: e.g., busid */
@@ -534,6 +540,8 @@ typedef struct drm_device {
#endif
unsigned long *ctx_bitmap;
void *dev_private;
+ drm_sigdata_t sigdata; /* For block_all_signals */
+ sigset_t sigmask;
} drm_device_t;
@@ -728,6 +736,7 @@ extern int drm_flush_unblock(drm_device_t *dev, int context,
drm_lock_flags_t flags);
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,
drm_lock_flags_t flags);
+extern int drm_notifier(void *priv);
/* Context Bitmap support (ctxbitmap.c) */
extern int drm_ctxbitmap_init(drm_device_t *dev);
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index d81685230..84c7f0644 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -1,4 +1,4 @@
-/* $Id: ffb_drv.c,v 1.5 2000/07/26 01:03:57 davem Exp $
+/* $Id: ffb_drv.c,v 1.6 2000/08/10 05:26:23 davem Exp $
* ffb_drv.c: Creator/Creator3D direct rendering driver.
*
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
@@ -754,6 +754,7 @@ static void align_shm_mapping(struct vm_area_struct *vma, unsigned long kvirt)
extern struct vm_operations_struct drm_vm_ops;
extern struct vm_operations_struct drm_vm_shm_ops;
+extern struct vm_operations_struct drm_vm_shm_lock_ops;
static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
{
@@ -766,7 +767,6 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
- lock_kernel();
minor = MINOR(filp->f_dentry->d_inode->i_rdev);
ffb_priv = NULL;
for (i = 0; i < ffb_dev_table_size; i++) {
@@ -774,15 +774,13 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
if (ffb_priv->miscdev.minor == minor)
break;
}
- if (i >= ffb_dev_table_size) {
- unlock_kernel();
+ if (i >= ffb_dev_table_size)
return -EINVAL;
- }
+
/* We don't support/need dma mappings, so... */
- if (!VM_OFFSET(vma)) {
- unlock_kernel();
+ if (!VM_OFFSET(vma))
return -EINVAL;
- }
+
for (i = 0; i < dev->map_count; i++) {
unsigned long off;
@@ -794,19 +792,16 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
break;
}
- if (i >= dev->map_count) {
- unlock_kernel();
+ if (i >= dev->map_count)
return -EINVAL;
- }
+
if (!map ||
- ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) {
- unlock_kernel();
+ ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
- }
- if (map->size != (vma->vm_end - vma->vm_start)) {
- unlock_kernel();
+
+ if (map->size != (vma->vm_end - vma->vm_start))
return -EINVAL;
- }
+
/* Set read-only attribute before mappings are created
* so it works for fb/reg maps too.
*/
@@ -829,15 +824,19 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
if (io_remap_page_range(vma->vm_start,
ffb_priv->card_phys_base + VM_OFFSET(vma),
vma->vm_end - vma->vm_start,
- vma->vm_page_prot, 0)) {
- unlock_kernel();
+ vma->vm_page_prot, 0))
return -EAGAIN;
- }
+
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
align_shm_mapping(vma, (unsigned long)dev->lock.hw_lock);
- vma->vm_ops = &drm_vm_shm_ops;
+ if (map->flags & _DRM_CONTAINS_LOCK)
+ vma->vm_ops = &drm_vm_shm_lock_ops;
+ else {
+ vma->vm_ops = &drm_vm_shm_ops;
+ vma->vm_private_data = (void *) map;
+ }
/* Don't let this area swap. Change when
* DRM_KERNEL advisory is supported.
@@ -845,10 +844,8 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_LOCKED;
break;
default:
- unlock_kernel();
return -EINVAL; /* This should never happen. */
};
- unlock_kernel();
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
diff --git a/drivers/char/drm/lists.c b/drivers/char/drm/lists.c
index f62495aa2..5da7cc6c5 100644
--- a/drivers/char/drm/lists.c
+++ b/drivers/char/drm/lists.c
@@ -116,6 +116,7 @@ int drm_freelist_create(drm_freelist_t *bl, int count)
bl->low_mark = 0;
bl->high_mark = 0;
atomic_set(&bl->wfh, 0);
+ bl->lock = SPIN_LOCK_UNLOCKED;
++bl->initialized;
return 0;
}
@@ -130,8 +131,6 @@ int drm_freelist_destroy(drm_freelist_t *bl)
int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
{
- drm_buf_t *old, *prev;
- int count = 0;
drm_device_dma_t *dma = dev->dma;
if (!dma) {
@@ -152,15 +151,12 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
drm_histogram_compute(dev, buf);
#endif
buf->list = DRM_LIST_FREE;
- do {
- old = bl->next;
- buf->next = old;
- prev = cmpxchg(&bl->next, old, buf);
- if (++count > DRM_LOOPING_LIMIT) {
- DRM_ERROR("Looping\n");
- return 1;
- }
- } while (prev != old);
+
+ spin_lock(&bl->lock);
+ buf->next = bl->next;
+ bl->next = buf;
+ spin_unlock(&bl->lock);
+
atomic_inc(&bl->count);
if (atomic_read(&bl->count) > dma->buf_count) {
DRM_ERROR("%d of %d buffers free after addition of %d\n",
@@ -177,26 +173,21 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
{
- drm_buf_t *old, *new, *prev;
drm_buf_t *buf;
- int count = 0;
if (!bl) return NULL;
/* Get buffer */
- do {
- old = bl->next;
- if (!old) return NULL;
- new = bl->next->next;
- prev = cmpxchg(&bl->next, old, new);
- if (++count > DRM_LOOPING_LIMIT) {
- DRM_ERROR("Looping\n");
- return NULL;
- }
- } while (prev != old);
- atomic_dec(&bl->count);
+ spin_lock(&bl->lock);
+ if (!bl->next) {
+ spin_unlock(&bl->lock);
+ return NULL;
+ }
+ buf = bl->next;
+ bl->next = bl->next->next;
+ spin_unlock(&bl->lock);
- buf = old;
+ atomic_dec(&bl->count);
buf->next = NULL;
buf->list = DRM_LIST_NONE;
DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
diff --git a/drivers/char/drm/lock.c b/drivers/char/drm/lock.c
index 550827278..33b2cc03f 100644
--- a/drivers/char/drm/lock.c
+++ b/drivers/char/drm/lock.c
@@ -223,3 +223,35 @@ int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd,
drm_flush_unblock(dev, lock.context, lock.flags);
return ret;
}
+
+/* If we get here, it means that the process has called DRM_IOCTL_LOCK
+ without calling DRM_IOCTL_UNLOCK.
+
+ If the lock is not held, then let the signal proceed as usual.
+
+ If the lock is held, then set the contended flag and keep the signal
+ blocked.
+
+
+ Return 1 if the signal should be delivered normally.
+ Return 0 if the signal should be blocked. */
+
+int drm_notifier(void *priv)
+{
+ drm_sigdata_t *s = (drm_sigdata_t *)priv;
+ unsigned int old, new, prev;
+
+
+ /* Allow signal delivery if lock isn't held */
+ if (!_DRM_LOCK_IS_HELD(s->lock->lock)
+ || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
+
+ /* Otherwise, set flag to force call to
+ drmUnlock */
+ do {
+ old = s->lock->lock;
+ new = old | _DRM_LOCK_CONT;
+ prev = cmpxchg(&s->lock->lock, old, new);
+ } while (prev != old);
+ return 0;
+}
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index d02c3b581..0df0906e5 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -765,7 +765,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
dev_priv->mAccess = init->mAccess;
init_waitqueue_head(&dev_priv->flush_queue);
init_waitqueue_head(&dev_priv->buf_queue);
- dev_priv->WarpPipe = -1;
+ dev_priv->WarpPipe = 0xff000000;
DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
dev_priv->chipset, dev_priv->warp_ucode_size,
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index fac882471..e0080e595 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -656,6 +656,14 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
#endif
if (!ret) {
+ sigemptyset(&dev->sigmask);
+ sigaddset(&dev->sigmask, SIGSTOP);
+ sigaddset(&dev->sigmask, SIGTSTP);
+ sigaddset(&dev->sigmask, SIGTTIN);
+ sigaddset(&dev->sigmask, SIGTTOU);
+ dev->sigdata.context = lock.context;
+ dev->sigdata.lock = dev->lock.hw_lock;
+ block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
if (lock.flags & _DRM_LOCK_READY) {
/* Wait for space in DMA/FIFO */
}
@@ -719,6 +727,6 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
current->priority = DEF_PRIORITY;
}
#endif
-
+ unblock_all_signals();
return 0;
}
diff --git a/drivers/char/drm/vm.c b/drivers/char/drm/vm.c
index d295529ba..7c5a24bc9 100644
--- a/drivers/char/drm/vm.c
+++ b/drivers/char/drm/vm.c
@@ -250,7 +250,7 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
/* Length must match exact page count */
- if ((length >> PAGE_SHIFT) != dma->page_count) {
+ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
unlock_kernel();
return -EINVAL;
}
@@ -323,6 +323,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
}
+#elif defined(__ia64__)
+ if (map->type != _DRM_AGP)
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
#endif
vma->vm_flags |= VM_IO; /* not in core dump */
}
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index f0c76181b..8b8d0f123 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
+#include <asm/mach-types.h>
#include <asm/uaccess.h>
#include <asm/therm.h>
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 9bb1748ae..4639f34eb 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -395,11 +395,10 @@ efi_rtc_init(void)
return 0;
}
-static int __exit
+static void __exit
efi_rtc_exit(void)
{
/* not yet used */
- return 0;
}
module_init(efi_rtc_init);
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 01eb20e92..6ceb5a152 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -12,7 +12,12 @@
* Version 0.1 -- December, 1998. Initial version.
* Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc.
* Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus.
- */
+ *
+ * BitWizard is actively maintaining this file. We sometimes find
+ * that someone submitted changes to this file. We really appreciate
+ * your help, but please submit changes through us. We're doing our
+ * best to be responsive. -- REW
+ * */
#include <linux/tty.h>
#include <linux/serial.h>
@@ -80,10 +85,18 @@ static void my_hd (unsigned char *addr, int len)
void gs_put_char(struct tty_struct * tty, unsigned char ch)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
DECL
- /* func_enter (); */
+ func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
+ if (! (port->flags & ASYNC_INITIALIZED)) return;
/* Take a lock on the serial tranmit buffer! */
LOCKIT;
@@ -99,7 +112,7 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
port->xmit_cnt++; /* Characters in buffer */
RELEASEIT;
- /* func_exit ();*/
+ func_exit ();
}
@@ -115,11 +128,17 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
int gs_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
int c, total = 0;
int t;
- /* func_enter (); */
+ func_enter ();
+
+ if (!tty) return 0;
+
+ port = tty->driver;
+
+ if (!port) return 0;
if (! (port->flags & ASYNC_INITIALIZED))
return 0;
@@ -170,7 +189,7 @@ int gs_write(struct tty_struct * tty, int from_user,
port->flags |= GS_TX_INTEN;
port->rd->enable_tx_interrupts (port);
}
- /* func_exit (); */
+ func_exit ();
return total;
}
#else
@@ -309,11 +328,11 @@ int gs_write_room(struct tty_struct * tty)
struct gs_port *port = tty->driver_data;
int ret;
- /* func_enter (); */
+ func_enter ();
ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
if (ret < 0)
ret = 0;
- /* func_exit (); */
+ func_exit ();
return ret;
}
@@ -361,7 +380,7 @@ static int gs_wait_tx_flushed (void * ptr, int timeout)
if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
- func_exit();
+ func_exit();
return -EINVAL; /* This is an error which we don't know how to handle. */
}
@@ -399,7 +418,7 @@ static int gs_wait_tx_flushed (void * ptr, int timeout)
gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies "
"(%d chars).\n", jiffies_to_transmit, charsleft);
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout(jiffies_to_transmit);
if (signal_pending (current)) {
gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: ");
@@ -409,7 +428,7 @@ static int gs_wait_tx_flushed (void * ptr, int timeout)
}
gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft);
- current->state = TASK_RUNNING;
+ set_current_state (TASK_RUNNING);
func_exit();
return rv;
@@ -419,10 +438,17 @@ static int gs_wait_tx_flushed (void * ptr, int timeout)
void gs_flush_buffer(struct tty_struct *tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
unsigned long flags;
func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
/* XXX Would the write semaphore do? */
save_flags(flags); cli();
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -438,9 +464,16 @@ void gs_flush_buffer(struct tty_struct *tty)
void gs_flush_chars(struct tty_struct * tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
!port->xmit_buf) {
func_exit ();
@@ -456,9 +489,16 @@ void gs_flush_chars(struct tty_struct * tty)
void gs_stop(struct tty_struct * tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
+
if (port->xmit_cnt &&
port->xmit_buf &&
(port->flags & GS_TX_INTEN) ) {
@@ -471,7 +511,13 @@ void gs_stop(struct tty_struct * tty)
void gs_start(struct tty_struct * tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
+
+ if (!tty) return;
+
+ port = tty->driver_data;
+
+ if (!port) return;
if (port->xmit_cnt &&
port->xmit_buf &&
@@ -486,7 +532,11 @@ void gs_start(struct tty_struct * tty)
void gs_shutdown_port (struct gs_port *port)
{
long flags;
+
func_enter();
+
+ if (!port) return;
+
if (!(port->flags & ASYNC_INITIALIZED))
return;
@@ -505,16 +555,20 @@ void gs_shutdown_port (struct gs_port *port)
port->flags &= ~ASYNC_INITIALIZED;
restore_flags (flags);
+
func_exit();
}
void gs_hangup(struct tty_struct *tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
+ if (!tty) return;
+
+ port = tty->driver_data;
tty = port->tty;
if (!tty)
return;
@@ -534,8 +588,13 @@ void gs_do_softint(void *private_)
struct gs_port *port = private_;
struct tty_struct *tty;
+ func_enter ();
+
+ if (!port) return;
+
tty = port->tty;
- if(!tty) return;
+
+ if (!tty) return;
if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
@@ -557,8 +616,13 @@ int block_til_ready(void *port_, struct file * filp)
struct tty_struct *tty;
func_enter ();
+
+ if (!port) return 0;
+
tty = port->tty;
+ if (!tty) return 0;
+
gs_dprintk (GS_DEBUG_BTR, "Entering block_till_ready.\n");
/*
* If the device is in the middle of being closed, then block
@@ -571,6 +635,7 @@ int block_til_ready(void *port_, struct file * filp)
else
return -ERESTARTSYS;
}
+
gs_dprintk (GS_DEBUG_BTR, "after hung up\n");
/*
@@ -593,6 +658,7 @@ int block_til_ready(void *port_, struct file * filp)
}
gs_dprintk (GS_DEBUG_BTR, "after subtype\n");
+
/*
* If non-blocking mode is set, or the port is not enabled,
* then make the check up front and then exit.
@@ -606,6 +672,7 @@ int block_til_ready(void *port_, struct file * filp)
}
gs_dprintk (GS_DEBUG_BTR, "after nonblock\n");
+
if (port->flags & ASYNC_CALLOUT_ACTIVE) {
if (port->normal_termios.c_cflag & CLOCAL)
do_clocal = 1;
@@ -614,7 +681,6 @@ int block_til_ready(void *port_, struct file * filp)
do_clocal = 1;
}
- gs_dprintk (GS_DEBUG_BTR, "after clocal check.\n");
/*
* Block waiting for the carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
@@ -623,9 +689,9 @@ int block_til_ready(void *port_, struct file * filp)
* exit, either normal or abnormal.
*/
retval = 0;
-
+
add_wait_queue(&port->open_wait, &wait);
-
+
gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n");
cli();
if (!tty_hung_up_p(filp))
@@ -635,7 +701,7 @@ int block_til_ready(void *port_, struct file * filp)
while (1) {
CD = port->rd->get_CD (port);
gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state (TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
!(port->flags & ASYNC_INITIALIZED)) {
if (port->flags & ASYNC_HUP_NOTIFY)
@@ -679,12 +745,11 @@ void gs_close(struct tty_struct * tty, struct file * filp)
func_enter ();
+ if (!tty) return;
+
port = (struct gs_port *) tty->driver_data;
- if(! port) {
- func_exit();
- return;
- }
+ if (!port) return;
if (!port->tty) {
/* This seems to happen when this is called from vhangup. */
@@ -693,6 +758,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
}
save_flags(flags); cli();
+
if (tty_hung_up_p(filp)) {
restore_flags(flags);
port->rd->hungup (port);
@@ -761,7 +827,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
if (port->blocked_open) {
if (port->close_delay) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout(port->close_delay);
}
wake_up_interruptible(&port->open_wait);
@@ -784,14 +850,19 @@ static unsigned int gs_baudrates[] = {
void gs_set_termios (struct tty_struct * tty,
struct termios * old_termios)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
int baudrate, tmp, rv;
struct termios *tiosp;
func_enter();
- tiosp = tty->termios;
+ if (!tty) return;
+
+ port = tty->driver_data;
+ if (!port) return;
+
+ tiosp = tty->termios;
if (gs_debug & GS_DEBUG_TERMIOS) {
gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
diff --git a/drivers/char/i2c-old.c b/drivers/char/i2c-old.c
deleted file mode 100644
index bd9750fc3..000000000
--- a/drivers/char/i2c-old.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Generic i2c interface for linux
- *
- * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/locks.h>
-#include <linux/sched.h>
-#include <linux/malloc.h>
-#include <linux/i2c-old.h>
-
-#define REGPRINT(x) if (verbose) (x)
-#define I2C_DEBUG(x) if (i2c_debug) (x)
-
-static int scan = 0;
-static int verbose = 0;
-static int i2c_debug = 0;
-
-#if LINUX_VERSION_CODE >= 0x020117
-MODULE_PARM(scan,"i");
-MODULE_PARM(verbose,"i");
-MODULE_PARM(i2c_debug,"i");
-#endif
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_bus *busses[I2C_BUS_MAX];
-static struct i2c_driver *drivers[I2C_DRIVER_MAX];
-static int bus_count = 0, driver_count = 0;
-
-#ifdef CONFIG_VIDEO_BT848
-extern int i2c_tuner_init(void);
-extern int msp3400c_init(void);
-#endif
-#ifdef CONFIG_VIDEO_BUZ
-extern int saa7111_init(void);
-extern int saa7185_init(void);
-#endif
-#ifdef CONFIG_VIDEO_LML33
-extern int bt819_init(void);
-extern int bt856_init(void);
-#endif
-
-int i2c_init(void)
-{
- printk(KERN_INFO "i2c: initialized%s\n",
- scan ? " (i2c bus scan enabled)" : "");
- /* anything to do here ? */
-#ifdef CONFIG_VIDEO_BT848
- i2c_tuner_init();
- msp3400c_init();
-#endif
-#ifdef CONFIG_VIDEO_BUZ
- saa7111_init();
- saa7185_init();
-#endif
-#ifdef CONFIG_VIDEO_LML33
- bt819_init();
- bt856_init();
-#endif
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void i2c_attach_device(struct i2c_bus *bus, struct i2c_driver *driver)
-{
- struct i2c_device *device;
- int i,j,ack=1;
- unsigned char addr;
- LOCK_FLAGS;
-
- /* probe for device */
- LOCK_I2C_BUS(bus);
- for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2)
- {
- i2c_start(bus);
- ack = i2c_sendbyte(bus,addr,0);
- i2c_stop(bus);
- if (!ack)
- break;
- }
- UNLOCK_I2C_BUS(bus);
- if (ack)
- return;
-
- /* got answer */
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (NULL == driver->devices[i])
- break;
- if (I2C_DEVICE_MAX == i)
- return;
-
- for (j = 0; j < I2C_DEVICE_MAX; j++)
- if (NULL == bus->devices[j])
- break;
- if (I2C_DEVICE_MAX == j)
- return;
-
- if (NULL == (device = kmalloc(sizeof(struct i2c_device),GFP_KERNEL)))
- return;
- device->bus = bus;
- device->driver = driver;
- device->addr = addr;
-
- /* Attach */
-
- if (driver->attach(device)!=0)
- {
- kfree(device);
- return;
- }
- driver->devices[i] = device;
- driver->devcount++;
- bus->devices[j] = device;
- bus->devcount++;
-
- if (bus->attach_inform)
- bus->attach_inform(bus,driver->id);
- REGPRINT(printk("i2c: device attached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,addr,bus->name,driver->name));
-}
-
-static void i2c_detach_device(struct i2c_device *device)
-{
- int i;
-
- if (device->bus->detach_inform)
- device->bus->detach_inform(device->bus,device->driver->id);
- device->driver->detach(device);
-
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (device == device->driver->devices[i])
- break;
- if (I2C_DEVICE_MAX == i)
- {
- printk(KERN_WARNING "i2c: detach_device #1: device not found: %s\n",
- device->name);
- return;
- }
- device->driver->devices[i] = NULL;
- device->driver->devcount--;
-
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (device == device->bus->devices[i])
- break;
- if (I2C_DEVICE_MAX == i)
- {
- printk(KERN_WARNING "i2c: detach_device #2: device not found: %s\n",
- device->name);
- return;
- }
- device->bus->devices[i] = NULL;
- device->bus->devcount--;
-
- REGPRINT(printk("i2c: device detached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,device->addr,device->bus->name,device->driver->name));
- kfree(device);
-}
-
-/* ----------------------------------------------------------------------- */
-
-int i2c_register_bus(struct i2c_bus *bus)
-{
- int i,ack;
- LOCK_FLAGS;
-
- memset(bus->devices,0,sizeof(bus->devices));
- bus->devcount = 0;
-
- for (i = 0; i < I2C_BUS_MAX; i++)
- if (NULL == busses[i])
- break;
- if (I2C_BUS_MAX == i)
- return -ENOMEM;
-
- busses[i] = bus;
- bus_count++;
- REGPRINT(printk("i2c: bus registered: %s\n",bus->name));
-
- MOD_INC_USE_COUNT;
-
- if (scan)
- {
- /* scan whole i2c bus */
- LOCK_I2C_BUS(bus);
- for (i = 0; i < 256; i+=2)
- {
- i2c_start(bus);
- ack = i2c_sendbyte(bus,i,0);
- i2c_stop(bus);
- if (!ack)
- {
- printk(KERN_INFO "i2c: scanning bus %s: found device at addr=0x%02x\n",
- bus->name,i);
- }
- }
- UNLOCK_I2C_BUS(bus);
- }
-
- /* probe available drivers */
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (drivers[i])
- i2c_attach_device(bus,drivers[i]);
- return 0;
-}
-
-int i2c_unregister_bus(struct i2c_bus *bus)
-{
- int i;
-
- /* detach devices */
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (bus->devices[i])
- i2c_detach_device(bus->devices[i]);
-
- for (i = 0; i < I2C_BUS_MAX; i++)
- if (bus == busses[i])
- break;
- if (I2C_BUS_MAX == i)
- {
- printk(KERN_WARNING "i2c: unregister_bus #1: bus not found: %s\n",
- bus->name);
- return -ENODEV;
- }
-
- MOD_DEC_USE_COUNT;
-
- busses[i] = NULL;
- bus_count--;
- REGPRINT(printk("i2c: bus unregistered: %s\n",bus->name));
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-int i2c_register_driver(struct i2c_driver *driver)
-{
- int i;
-
- memset(driver->devices,0,sizeof(driver->devices));
- driver->devcount = 0;
-
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (NULL == drivers[i])
- break;
- if (I2C_DRIVER_MAX == i)
- return -ENOMEM;
-
- drivers[i] = driver;
- driver_count++;
-
- MOD_INC_USE_COUNT;
-
- REGPRINT(printk("i2c: driver registered: %s\n",driver->name));
-
- /* Probe available busses */
- for (i = 0; i < I2C_BUS_MAX; i++)
- if (busses[i])
- i2c_attach_device(busses[i],driver);
-
- return 0;
-}
-
-int i2c_unregister_driver(struct i2c_driver *driver)
-{
- int i;
-
- /* detach devices */
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (driver->devices[i])
- i2c_detach_device(driver->devices[i]);
-
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (driver == drivers[i])
- break;
- if (I2C_DRIVER_MAX == i)
- {
- printk(KERN_WARNING "i2c: unregister_driver: driver not found: %s\n",
- driver->name);
- return -ENODEV;
- }
-
- MOD_DEC_USE_COUNT;
-
- drivers[i] = NULL;
- driver_count--;
- REGPRINT(printk("i2c: driver unregistered: %s\n",driver->name));
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-int i2c_control_device(struct i2c_bus *bus, int id,
- unsigned int cmd, void *arg)
-{
- int i;
-
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (bus->devices[i] && bus->devices[i]->driver->id == id)
- break;
- if (i == I2C_DEVICE_MAX)
- return -ENODEV;
- if (NULL == bus->devices[i]->driver->command)
- return -ENODEV;
- return bus->devices[i]->driver->command(bus->devices[i],cmd,arg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-#define I2C_SET(bus,ctrl,data) (bus->i2c_setlines(bus,ctrl,data))
-#define I2C_GET(bus) (bus->i2c_getdataline(bus))
-
-void i2c_start(struct i2c_bus *bus)
-{
- I2C_SET(bus,0,1);
- I2C_SET(bus,1,1);
- I2C_SET(bus,1,0);
- I2C_SET(bus,0,0);
- I2C_DEBUG(printk("%s: < ",bus->name));
-}
-
-void i2c_stop(struct i2c_bus *bus)
-{
- I2C_SET(bus,0,0);
- I2C_SET(bus,1,0);
- I2C_SET(bus,1,1);
- I2C_DEBUG(printk(">\n"));
-}
-
-void i2c_one(struct i2c_bus *bus)
-{
- I2C_SET(bus,0,1);
- I2C_SET(bus,1,1);
- I2C_SET(bus,0,1);
-}
-
-void i2c_zero(struct i2c_bus *bus)
-{
- I2C_SET(bus,0,0);
- I2C_SET(bus,1,0);
- I2C_SET(bus,0,0);
-}
-
-int i2c_ack(struct i2c_bus *bus)
-{
- int ack;
-
- I2C_SET(bus,0,1);
- I2C_SET(bus,1,1);
- ack = I2C_GET(bus);
- I2C_SET(bus,0,1);
- return ack;
-}
-
-int i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack)
-{
- int i, ack;
-
- I2C_SET(bus,0,0);
- for (i=7; i>=0; i--)
- (data&(1<<i)) ? i2c_one(bus) : i2c_zero(bus);
- if (wait_for_ack)
- udelay(wait_for_ack);
- ack=i2c_ack(bus);
- I2C_DEBUG(printk("%02x%c ",(int)data,ack?'-':'+'));
- return ack;
-}
-
-unsigned char i2c_readbyte(struct i2c_bus *bus,int last)
-{
- int i;
- unsigned char data=0;
-
- I2C_SET(bus,0,1);
- for (i=7; i>=0; i--)
- {
- I2C_SET(bus,1,1);
- if (I2C_GET(bus))
- data |= (1<<i);
- I2C_SET(bus,0,1);
- }
- last ? i2c_one(bus) : i2c_zero(bus);
- I2C_DEBUG(printk("=%02x%c ",(int)data,last?'-':'+'));
- return data;
-}
-
-/* ----------------------------------------------------------------------- */
-
-int i2c_read(struct i2c_bus *bus, unsigned char addr)
-{
- int ret;
-
- if (bus->i2c_read)
- return bus->i2c_read(bus, addr);
-
- i2c_start(bus);
- i2c_sendbyte(bus,addr,0);
- ret = i2c_readbyte(bus,1);
- i2c_stop(bus);
- return ret;
-}
-
-int i2c_write(struct i2c_bus *bus, unsigned char addr,
- unsigned char data1, unsigned char data2, int both)
-{
- int ack;
-
- if (bus->i2c_write)
- return bus->i2c_write(bus, addr, data1, data2, both);
-
- i2c_start(bus);
- i2c_sendbyte(bus,addr,0);
- ack = i2c_sendbyte(bus,data1,0);
- if (both)
- ack = i2c_sendbyte(bus,data2,0);
- i2c_stop(bus);
- return ack ? -1 : 0 ;
-}
-
-/* ----------------------------------------------------------------------- */
-
-#ifdef MODULE
-
-#if LINUX_VERSION_CODE >= 0x020100
-EXPORT_SYMBOL(i2c_register_bus);
-EXPORT_SYMBOL(i2c_unregister_bus);
-EXPORT_SYMBOL(i2c_register_driver);
-EXPORT_SYMBOL(i2c_unregister_driver);
-EXPORT_SYMBOL(i2c_control_device);
-EXPORT_SYMBOL(i2c_start);
-EXPORT_SYMBOL(i2c_stop);
-EXPORT_SYMBOL(i2c_one);
-EXPORT_SYMBOL(i2c_zero);
-EXPORT_SYMBOL(i2c_ack);
-EXPORT_SYMBOL(i2c_sendbyte);
-EXPORT_SYMBOL(i2c_readbyte);
-EXPORT_SYMBOL(i2c_read);
-EXPORT_SYMBOL(i2c_write);
-#endif
-
-int init_module(void)
-{
- return i2c_init();
-}
-
-void cleanup_module(void)
-{
-}
-#endif
diff --git a/drivers/char/i2c-parport.c b/drivers/char/i2c-parport.c
deleted file mode 100644
index 00b574f60..000000000
--- a/drivers/char/i2c-parport.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * I2C driver for parallel port
- *
- * Author: Phil Blundell <philb@gnu.org>
- *
- * 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 of the License, or (at your option) any later version.
- *
- * This driver implements a simple I2C protocol by bit-twiddling some
- * signals on the parallel port. Since the outputs on the parallel port
- * aren't open collector, three lines rather than two are used:
- *
- * D0 clock out
- * D1 data out
- * BUSY data in
- */
-
-#include <linux/parport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c-old.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-
-#define I2C_DELAY 10
-
-static int debug = 0;
-
-struct parport_i2c_bus
-{
- struct i2c_bus i2c;
- struct parport_i2c_bus *next;
-};
-
-static struct parport_i2c_bus *bus_list;
-
-static spinlock_t bus_list_lock = SPIN_LOCK_UNLOCKED;
-
-/* software I2C functions */
-
-static void i2c_setlines(struct i2c_bus *bus, int clk, int data)
-{
- struct parport *p = bus->data;
- parport_write_data(p, (clk?1:0) | (data?2:0));
- udelay(I2C_DELAY);
-}
-
-static int i2c_getdataline(struct i2c_bus *bus)
-{
- struct parport *p = bus->data;
- return (parport_read_status(p) & PARPORT_STATUS_BUSY) ? 0 : 1;
-}
-
-static struct i2c_bus parport_i2c_bus_template =
-{
- "...",
- I2C_BUSID_PARPORT,
- NULL,
-
- SPIN_LOCK_UNLOCKED,
-
- NULL,
- NULL,
-
- i2c_setlines,
- i2c_getdataline,
- NULL,
- NULL,
-};
-
-static void i2c_parport_attach(struct parport *port)
-{
- struct parport_i2c_bus *b = kmalloc(sizeof(struct parport_i2c_bus),
- GFP_KERNEL);
- b->i2c = parport_i2c_bus_template;
- b->i2c.data = parport_get_port (port);
- strncpy(b->i2c.name, port->name, 32);
- spin_lock(&bus_list_lock);
- b->next = bus_list;
- bus_list = b;
- spin_unlock(&bus_list_lock);
- i2c_register_bus(&b->i2c);
- if (debug)
- printk(KERN_DEBUG "i2c: attached to %s\n", port->name);
-}
-
-static void i2c_parport_detach(struct parport *port)
-{
- struct parport_i2c_bus *b, *old_b = NULL;
- spin_lock(&bus_list_lock);
- b = bus_list;
- while (b)
- {
- if (b->i2c.data == port)
- {
- if (old_b)
- old_b->next = b->next;
- else
- bus_list = b->next;
- i2c_unregister_bus(&b->i2c);
- kfree(b);
- break;
- }
- old_b = b;
- b = b->next;
- }
- spin_unlock(&bus_list_lock);
- if (debug)
- printk(KERN_DEBUG "i2c: detached from %s\n", port->name);
-}
-
-static struct parport_driver parport_i2c_driver =
-{
- "i2c",
- i2c_parport_attach,
- i2c_parport_detach
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int __init i2c_parport_init(void)
-#endif
-{
- printk("I2C: driver for parallel port v0.1 philb@gnu.org\n");
- parport_register_driver(&parport_i2c_driver);
- return 0;
-}
-
-#ifdef MODULE
-MODULE_PARM(debug, "i");
-
-void cleanup_module(void)
-{
- struct parport_i2c_bus *b = bus_list;
- while (b)
- {
- struct parport_i2c_bus *next = b->next;
- i2c_unregister_bus(&b->i2c);
- kfree(b);
- b = next;
- }
- parport_unregister_driver(&parport_i2c_driver);
-}
-#endif
diff --git a/drivers/char/i810-tco.c b/drivers/char/i810-tco.c
new file mode 100644
index 000000000..fcd105d35
--- /dev/null
+++ b/drivers/char/i810-tco.c
@@ -0,0 +1,326 @@
+/*
+ * i810-tco 0.02: TCO timer driver for i810 chipsets
+ *
+ * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
+ * http://www.kernelconcepts.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 of the License, or (at your option) any later version.
+ *
+ * Neither kernel concepts nor Nils Faerber admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
+ *
+ * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>
+ * developed for
+ * Jentro AG, Haar/Munich (Germany)
+ *
+ * TCO timer driver for i810/i815 chipsets
+ * based on softdog.c by Alan Cox <alan@redhat.com>
+ *
+ * The TCO timer is implemented in the 82801AA (82801AB) chip,
+ * see intel documentation from http://developer.intel.com,
+ * order number 290655-003
+ *
+ * 20000710 Nils Faerber
+ * Initial Version 0.01
+ * 20000728 Nils Faerber
+ * 0.02 Fix for SMI_EN->TCO_EN bit, some cleanups
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include "i810-tco.h"
+
+
+/* Just in case that the PCI vendor and device IDs are not yet defined */
+#ifndef PCI_DEVICE_ID_INTEL_82801AA_0
+#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
+#endif
+
+/* Default expire timeout */
+#define TIMER_MARGIN 50 /* steps of 0.6sec, 2<n<64. Default is 30 seconds */
+
+static unsigned int ACPIBASE;
+
+static int i810_margin = TIMER_MARGIN; /* steps of 0.6sec */
+
+MODULE_PARM (i810_margin, "i");
+
+/*
+ * Timer active flag
+ */
+
+static int timer_alive;
+static int boot_status;
+
+/*
+ * Some i810 specific functions
+ */
+
+
+/*
+ * Start the timer countdown
+ */
+static int tco_timer_start (void)
+{
+ unsigned char val;
+
+ val = inb (TCO1_CNT + 1);
+ val &= 0xf7;
+ outb (val, TCO1_CNT + 1);
+ val = inb (TCO1_CNT + 1);
+ if (val & 0x08)
+ return -1;
+ return 0;
+}
+
+/*
+ * Stop the timer countdown
+ */
+static int tco_timer_stop (void)
+{
+ unsigned char val;
+
+ val = inb (TCO1_CNT + 1);
+ val |= 0x08;
+ outb (val, TCO1_CNT + 1);
+ val = inb (TCO1_CNT + 1);
+ if ((val & 0x08) == 0)
+ return -1;
+ return 0;
+}
+
+/*
+ * Set the timer reload value
+ */
+static int tco_timer_settimer (unsigned char tmrval)
+{
+ unsigned char val;
+
+ /* from the specs: */
+ /* "Values of 0h-3h are ignored and should not be attempted" */
+ if (tmrval > 0x3f || tmrval < 0x03)
+ return -1;
+
+ val = inb (TCO1_TMR);
+ val &= 0xc0;
+ val |= tmrval;
+ outb (val, TCO1_TMR);
+ val = inb (TCO1_TMR);
+ if ((val & 0x3f) != tmrval)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Reload (trigger) the timer
+ */
+static void tco_timer_reload (void)
+{
+ outb (0x01, TCO1_RLD);
+}
+
+/*
+ * Read the current timer value
+ */
+static unsigned char tco_timer_read (void)
+{
+ return (inb (TCO1_RLD));
+}
+
+
+/*
+ * Allow only one person to hold it open
+ */
+
+static int i810tco_open (struct inode *inode, struct file *file)
+{
+ if (timer_alive)
+ return -EBUSY;
+
+ /*
+ * Reload and activate timer
+ */
+ tco_timer_reload ();
+ tco_timer_start ();
+ timer_alive = 1;
+ return 0;
+}
+
+static int i810tco_release (struct inode *inode, struct file *file)
+{
+ /*
+ * Shut off the timer.
+ */
+ tco_timer_stop ();
+ timer_alive = 0;
+ return 0;
+}
+
+static ssize_t i810tco_write (struct file *file, const char *data,
+ size_t len, loff_t * ppos)
+{
+ /* Can't seek (pwrite) on this device */
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+
+ /*
+ * Refresh the timer.
+ */
+ if (len) {
+ tco_timer_reload ();
+ return 1;
+ }
+ return 0;
+}
+
+static int i810tco_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ static struct watchdog_info ident = {
+ 0,
+ 0,
+ "i810 TCO timer"
+ };
+ switch (cmd) {
+ default:
+ return -ENOIOCTLCMD;
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user
+ ((struct watchdog_info *) arg, &ident, sizeof (ident)))
+ return -EFAULT;
+ return 0;
+ case WDIOC_GETSTATUS:
+ return put_user (tco_timer_read (),
+ (unsigned int *) (int) arg);
+ case WDIOC_GETBOOTSTATUS:
+ return put_user (boot_status, (int *) arg);
+ case WDIOC_KEEPALIVE:
+ tco_timer_reload ();
+ return 0;
+ }
+}
+
+static struct pci_dev *i810tco_pci;
+
+static unsigned char i810tco_getdevice (void)
+{
+ u8 val1, val2;
+ u16 badr;
+ /*
+ * Find the PCI device which has vendor id 0x8086
+ * and device ID 0x2410
+ */
+ i810tco_pci = pci_find_device (PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82801AA_0, NULL);
+ if (i810tco_pci) {
+ /*
+ * Find the ACPI base I/O address which is the base
+ * for the TCO registers (TCOBASE=ACPIBASE + 0x60)
+ * ACPIBASE is bits [15:7] from 0x40-0x43
+ */
+ pci_read_config_byte (i810tco_pci, 0x40, &val1);
+ pci_read_config_byte (i810tco_pci, 0x41, &val2);
+ badr = ((val2 << 1) | (val1 >> 7)) << 7;
+ ACPIBASE = badr;
+ /* Something's wrong here, ACPIBASE has to be set */
+ if (badr == 0x0001 || badr == 0x0000) {
+ printk (KERN_ERR "i810tco init: failed to get TCOBASE address\n");
+ return 0;
+ }
+ /*
+ * Check chipset's NO_REBOOT bit
+ */
+ pci_read_config_byte (i810tco_pci, 0xd4, &val1);
+ if (val1 & 0x02) {
+ val1 &= 0xfd;
+ pci_write_config_byte (i810tco_pci, 0xd4, val1);
+ pci_read_config_byte (i810tco_pci, 0xd4, &val1);
+ if (val1 & 0x02) {
+ printk (KERN_ERR "i810tco init: failed to reset NO_REBOOT flag\n");
+ return 0; /* Cannot reset NO_REBOOT bit */
+ }
+ }
+ /* Set the TCO_EN bit in SMI_EN register */
+ val1 = inb (SMI_EN + 1);
+ val1 &= 0xdf;
+ outb (val1, SMI_EN + 1);
+ /* Clear out the (probably old) status */
+ outb (0, TCO1_STS);
+ boot_status = (int) inb (TCO2_STS);
+ outb (3, TCO2_STS);
+ return 1;
+ }
+ return 0;
+}
+
+static struct file_operations i810tco_fops = {
+ owner: THIS_MODULE,
+ write: i810tco_write,
+ ioctl: i810tco_ioctl,
+ open: i810tco_open,
+ release: i810tco_release,
+};
+
+static struct miscdevice i810tco_miscdev = {
+ WATCHDOG_MINOR,
+ "watchdog",
+ &i810tco_fops
+};
+
+static int __init watchdog_init (void)
+{
+ if (!i810tco_getdevice () || i810tco_pci == NULL)
+ return -ENODEV;
+ if (!request_region (TCOBASE, 0x10, "i810 TCO")) {
+ printk (KERN_ERR
+ "i810 TCO timer: I/O address 0x%04x already in use\n",
+ TCOBASE);
+ return -EIO;
+ }
+ if (misc_register (&i810tco_miscdev) != 0) {
+ release_region (TCOBASE, 0x10);
+ printk (KERN_ERR "i810 TCO timer: cannot register miscdev\n");
+ return -EIO;
+ }
+ tco_timer_settimer ((unsigned char) i810_margin);
+ tco_timer_reload ();
+
+ /* FIXME: no floating point math */
+ printk (KERN_INFO
+ "i810 TCO timer: V0.02, timer margin: %d sec (0x%04x)\n",
+ (int) (i810_margin * 0.6), TCOBASE);
+ return 0;
+}
+
+static void __exit watchdog_cleanup (void)
+{
+ u8 val;
+
+ /* Reset the timer before we leave */
+ tco_timer_reload ();
+ /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+ pci_read_config_byte (i810tco_pci, 0xd4, &val);
+ val |= 0x02;
+ pci_write_config_byte (i810tco_pci, 0xd4, val);
+ release_region (TCOBASE, 0x10);
+ misc_deregister (&i810tco_miscdev);
+}
+
+module_init(watchdog_init);
+module_exit(watchdog_cleanup);
diff --git a/drivers/char/i810-tco.h b/drivers/char/i810-tco.h
new file mode 100644
index 000000000..a078ae8f6
--- /dev/null
+++ b/drivers/char/i810-tco.h
@@ -0,0 +1,45 @@
+/*
+ * i810-tco 0.02: TCO timer driver for i810 chipsets
+ *
+ * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
+ * http://www.kernelconcepts.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 of the License, or (at your option) any later version.
+ *
+ * Neither kernel concepts nor Nils Faerber admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
+ *
+ * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>
+ * developed for
+ * Jentro AG, Haar/Munich (Germany)
+ *
+ * TCO timer driver for i810 chipsets
+ * based on softdog.c by Alan Cox <alan@redhat.com>
+ *
+ * The TCO timer is implemented in the 82801AA (82801AB) chip,
+ * see intel documentation from http://developer.intel.com,
+ * order number 290655-003
+ *
+ * For history see i810-tco.c
+ */
+
+
+/*
+ * Some address definitions for the i810 TCO
+ */
+
+#define TCOBASE ACPIBASE + 0x60 /* TCO base address */
+#define TCO1_RLD TCOBASE + 0x00 /* TCO Timer Reload and Current Value */
+#define TCO1_TMR TCOBASE + 0x01 /* TCO Timer Initial Value */
+#define TCO1_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
+#define TCO1_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
+#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
+#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
+#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */
+#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */
+
+#define SMI_EN ACPIBASE + 0x30 /* SMI Control and Enable Register */
diff --git a/drivers/char/ibmmpeg2.h b/drivers/char/ibmmpeg2.h
deleted file mode 100644
index 68e10387c..000000000
--- a/drivers/char/ibmmpeg2.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* ibmmpeg2.h - IBM MPEGCD21 definitions */
-
-#ifndef __IBM_MPEG2__
-#define __IBM_MPEG2__
-
-/* Define all MPEG Decoder registers */
-/* Chip Control and Status */
-#define IBM_MP2_CHIP_CONTROL 0x200*2
-#define IBM_MP2_CHIP_MODE 0x201*2
-/* Timer Control and Status */
-#define IBM_MP2_SYNC_STC2 0x202*2
-#define IBM_MP2_SYNC_STC1 0x203*2
-#define IBM_MP2_SYNC_STC0 0x204*2
-#define IBM_MP2_SYNC_PTS2 0x205*2
-#define IBM_MP2_SYNC_PTS1 0x206*2
-#define IBM_MP2_SYNC_PTS0 0x207*2
-/* Video FIFO Control */
-#define IBM_MP2_FIFO 0x208*2
-#define IBM_MP2_FIFOW 0x100*2
-#define IBM_MP2_FIFO_STAT 0x209*2
-#define IBM_MP2_RB_THRESHOLD 0x22b*2
-/* Command buffer */
-#define IBM_MP2_COMMAND 0x20a*2
-#define IBM_MP2_CMD_DATA 0x20b*2
-#define IBM_MP2_CMD_STAT 0x20c*2
-#define IBM_MP2_CMD_ADDR 0x20d*2
-/* Internal Processor Control and Status */
-#define IBM_MP2_PROC_IADDR 0x20e*2
-#define IBM_MP2_PROC_IDATA 0x20f*2
-#define IBM_MP2_WR_PROT 0x235*2
-/* DRAM Access */
-#define IBM_MP2_DRAM_ADDR 0x210*2
-#define IBM_MP2_DRAM_DATA 0x212*2
-#define IBM_MP2_DRAM_CMD_STAT 0x213*2
-#define IBM_MP2_BLOCK_SIZE 0x23b*2
-#define IBM_MP2_SRC_ADDR 0x23c*2
-/* Onscreen Display */
-#define IBM_MP2_OSD_ADDR 0x214*2
-#define IBM_MP2_OSD_DATA 0x215*2
-#define IBM_MP2_OSD_MODE 0x217*2
-#define IBM_MP2_OSD_LINK_ADDR 0x229*2
-#define IBM_MP2_OSD_SIZE 0x22a*2
-/* Interrupt Control */
-#define IBM_MP2_HOST_INT 0x218*2
-#define IBM_MP2_MASK0 0x219*2
-#define IBM_MP2_HOST_INT1 0x23e*2
-#define IBM_MP2_MASK1 0x23f*2
-/* Audio Control */
-#define IBM_MP2_AUD_IADDR 0x21a*2
-#define IBM_MP2_AUD_IDATA 0x21b*2
-#define IBM_MP2_AUD_FIFO 0x21c*2
-#define IBM_MP2_AUD_FIFOW 0x101*2
-#define IBM_MP2_AUD_CTL 0x21d*2
-#define IBM_MP2_BEEP_CTL 0x21e*2
-#define IBM_MP2_FRNT_ATTEN 0x22d*2
-/* Display Control */
-#define IBM_MP2_DISP_MODE 0x220*2
-#define IBM_MP2_DISP_DLY 0x221*2
-#define IBM_MP2_VBI_CTL 0x222*2
-#define IBM_MP2_DISP_LBOR 0x223*2
-#define IBM_MP2_DISP_TBOR 0x224*2
-/* Polarity Control */
-#define IBM_MP2_INFC_CTL 0x22c*2
-
-/* control commands */
-#define IBM_MP2_PLAY 0
-#define IBM_MP2_PAUSE 1
-#define IBM_MP2_SINGLE_FRAME 2
-#define IBM_MP2_FAST_FORWARD 3
-#define IBM_MP2_SLOW_MOTION 4
-#define IBM_MP2_IMED_NORM_PLAY 5
-#define IBM_MP2_RESET_WINDOW 6
-#define IBM_MP2_FREEZE_FRAME 7
-#define IBM_MP2_RESET_VID_RATE 8
-#define IBM_MP2_CONFIG_DECODER 9
-#define IBM_MP2_CHANNEL_SWITCH 10
-#define IBM_MP2_RESET_AUD_RATE 11
-#define IBM_MP2_PRE_OP_CHN_SW 12
-#define IBM_MP2_SET_STILL_MODE 14
-
-/* Define Xilinx FPGA Internal Registers */
-
-/* general control register 0 */
-#define XILINX_CTL0 0x600
-/* genlock delay resister 1 */
-#define XILINX_GLDELAY 0x602
-/* send 16 bits to CS3310 port */
-#define XILINX_CS3310 0x604
-/* send 16 bits to CS3310 and complete */
-#define XILINX_CS3310_CMPLT 0x60c
-/* pulse width modulator control */
-#define XILINX_PWM 0x606
-
-#endif
diff --git a/drivers/char/joystick/Config.in b/drivers/char/joystick/Config.in
index b020f1728..e99afa949 100644
--- a/drivers/char/joystick/Config.in
+++ b/drivers/char/joystick/Config.in
@@ -5,50 +5,50 @@
mainmenu_option next_comment
comment 'Joysticks'
-tristate 'Joystick support' CONFIG_JOYSTICK
+dep_mbool 'Joystick support' CONFIG_JOYSTICK $CONFIG_INPUT
if [ "$CONFIG_JOYSTICK" != "n" ]; then
- define_tristate CONFIG_INPUT_JOYDEV $CONFIG_JOYSTICK
-
comment 'Game port support'
- dep_tristate ' ns558 gameports' CONFIG_INPUT_NS558 $CONFIG_JOYSTICK
- dep_tristate ' PDPI Lightning 4 gamecard' CONFIG_INPUT_LIGHTNING $CONFIG_JOYSTICK
- dep_tristate ' Aureal Vortex and Trident 4DWave gameports' CONFIG_INPUT_PCIGAME $CONFIG_JOYSTICK
+ dep_tristate ' ns558 gameports' CONFIG_INPUT_NS558 $CONFIG_INPUT
+ dep_tristate ' PDPI Lightning 4 gamecard' CONFIG_INPUT_LIGHTNING $CONFIG_INPUT
+ dep_tristate ' Aureal Vortex and Trident 4DWave gameports' CONFIG_INPUT_PCIGAME $CONFIG_INPUT
comment 'Gameport joysticks'
- dep_tristate ' Classic PC analog joysticks and gamepads' CONFIG_INPUT_ANALOG $CONFIG_JOYSTICK
- dep_tristate ' Assasin 3D and MadCatz Panther devices' CONFIG_INPUT_A3D $CONFIG_JOYSTICK
- dep_tristate ' Logitech ADI digital joysticks and gamepads' CONFIG_INPUT_ADI $CONFIG_JOYSTICK
- dep_tristate ' Creative Labs Blaster Cobra gamepad' CONFIG_INPUT_COBRA $CONFIG_JOYSTICK
- dep_tristate ' Genius Flight2000 Digital joysticks and gamepads' CONFIG_INPUT_GF2K $CONFIG_JOYSTICK
- dep_tristate ' Gravis GrIP joysticks and gamepads' CONFIG_INPUT_GRIP $CONFIG_JOYSTICK
- dep_tristate ' InterAct digital joysticks and gamepads' CONFIG_INPUT_INTERACT $CONFIG_JOYSTICK
- dep_tristate ' ThrustMaster DirectConnect joysticks and gamepads' CONFIG_INPUT_TMDC $CONFIG_JOYSTICK
- dep_tristate ' Microsoft SideWinder digital joysticks and gamepads' CONFIG_INPUT_SIDEWINDER $CONFIG_JOYSTICK
+ dep_tristate ' Classic PC analog joysticks and gamepads' CONFIG_INPUT_ANALOG $CONFIG_INPUT
+ dep_tristate ' Assasin 3D and MadCatz Panther devices' CONFIG_INPUT_A3D $CONFIG_INPUT
+ dep_tristate ' Logitech ADI digital joysticks and gamepads' CONFIG_INPUT_ADI $CONFIG_INPUT
+ dep_tristate ' Creative Labs Blaster Cobra gamepad' CONFIG_INPUT_COBRA $CONFIG_INPUT
+ dep_tristate ' Genius Flight2000 Digital joysticks and gamepads' CONFIG_INPUT_GF2K $CONFIG_INPUT
+ dep_tristate ' Gravis GrIP joysticks and gamepads' CONFIG_INPUT_GRIP $CONFIG_INPUT
+ dep_tristate ' InterAct digital joysticks and gamepads' CONFIG_INPUT_INTERACT $CONFIG_INPUT
+ dep_tristate ' ThrustMaster DirectConnect joysticks and gamepads' CONFIG_INPUT_TMDC $CONFIG_INPUT
+ dep_tristate ' Microsoft SideWinder digital joysticks and gamepads' CONFIG_INPUT_SIDEWINDER $CONFIG_INPUT
comment 'Serial port support'
- dep_tristate ' Serial port input line discipline' CONFIG_INPUT_SERPORT $CONFIG_JOYSTICK
+ dep_tristate ' Serial port input line discipline' CONFIG_INPUT_SERPORT $CONFIG_INPUT
comment 'Serial port joysticks'
- dep_tristate ' Logitech WingMan Warrior joystick' CONFIG_INPUT_WARRIOR $CONFIG_JOYSTICK
- dep_tristate ' LogiCad3d Magellan/SpaceMouse 6dof controller' CONFIG_INPUT_MAGELLAN $CONFIG_JOYSTICK
- dep_tristate ' SpaceTec SpaceOrb/Avenger 6dof controller' CONFIG_INPUT_SPACEORB $CONFIG_JOYSTICK
- dep_tristate ' SpaceTec SpaceBall 4000 FLX 6dof controller' CONFIG_INPUT_SPACEBALL $CONFIG_JOYSTICK
- dep_tristate ' I-Force joysticks/wheels' CONFIG_INPUT_IFORCE_232 $CONFIG_JOYSTICK
- if [ "$CONFIG_INPUT_IFORCE_232" != "n" ]; then
- define_tristate CONFIG_INPUT_IFORCE $CONFIG_INPUT_IFORCE_232
- fi
+ dep_tristate ' Logitech WingMan Warrior joystick' CONFIG_INPUT_WARRIOR $CONFIG_INPUT
+ dep_tristate ' LogiCad3d Magellan/SpaceMouse 6dof controller' CONFIG_INPUT_MAGELLAN $CONFIG_INPUT
+ dep_tristate ' SpaceTec SpaceOrb/Avenger 6dof controller' CONFIG_INPUT_SPACEORB $CONFIG_INPUT
+ dep_tristate ' SpaceTec SpaceBall 4000 FLX 6dof controller' CONFIG_INPUT_SPACEBALL $CONFIG_INPUT
+ dep_tristate ' I-Force/Serial controllers' CONFIG_INPUT_IFORCE_232 $CONFIG_INPUT
+ dep_tristate ' I-Force/USB controllers' CONFIG_INPUT_IFORCE_USB $CONFIG_INPUT $CONFIG_USB
- if [ "$CONFIG_PARPORT" != "n" ]; then
comment 'Parallel port joysticks'
- dep_tristate ' Multisystem, Sega Genesis, Saturn joysticks and gamepads' CONFIG_INPUT_DB9 $CONFIG_JOYSTICK
- dep_tristate ' Multisystem, NES, SNES, N64, PSX joysticks and gamepads' CONFIG_INPUT_GAMECON $CONFIG_JOYSTICK
- dep_tristate ' Multisystem joysticks via TurboGraFX device' CONFIG_INPUT_TURBOGRAFX $CONFIG_JOYSTICK
+ if [ "$CONFIG_PARPORT" != "n" ]; then
+ dep_tristate ' Multisystem, Sega Genesis, Saturn joysticks and gamepads' CONFIG_INPUT_DB9 $CONFIG_INPUT $CONFIG_PARPORT
+ dep_tristate ' Multisystem, NES, SNES, N64, PSX joysticks and gamepads' CONFIG_INPUT_GAMECON $CONFIG_INPUT $CONFIG_PARPORT
+ dep_tristate ' Multisystem joysticks via TurboGraFX device' CONFIG_INPUT_TURBOGRAFX $CONFIG_INPUT $CONFIG_PARPORT
+ else
+ comment ' Parport support is needed for parallel port joysticks'
fi
if [ "$CONFIG_AMIGA" = "y" ]; then
comment 'System joysticks'
- dep_tristate ' Amiga joysticks' CONFIG_INPUT_AMIJOY $CONFIG_JOYSTICK
+ dep_tristate ' Amiga joysticks' CONFIG_INPUT_AMIJOY $CONFIG_INPUT
fi
+else
+ comment 'Input core support is needed for joysticks'
fi
-
+
endmenu
diff --git a/drivers/char/joystick/Makefile b/drivers/char/joystick/Makefile
index ae6a42cb8..e8eadc870 100644
--- a/drivers/char/joystick/Makefile
+++ b/drivers/char/joystick/Makefile
@@ -19,6 +19,19 @@ O_OBJS :=
export-objs := serio.o gameport.o
+# I-Force may need both USB and RS-232
+
+ifeq ($(CONFIG_INPUT_IFORCE_232),m)
+ ifeq ($(CONFIG_INPUT_IFORCE_USB),y)
+ CONFIG_INPUT_IFORCE_USB := m
+ endif
+endif
+ifeq ($(CONFIG_INPUT_IFORCE_USB),m)
+ ifeq ($(CONFIG_INPUT_IFORCE_232),y)
+ CONFIG_INPUT_IFORCE_232 := m
+ endif
+endif
+
# Object file lists.
obj-y :=
@@ -38,7 +51,8 @@ obj-$(CONFIG_INPUT_WARRIOR) += warrior.o serio.o
obj-$(CONFIG_INPUT_MAGELLAN) += magellan.o serio.o
obj-$(CONFIG_INPUT_SPACEORB) += spaceorb.o serio.o
obj-$(CONFIG_INPUT_SPACEBALL) += spaceball.o serio.o
-obj-$(CONFIG_INPUT_IFORCE_232) += serio.o
+obj-$(CONFIG_INPUT_IFORCE_232) += iforce.o serio.o
+obj-$(CONFIG_INPUT_IFORCE_USB) += iforce.o
obj-$(CONFIG_INPUT_ANALOG) += analog.o gameport.o
obj-$(CONFIG_INPUT_A3D) += a3d.o gameport.o
diff --git a/drivers/char/joystick/amijoy.c b/drivers/char/joystick/amijoy.c
index f17aeda24..452d173d7 100644
--- a/drivers/char/joystick/amijoy.c
+++ b/drivers/char/joystick/amijoy.c
@@ -1,5 +1,5 @@
/*
- * $Id: amijoy.c,v 1.4 2000/05/29 10:39:54 vojtech Exp $
+ * $Id: amijoy.c,v 1.5 2000/07/21 22:52:24 vojtech Exp $
*
* Copyright (c) 1998-2000 Vojtech Pavlik
*
@@ -77,7 +77,7 @@ static int amijoy_open(struct input_dev *dev)
return 0;
if (request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", NULL)) {
- amijoy_used--;
+ (*used)--;
printk(KERN_ERR "amijoy.c: Can't allocate irq %d\n", amijoy_irq);
return -EBUSY;
}
@@ -89,7 +89,7 @@ static void amijoy_close(struct input_dev *dev)
{
int *used = dev->private;
- if (!--(*port->used))
+ if (!--(*used))
free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt);
}
@@ -112,13 +112,21 @@ static int __init amijoy_init(void)
for (i = 0; i < 2; i++)
if (amijoy[i]) {
+ if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
+ amijoy [Denise]")) {
+ if (i == 1 && amijoy[0]) {
+ input_unregister_device(amijoy_dev);
+ release_mem_region(CUSTOM_PHYSADDR+10, 2);
+ }
+ return -EBUSY;
+ }
amijoy_dev[i].open = amijoy_open;
amijoy_dev[i].close = amijoy_close;
amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- for (j = 0; j < 2; j++)
+ for (j = 0; j < 2; j++) {
amijoy_dev[i].absmin[ABS_X + j] = -1;
amijoy_dev[i].absmax[ABS_X + j] = 1;
}
@@ -134,6 +142,7 @@ static int __init amijoy_init(void)
input_register_device(amijoy_dev + i);
printk(KERN_INFO "input%d: %s at joy%ddat\n", amijoy_dev[i].number, amijoy_name, i);
}
+ return 0;
}
static void _exit amijoy_exit(void)
@@ -141,8 +150,10 @@ static void _exit amijoy_exit(void)
int i;
for (i = 0; i < 2; i++)
- if (amijoy[i])
+ if (amijoy[i]) {
input_unregister_device(amijoy_dev + i);
+ release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2);
+ }
}
module_init(amijoy_init);
diff --git a/drivers/char/joystick/db9.c b/drivers/char/joystick/db9.c
index f9edd0755..4277e7f3d 100644
--- a/drivers/char/joystick/db9.c
+++ b/drivers/char/joystick/db9.c
@@ -1,5 +1,5 @@
/*
- * $Id: db9.c,v 1.5 2000/05/29 20:39:38 vojtech Exp $
+ * $Id: db9.c,v 1.6 2000/06/25 10:57:50 vojtech Exp $
*
* Copyright (c) 1999 Vojtech Pavlik
*
@@ -95,7 +95,7 @@ static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y,
static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 };
-static short *db9_btn[DB9_MAX_PAD] = { db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
+static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn };
static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
@@ -113,36 +113,36 @@ static void db9_timer(unsigned long private)
data = parport_read_data(port) >> 3;
- input_report_abs(dev + 1, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev + 1, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
- input_report_key(dev + 1, BTN_TRIGGER, ~data&DB9_FIRE1);
+ input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1);
case DB9_MULTI_0802:
data = parport_read_status(port) >> 3;
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
- input_report_key(dev, BTN_TRIGGER, data&DB9_FIRE1);
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev, BTN_TRIGGER, data & DB9_FIRE1);
break;
case DB9_MULTI_STICK:
data = parport_read_data(port);
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
- input_report_key(dev, BTN_TRIGGER, ~data&DB9_FIRE1);
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
break;
case DB9_MULTI2_STICK:
data = parport_read_data(port);
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
- input_report_key(dev, BTN_TRIGGER, ~data&DB9_FIRE1);
- input_report_key(dev, BTN_THUMB, ~data&DB9_FIRE2);
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
+ input_report_key(dev, BTN_THUMB, ~data & DB9_FIRE2);
break;
case DB9_GENESIS_PAD:
@@ -150,16 +150,16 @@ static void db9_timer(unsigned long private)
parport_write_control(port, DB9_NOSELECT);
data = parport_read_data(port);
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
- input_report_key(dev, BTN_B, ~data&DB9_FIRE1);
- input_report_key(dev, BTN_C, ~data&DB9_FIRE2);
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
+ input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NORMAL);
data=parport_read_data(port);
- input_report_key(dev, BTN_A, ~data&DB9_FIRE1);
- input_report_key(dev, BTN_START, ~data&DB9_FIRE2);
+ input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
+ input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
break;
case DB9_GENESIS5_PAD:
@@ -167,18 +167,18 @@ static void db9_timer(unsigned long private)
parport_write_control(port, DB9_NOSELECT);
data=parport_read_data(port);
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
- input_report_key(dev, BTN_B, ~data&DB9_FIRE1);
- input_report_key(dev, BTN_C, ~data&DB9_FIRE2);
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
+ input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NORMAL);
data=parport_read_data(port);
- input_report_key(dev, BTN_A, ~data&DB9_FIRE1);
- input_report_key(dev, BTN_X, ~data&DB9_FIRE2);
- input_report_key(dev, BTN_Y, ~data&DB9_LEFT);
- input_report_key(dev, BTN_START, ~data&DB9_RIGHT);
+ input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
+ input_report_key(dev, BTN_X, ~data & DB9_FIRE2);
+ input_report_key(dev, BTN_Y, ~data & DB9_LEFT);
+ input_report_key(dev, BTN_START, ~data & DB9_RIGHT);
break;
case DB9_GENESIS6_PAD:
@@ -187,17 +187,17 @@ static void db9_timer(unsigned long private)
udelay(DB9_GENESIS6_DELAY);
data=parport_read_data(port);
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
- input_report_key(dev, BTN_B, ~data&DB9_FIRE1);
- input_report_key(dev, BTN_C, ~data&DB9_FIRE2);
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
+ input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NORMAL);
udelay(DB9_GENESIS6_DELAY);
data=parport_read_data(port);
- input_report_key(dev, BTN_A, ~data&DB9_FIRE1);
- input_report_key(dev, BTN_X, ~data&DB9_FIRE2);
+ input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
+ input_report_key(dev, BTN_X, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NOSELECT); /* 2 */
udelay(DB9_GENESIS6_DELAY);
@@ -207,10 +207,10 @@ static void db9_timer(unsigned long private)
udelay(DB9_GENESIS6_DELAY);
data=parport_read_data(port);
- input_report_key(dev, BTN_Y, ~data&DB9_LEFT);
- input_report_key(dev, BTN_Z, ~data&DB9_DOWN);
- input_report_key(dev, BTN_MODE, ~data&DB9_UP);
- input_report_key(dev, BTN_START, ~data&DB9_RIGHT);
+ input_report_key(dev, BTN_Y, ~data & DB9_LEFT);
+ input_report_key(dev, BTN_Z, ~data & DB9_DOWN);
+ input_report_key(dev, BTN_MODE, ~data & DB9_UP);
+ input_report_key(dev, BTN_START, ~data & DB9_RIGHT);
parport_write_control(port, DB9_NORMAL);
udelay(DB9_GENESIS6_DELAY);
@@ -224,32 +224,32 @@ static void db9_timer(unsigned long private)
parport_write_control(port, DB9_SATURN0);
data = parport_read_data(port);
- input_report_key(dev, BTN_Y, ~data&DB9_LEFT);
- input_report_key(dev, BTN_Z, ~data&DB9_DOWN);
- input_report_key(dev, BTN_TL,~data&DB9_UP);
- input_report_key(dev, BTN_TR,~data&DB9_RIGHT);
+ input_report_key(dev, BTN_Y, ~data & DB9_LEFT);
+ input_report_key(dev, BTN_Z, ~data & DB9_DOWN);
+ input_report_key(dev, BTN_TL, ~data & DB9_UP);
+ input_report_key(dev, BTN_TR, ~data & DB9_RIGHT);
parport_write_control(port, DB9_SATURN2);
data = parport_read_data(port);
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
parport_write_control(port, DB9_NORMAL);
data = parport_read_data(port);
- input_report_key(dev, BTN_A, ~data&DB9_LEFT);
- input_report_key(dev, BTN_B, ~data&DB9_UP);
- input_report_key(dev, BTN_C, ~data&DB9_DOWN);
- input_report_key(dev, BTN_X, ~data&DB9_RIGHT);
+ input_report_key(dev, BTN_A, ~data & DB9_LEFT);
+ input_report_key(dev, BTN_B, ~data & DB9_UP);
+ input_report_key(dev, BTN_C, ~data & DB9_DOWN);
+ input_report_key(dev, BTN_X, ~data & DB9_RIGHT);
break;
case DB9_CD32_PAD:
data=parport_read_data(port);
- input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1));
- input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1));
+ input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
parport_write_control(port, 0x0a);
@@ -257,7 +257,7 @@ static void db9_timer(unsigned long private)
data = parport_read_data(port);
parport_write_control(port, 0x02);
parport_write_control(port, 0x0a);
- input_report_key(dev, db9_cd32_btn[i], ~data&DB9_FIRE2);
+ input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
}
parport_write_control(port, 0x00);
diff --git a/drivers/char/joystick/gamecon.c b/drivers/char/joystick/gamecon.c
index a92ef58a9..c1d37248f 100644
--- a/drivers/char/joystick/gamecon.c
+++ b/drivers/char/joystick/gamecon.c
@@ -1,5 +1,5 @@
/*
- * $Id: gamecon.c,v 1.4 2000/05/29 21:08:45 vojtech Exp $
+ * $Id: gamecon.c,v 1.5 2000/06/25 09:56:58 vojtech Exp $
*
* Copyright (c) 1999-2000 Vojtech Pavlik
*
@@ -157,7 +157,7 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data)
static unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 };
static unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 };
-static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_START, BTN_SELECT, BTN_X, BTN_Y, BTN_TL, BTN_TR };
+static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR };
/*
* gc_nes_read_packet() reads a NES/SNES packet.
@@ -515,7 +515,7 @@ static struct gc __init *gc_probe(int *config)
case GC_N64:
for (j = 0; j < 10; j++)
- set_bit(gc_n64_btn[j], gc->dev[j].keybit);
+ set_bit(gc_n64_btn[j], gc->dev[i].keybit);
for (j = 0; j < 2; j++) {
set_bit(ABS_X + j, gc->dev[i].absbit);
@@ -530,18 +530,15 @@ static struct gc __init *gc_probe(int *config)
break;
case GC_SNES:
- for (j = 0; j < 8; j++)
- set_bit(gc_snes_btn[j], gc->dev[j].keybit);
- break;
-
+ for (j = 4; j < 8; j++)
+ set_bit(gc_snes_btn[j], gc->dev[i].keybit);
case GC_NES:
for (j = 0; j < 4; j++)
- set_bit(gc_snes_btn[j], gc->dev[j].keybit);
+ set_bit(gc_snes_btn[j], gc->dev[i].keybit);
break;
case GC_MULTI2:
set_bit(BTN_THUMB, gc->dev[i].keybit);
-
case GC_MULTI:
set_bit(BTN_TRIGGER, gc->dev[i].keybit);
break;
@@ -656,12 +653,13 @@ void __exit gc_exit(void)
{
int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 5; j++)
- if (gc_base[i]->pads[0] & gc_status_bit[j])
- input_unregister_device(gc_base[i]->dev + j);
- parport_unregister_device(gc_base[i]->pd);
- }
+ for (i = 0; i < 3; i++)
+ if (gc_base[i]) {
+ for (j = 0; j < 5; j++)
+ if (gc_base[i]->pads[0] & gc_status_bit[j])
+ input_unregister_device(gc_base[i]->dev + j);
+ parport_unregister_device(gc_base[i]->pd);
+ }
}
module_init(gc_init);
diff --git a/drivers/char/joystick/iforce.c b/drivers/char/joystick/iforce.c
new file mode 100644
index 000000000..acb0bfe5b
--- /dev/null
+++ b/drivers/char/joystick/iforce.c
@@ -0,0 +1,342 @@
+/*
+ * $Id: iforce.c,v 1.7 2000/06/04 14:03:36 vojtech Exp $
+ *
+ * Copyright (c) 2000 Vojtech Pavlik
+ *
+ * USB/RS232 I-Force joysticks and wheels.
+ *
+ * Sponsored by SuSE
+ */
+
+/*
+ * 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
+ * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
+ */
+
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/serio.h>
+#include <linux/config.h>
+
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver");
+
+#define USB_VENDOR_ID_LOGITECH 0x046d
+#define USB_DEVICE_ID_LOGITECH_WMFORCE 0xc281
+
+#define IFORCE_MAX_LENGTH 16
+
+#if defined(CONFIG_INPUT_IFORCE_232) || defined(CONFIG_INPUT_IFORCE_232_MODULE)
+#define IFORCE_232
+#endif
+#if defined(CONFIG_INPUT_IFORCE_USB) || defined(CONFIG_INPUT_IFORCE_USB_MODULE)
+#define IFORCE_USB
+#endif
+
+struct iforce {
+ signed char data[IFORCE_MAX_LENGTH];
+ struct input_dev dev;
+ struct urb irq;
+ int open;
+ int idx, pkt, len, id;
+ unsigned char csum;
+};
+
+static struct {
+ __s32 x;
+ __s32 y;
+} iforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
+
+static char *iforce_name = "I-Force joystick/wheel";
+
+static void iforce_process_packet(struct input_dev *dev, unsigned char id, int idx, unsigned char *data)
+{
+ switch (id) {
+
+ case 1: /* joystick position data */
+ case 3: /* wheel position data */
+
+ if (id == 1) {
+ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
+ input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
+ input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
+ } else {
+ input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
+ input_report_abs(dev, ABS_GAS, 255 - data[2]);
+ input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
+ }
+
+ input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
+ input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
+
+ input_report_key(dev, BTN_TRIGGER, data[5] & 0x01);
+ input_report_key(dev, BTN_TOP, data[5] & 0x02);
+ input_report_key(dev, BTN_THUMB, data[5] & 0x04);
+ input_report_key(dev, BTN_TOP2, data[5] & 0x08);
+ input_report_key(dev, BTN_BASE, data[5] & 0x10);
+ input_report_key(dev, BTN_BASE2, data[5] & 0x20);
+ input_report_key(dev, BTN_BASE3, data[5] & 0x40);
+ input_report_key(dev, BTN_BASE4, data[5] & 0x80);
+ input_report_key(dev, BTN_BASE5, data[6] & 0x01);
+ input_report_key(dev, BTN_A, data[6] & 0x02);
+ input_report_key(dev, BTN_B, data[6] & 0x04);
+ input_report_key(dev, BTN_C, data[6] & 0x08);
+ break;
+
+ case 2: /* force feedback effect status */
+ break;
+ }
+}
+
+#ifdef IFORCE_USB
+
+static int iforce_open(struct input_dev *dev)
+{
+ struct iforce *iforce = dev->private;
+
+ if (dev->idbus == BUS_USB && !iforce->open++)
+ if (usb_submit_urb(&iforce->irq))
+ return -EIO;
+
+ return 0;
+}
+
+static void iforce_close(struct input_dev *dev)
+{
+ struct iforce *iforce = dev->private;
+
+ if (dev->idbus == BUS_USB && !--iforce->open)
+ usb_unlink_urb(&iforce->irq);
+}
+
+#endif
+
+static void iforce_input_setup(struct iforce *iforce)
+{
+ int i;
+
+ iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ iforce->dev.keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_TOP) | BIT(BTN_THUMB) | BIT(BTN_TOP2) |
+ BIT(BTN_BASE) | BIT(BTN_BASE2) | BIT(BTN_BASE3) | BIT(BTN_BASE4) | BIT(BTN_BASE5);
+ iforce->dev.keybit[LONG(BTN_GAMEPAD)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C);
+ iforce->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y)
+ | BIT(ABS_WHEEL) | BIT(ABS_GAS) | BIT(ABS_BRAKE);
+
+ for (i = ABS_X; i <= ABS_Y; i++) {
+ iforce->dev.absmax[i] = 1920;
+ iforce->dev.absmin[i] = -1920;
+ iforce->dev.absflat[i] = 128;
+ iforce->dev.absfuzz[i] = 16;
+ }
+
+ for (i = ABS_THROTTLE; i <= ABS_RUDDER; i++) {
+ iforce->dev.absmax[i] = 255;
+ iforce->dev.absmin[i] = 0;
+ }
+
+ for (i = ABS_HAT0X; i <= ABS_HAT0Y; i++) {
+ iforce->dev.absmax[i] = 1;
+ iforce->dev.absmin[i] = -1;
+ }
+
+ iforce->dev.private = iforce;
+
+#ifdef IFORCE_USB
+ iforce->dev.open = iforce_open;
+ iforce->dev.close = iforce_close;
+#endif
+
+ input_register_device(&iforce->dev);
+}
+
+#ifdef IFORCE_USB
+
+static void iforce_usb_irq(struct urb *urb)
+{
+ struct iforce *iforce = urb->context;
+ if (urb->status) return;
+ iforce_process_packet(&iforce->dev, iforce->data[0], 8, iforce->data + 1);
+}
+
+static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum)
+{
+ struct usb_endpoint_descriptor *endpoint;
+ struct iforce *iforce;
+
+ if (dev->descriptor.idVendor != USB_VENDOR_ID_LOGITECH ||
+ dev->descriptor.idProduct != USB_DEVICE_ID_LOGITECH_WMFORCE)
+ return NULL;
+
+ endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
+
+ if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return NULL;
+ memset(iforce, 0, sizeof(struct iforce));
+
+ iforce->dev.name = iforce_name;
+ iforce->dev.idbus = BUS_USB;
+ iforce->dev.idvendor = dev->descriptor.idVendor;
+ iforce->dev.idproduct = dev->descriptor.idProduct;
+ iforce->dev.idversion = dev->descriptor.bcdDevice;
+
+ FILL_INT_URB(&iforce->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+ iforce->data, 8, iforce_usb_irq, iforce, endpoint->bInterval);
+
+ iforce_input_setup(iforce);
+
+ printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
+ iforce->dev.number, iforce_name, dev->bus->busnum, dev->devnum, ifnum);
+
+ return iforce;
+}
+
+static void iforce_usb_disconnect(struct usb_device *dev, void *ptr)
+{
+ struct iforce *iforce = ptr;
+ usb_unlink_urb(&iforce->irq);
+ input_unregister_device(&iforce->dev);
+ kfree(iforce);
+}
+
+static struct usb_driver iforce_usb_driver = {
+ name: "iforce",
+ probe: iforce_usb_probe,
+ disconnect: iforce_usb_disconnect,
+};
+
+#endif
+
+#ifdef IFORCE_232
+
+static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags)
+{
+ struct iforce* iforce = serio->private;
+
+ if (!iforce->pkt) {
+ if (data != 0x2b) {
+ return;
+ }
+ iforce->pkt = 1;
+ return;
+ }
+
+ if (!iforce->id) {
+ if (data > 3) {
+ iforce->pkt = 0;
+ return;
+ }
+ iforce->id = data;
+ return;
+ }
+
+ if (!iforce->len) {
+ if (data > IFORCE_MAX_LENGTH) {
+ iforce->pkt = 0;
+ iforce->id = 0;
+ return;
+ }
+ iforce->len = data;
+ return;
+ }
+
+ if (iforce->idx < iforce->len) {
+ iforce->csum += iforce->data[iforce->idx++] = data;
+ return;
+ }
+
+ if (iforce->idx == iforce->len) {
+ iforce_process_packet(&iforce->dev, iforce->id, iforce->idx, iforce->data);
+ iforce->pkt = 0;
+ iforce->id = 0;
+ iforce->len = 0;
+ iforce->idx = 0;
+ iforce->csum = 0;
+ }
+}
+
+static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev)
+{
+ struct iforce *iforce;
+
+ if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
+ return;
+
+ if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return;
+ memset(iforce, 0, sizeof(struct iforce));
+
+ iforce->dev.name = iforce_name;
+ iforce->dev.idbus = BUS_RS232;
+ iforce->dev.idvendor = SERIO_IFORCE;
+ iforce->dev.idproduct = 0x0001;
+ iforce->dev.idversion = 0x0100;
+
+ serio->private = iforce;
+
+ if (serio_open(serio, dev)) {
+ kfree(iforce);
+ return;
+ }
+
+ iforce_input_setup(iforce);
+
+ printk(KERN_INFO "input%d: %s on serio%d\n",
+ iforce->dev.number, iforce_name, serio->number);
+}
+
+static void iforce_serio_disconnect(struct serio *serio)
+{
+ struct iforce* iforce = serio->private;
+ input_unregister_device(&iforce->dev);
+ serio_close(serio);
+ kfree(iforce);
+}
+
+static struct serio_dev iforce_serio_dev = {
+ interrupt: iforce_serio_irq,
+ connect: iforce_serio_connect,
+ disconnect: iforce_serio_disconnect,
+};
+
+#endif
+
+static int __init iforce_init(void)
+{
+#ifdef IFORCE_USB
+ usb_register(&iforce_usb_driver);
+#endif
+#ifdef IFORCE_232
+ serio_register_device(&iforce_serio_dev);
+#endif
+ return 0;
+}
+
+static void __exit iforce_exit(void)
+{
+#ifdef IFORCE_USB
+ usb_deregister(&iforce_usb_driver);
+#endif
+#ifdef IFORCE_232
+ serio_unregister_device(&iforce_serio_dev);
+#endif
+}
+
+module_init(iforce_init);
+module_exit(iforce_exit);
diff --git a/drivers/char/joystick/ns558.c b/drivers/char/joystick/ns558.c
index f34a18640..9ea833113 100644
--- a/drivers/char/joystick/ns558.c
+++ b/drivers/char/joystick/ns558.c
@@ -1,5 +1,5 @@
/*
- * $Id: ns558.c,v 1.11 2000/06/20 23:35:03 vojtech Exp $
+ * $Id: ns558.c,v 1.16 2000/08/17 20:03:56 vojtech Exp $
*
* Copyright (c) 1999-2000 Vojtech Pavlik
* Copyright (c) 1999 Brian Gerst
@@ -138,7 +138,7 @@ static struct ns558* ns558_isa_probe(int io, struct ns558 *next)
port->next = next;
port->type = NS558_ISA;
- port->gameport.io = io;
+ port->gameport.io = io & (-1 << i);
port->gameport.size = (1 << i);
request_region(port->gameport.io, port->gameport.size, "ns558-isa");
@@ -182,6 +182,7 @@ static int __devinit ns558_pci_probe(struct pci_dev *pdev, const struct pci_devi
if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) {
printk(KERN_ERR "Memory allocation failed.\n");
+ release_region(ioport, iolen);
return -ENOMEM;
}
memset(port, 0, sizeof(struct ns558));
@@ -208,6 +209,7 @@ static void __devexit ns558_pci_remove(struct pci_dev *pdev)
{
struct ns558 *port = (struct ns558 *)pdev->driver_data;
release_region(port->gameport.io, port->gameport.size);
+ kfree(port);
}
static struct pci_driver ns558_pci_driver = {
@@ -216,10 +218,16 @@ static struct pci_driver ns558_pci_driver = {
probe: ns558_pci_probe,
remove: ns558_pci_remove,
};
+#else
+static struct pci_driver ns558_pci_driver;
#endif /* CONFIG_PCI */
-#ifdef CONFIG_ISAPNP
+#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
+#define NSS558_ISAPNP
+#endif
+
+#ifdef NSS558_ISAPNP
/*
* PnP IDs:
*
@@ -297,7 +305,7 @@ deactivate:
int __init ns558_init(void)
{
int i = 0;
-#ifdef CONFIG_ISAPNP
+#ifdef NSS558_ISAPNP
struct pci_dev *dev = NULL;
struct pnp_devid *devid;
#endif
@@ -310,17 +318,10 @@ int __init ns558_init(void)
ns558 = ns558_isa_probe(ns558_isa_portlist[i++], ns558);
/*
- * Probe for PCI ports.
- */
-#ifdef CONFIG_PCI
- pci_register_driver(&ns558_pci_driver);
-#endif
-
-/*
* Probe for PnP ports.
*/
-#ifdef CONFIG_ISAPNP
+#ifdef NSS558_ISAPNP
for (devid = pnp_devids; devid->vendor; devid++) {
while ((dev = isapnp_find_dev(NULL, devid->vendor, devid->device, dev))) {
ns558 = ns558_pnp_probe(dev, ns558);
@@ -328,7 +329,14 @@ int __init ns558_init(void)
}
#endif
- return -!ns558;
+/*
+ * Probe for PCI ports.
+ */
+
+ if (!ns558 && pci_module_init(&ns558_pci_driver))
+ return -ENODEV;
+
+ return 0;
}
void __exit ns558_exit(void)
@@ -339,7 +347,7 @@ void __exit ns558_exit(void)
gameport_unregister_port(&port->gameport);
switch (port->type) {
-#ifdef CONFIG_ISAPNP
+#ifdef NSS558_ISAPNP
case NS558_PNP:
if (port->dev->deactivate)
port->dev->deactivate(port->dev);
@@ -357,9 +365,7 @@ void __exit ns558_exit(void)
port = port->next;
}
-#ifdef CONFIG_PCI
pci_unregister_driver(&ns558_pci_driver);
-#endif
}
module_init(ns558_init);
diff --git a/drivers/char/joystick/sidewinder.c b/drivers/char/joystick/sidewinder.c
index 861966b4e..85be9f8b1 100644
--- a/drivers/char/joystick/sidewinder.c
+++ b/drivers/char/joystick/sidewinder.c
@@ -1,5 +1,5 @@
/*
- * $Id: sidewinder.c,v 1.14 2000/05/29 11:27:55 vojtech Exp $
+ * $Id: sidewinder.c,v 1.16 2000/07/14 09:02:41 vojtech Exp $
*
* Copyright (c) 1998-2000 Vojtech Pavlik
*
@@ -330,8 +330,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (sw_parity(GB(i*15,15))) return -1;
- input_report_key(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
- input_report_key(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
+ input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
+ input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
for (j = 0; j < 10; j++)
input_report_key(dev, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
diff --git a/drivers/char/joystick/spaceball.c b/drivers/char/joystick/spaceball.c
index 4f5059330..8e2936f73 100644
--- a/drivers/char/joystick/spaceball.c
+++ b/drivers/char/joystick/spaceball.c
@@ -1,5 +1,5 @@
/*
- * $Id: spaceball.c,v 1.6 2000/05/29 11:19:51 vojtech Exp $
+ * $Id: spaceball.c,v 1.7 2000/06/24 11:55:40 vojtech Exp $
*
* Copyright (c) 1999-2000 Vojtech Pavlik
*
@@ -46,7 +46,7 @@
*/
#define JS_SBALL_MAX_LENGTH 128
-static int spaceball_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
+static int spaceball_axes[] = { ABS_X, ABS_Z, ABS_Y, ABS_RX, ABS_RZ, ABS_RY };
static char *spaceball_name = "SpaceTec SpaceBall 4000 FLX";
/*
@@ -70,10 +70,12 @@ static void spaceball_process_packet(struct spaceball* spaceball)
{
struct input_dev *dev = &spaceball->dev;
unsigned char *data = spaceball->data;
- int i, d;
+ int i;
if (spaceball->idx < 2) return;
+ printk("%c %d\n", spaceball->data[0], spaceball->idx);
+
switch (spaceball->data[0]) {
case '@': /* Reset packet */
@@ -84,17 +86,17 @@ static void spaceball_process_packet(struct spaceball* spaceball)
break;
case 'D': /* Ball data */
- if (spaceball->idx != 16) return;
+ if (spaceball->idx != 15) return;
for (i = 0; i < 6; i++) {
- d = ((data[2 * i + 3] << 8) | data[2 * i + 2]);
- input_report_abs(dev, spaceball_axes[i], d - ((d & 0x8000) ? 0x10000 : 0));
+ input_report_abs(dev, spaceball_axes[i],
+ (__s16)((data[2 * i + 3] << 8) | data[2 * i + 2]));
}
break;
case '.': /* Button data, part2 */
- if (spaceball->idx != 4) return;
- input_report_key(dev, BTN_LEFT, data[2] & 1);
- input_report_key(dev, BTN_RIGHT, data[2] & 2);
+ if (spaceball->idx != 3) return;
+ input_report_key(dev, BTN_0, data[2] & 1);
+ input_report_key(dev, BTN_1, data[2] & 2);
break;
case '?': /* Error packet */
@@ -118,22 +120,27 @@ static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigne
switch (data) {
case 0xd:
- if (spaceball->idx)
- spaceball_process_packet(spaceball);
+ spaceball_process_packet(spaceball);
spaceball->idx = 0;
spaceball->escape = 0;
return;
+ case '^':
+ if (!spaceball->escape) {
+ spaceball->escape ^= 1;
+ return;
+ }
+ spaceball->escape = 0;
case 'M':
case 'Q':
case 'S':
- if (spaceball->escape)
+ if (spaceball->escape) {
+ spaceball->escape = 0;
data = 0xd;
- case '^':
- spaceball->escape ^= 1;
+ }
default:
if (spaceball->escape) {
- printk(KERN_WARNING "spaceball.c: Unknown escaped character: %#x\n", data);
spaceball->escape = 0;
+ printk(KERN_WARNING "spaceball.c: Unknown escaped character: %#x (%c)\n", data, data);
}
if (spaceball->idx < JS_SBALL_MAX_LENGTH)
spaceball->data[spaceball->idx++] = data;
@@ -172,15 +179,15 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
memset(spaceball, 0, sizeof(struct spaceball));
spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- spaceball->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+ spaceball->dev.keybit[LONG(BTN_0)] = BIT(BTN_0) | BIT(BTN_1);
for (i = 0; i < 6; i++) {
t = spaceball_axes[i];
set_bit(t, spaceball->dev.absbit);
- spaceball->dev.absmin[t] = i < 3 ? -10000 : -2000;
- spaceball->dev.absmax[t] = i < 3 ? 10000 : 2000;
- spaceball->dev.absflat[t] = i < 3 ? 50 : 10;
- spaceball->dev.absfuzz[t] = i < 3 ? 12 : 2;
+ spaceball->dev.absmin[t] = i < 3 ? -8000 : -1600;
+ spaceball->dev.absmax[t] = i < 3 ? 8000 : 1600;
+ spaceball->dev.absflat[t] = i < 3 ? 40 : 8;
+ spaceball->dev.absfuzz[t] = i < 3 ? 8 : 2;
}
spaceball->serio = serio;
diff --git a/drivers/char/msp3400.c b/drivers/char/msp3400.c
deleted file mode 100644
index 2d2b1e89c..000000000
--- a/drivers/char/msp3400.c
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * programming the msp34* sound processor family
- *
- * (c) 1997-2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
- *
- * what works and what doesn't:
- *
- * AM-Mono
- * Support for Hauppauge cards added (decoding handled by tuner) added by
- * Frederic Crozat <fcrozat@mail.dotcom.fr>
- *
- * FM-Mono
- * should work. The stereo modes are backward compatible to FM-mono,
- * therefore FM-Mono should be allways available.
- *
- * FM-Stereo (B/G, used in germany)
- * should work, with autodetect
- *
- * FM-Stereo (satellite)
- * should work, no autodetect (i.e. default is mono, but you can
- * switch to stereo -- untested)
- *
- * NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
- * should work, with autodetect. Support for NICAM was added by
- * Pekka Pietikainen <pp@netppl.fi>
- *
- *
- * TODO:
- * - better SAT support
- *
- *
- * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
- * using soundcore instead of OSS
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/i2c.h>
-#include <linux/videodev.h>
-#include <asm/semaphore.h>
-#include <linux/init.h>
-
-#ifdef CONFIG_SMP
-#include <asm/pgtable.h>
-#include <linux/smp_lock.h>
-#endif
-/* kernel_thread */
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
-
-#include "audiochip.h"
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {0x40,0x40,I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-/* insmod parameters */
-static int debug = 0; /* debug output */
-static int once = 0; /* no continous stereo monitoring */
-static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france),
- the autoscan seems work well only with FM... */
-static int simple = -1; /* use short programming (>= msp3410 only) */
-static int dolby = 0;
-
-struct msp3400c {
- int simple;
- int nicam;
- int mode;
- int norm;
- int stereo;
- int nicam_on;
- int main, second; /* sound carrier */
-
- int left, right; /* volume */
- int bass, treble;
-
- /* thread */
- struct task_struct *thread;
- wait_queue_head_t wq;
-
- struct semaphore *notify;
- int active,restart,rmmod;
-
- int watch_stereo;
- struct timer_list wake_stereo;
-};
-
-#define MSP3400_MAX 4
-static struct i2c_client *msps[MSP3400_MAX];
-
-#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
-
-/* ---------------------------------------------------------------------- */
-
-#define dprintk if (debug) printk
-
-MODULE_PARM(once,"i");
-MODULE_PARM(debug,"i");
-MODULE_PARM(simple,"i");
-MODULE_PARM(amsound,"i");
-MODULE_PARM(dolby,"i");
-
-/* ---------------------------------------------------------------------- */
-
-#define I2C_MSP3400C 0x80
-#define I2C_MSP3400C_DEM 0x10
-#define I2C_MSP3400C_DFP 0x12
-
-/* ----------------------------------------------------------------------- */
-/* functions for talking to the MSP3400C Sound processor */
-
-static int msp3400c_reset(struct i2c_client *client)
-{
- static char reset_off[3] = { 0x00, 0x80, 0x00 };
- static char reset_on[3] = { 0x00, 0x00, 0x00 };
-
- i2c_master_send(client,reset_off,3); /* XXX ignore errors here */
- if (3 != i2c_master_send(client,reset_on, 3)) {
- printk(KERN_ERR "msp3400: chip reset failed, penguin on i2c bus?\n");
- return -1;
- }
- return 0;
-}
-
-static int
-msp3400c_read(struct i2c_client *client, int dev, int addr)
-{
- int err;
-
- unsigned char write[3];
- unsigned char read[2];
- struct i2c_msg msgs[2] = {
- { client->addr, 0, 3, write },
- { client->addr, I2C_M_RD, 2, read }
- };
- write[0] = dev+1;
- write[1] = addr >> 8;
- write[2] = addr & 0xff;
-
- for (err = 0; err < 3;) {
- if (2 == i2c_transfer(client->adapter,msgs,2))
- break;
- err++;
- printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n",
- err, dev, addr);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
- }
- if (3 == err) {
- printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
- msp3400c_reset(client);
- return -1;
- }
- return read[0] << 8 | read[1];
-}
-
-static int
-msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
-{
- int err;
- unsigned char buffer[5];
-
- buffer[0] = dev;
- buffer[1] = addr >> 8;
- buffer[2] = addr & 0xff;
- buffer[3] = val >> 8;
- buffer[4] = val & 0xff;
-
- for (err = 0; err < 3;) {
- if (5 == i2c_master_send(client, buffer, 5))
- break;
- err++;
- printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n",
- err, dev, addr);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
- }
- if (3 == err) {
- printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
- msp3400c_reset(client);
- return -1;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-/* This macro is allowed for *constants* only, gcc must calculate it
- at compile time. Remember -- no floats in kernel mode */
-#define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
-
-#define MSP_MODE_AM_DETECT 0
-#define MSP_MODE_FM_RADIO 2
-#define MSP_MODE_FM_TERRA 3
-#define MSP_MODE_FM_SAT 4
-#define MSP_MODE_FM_NICAM1 5
-#define MSP_MODE_FM_NICAM2 6
-#define MSP_MODE_AM_NICAM 7
-#define MSP_MODE_BTSC 8
-
-static struct MSP_INIT_DATA_DEM {
- int fir1[6];
- int fir2[6];
- int cdo1;
- int cdo2;
- int ad_cv;
- int mode_reg;
- int dfp_src;
- int dfp_matrix;
-} msp_init_data[] = {
- /* AM (for carrier detect / msp3400) */
- { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0500, 0x0020, 0x3000},
-
- /* AM (for carrier detect / msp3410) */
- { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0100, 0x0020, 0x3000},
-
- /* FM Radio */
- { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
- MSP_CARRIER(10.7), MSP_CARRIER(10.7),
- 0x00d0, 0x0480, 0x0020, 0x3000 },
-
- /* Terrestial FM-mono + FM-stereo */
- { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0480, 0x0030, 0x3000},
-
- /* Sat FM-mono */
- { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- 0x00c6, 0x0480, 0x0000, 0x3000},
-
- /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
- { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0040, 0x0120, 0x3000},
-
- /* NICAM/FM -- I (6.0/6.552) */
- { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(6.0), MSP_CARRIER(6.0),
- 0x00d0, 0x0040, 0x0120, 0x3000},
-
- /* NICAM/AM -- L (6.5/5.85) */
- { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 },
- MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- 0x00c6, 0x0140, 0x0120, 0x7c03},
-};
-
-struct CARRIER_DETECT {
- int cdo;
- char *name;
-};
-
-static struct CARRIER_DETECT carrier_detect_main[] = {
- /* main carrier */
- { MSP_CARRIER(4.5), "4.5 NTSC" },
- { MSP_CARRIER(5.5), "5.5 PAL B/G" },
- { MSP_CARRIER(6.0), "6.0 PAL I" },
- { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
-};
-
-static struct CARRIER_DETECT carrier_detect_55[] = {
- /* PAL B/G */
- { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
- { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
-};
-
-static struct CARRIER_DETECT carrier_detect_65[] = {
- /* PAL SAT / SECAM */
- { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },
- { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
- { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
- { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
- { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
- { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
-};
-
-#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
-
-/* ------------------------------------------------------------------------ */
-
-static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
-{
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
-}
-
-static void msp3400c_setvolume(struct i2c_client *client, int left, int right)
-{
- int vol,val,balance;
-
- vol = (left > right) ? left : right;
- val = (vol * 0x73 / 65535) << 8;
- balance = 0;
- if (vol > 0)
- balance = ((right-left) * 127) / vol;
-
- dprintk("msp34xx: setvolume: %d:%d 0x%02x 0x%02x\n",
- left,right,val>>8,balance);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
- /* scart - on/off only */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, balance << 8);
-}
-
-static void msp3400c_setbass(struct i2c_client *client, int bass)
-{
- int val = ((bass-32768) * 0x60 / 65535) << 8;
-
- dprintk("msp34xx: setbass: %d 0x%02x\n",bass, val>>8);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
-}
-
-static void msp3400c_settreble(struct i2c_client *client, int treble)
-{
- int val = ((treble-32768) * 0x60 / 65535) << 8;
-
- dprintk("msp34xx: settreble: %d 0x%02x\n",treble, val>>8);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
-}
-
-static void msp3400c_setmode(struct i2c_client *client, int type)
-{
- struct msp3400c *msp = client->data;
- int i;
-
- dprintk("msp3400: setmode: %d\n",type);
- msp->mode = type;
- msp->stereo = VIDEO_SOUND_MONO;
-
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */
- msp_init_data[type].ad_cv);
-
- for (i = 5; i >= 0; i--) /* fir 1 */
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001,
- msp_init_data[type].fir1[i]);
-
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040);
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000);
- for (i = 5; i >= 0; i--)
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005,
- msp_init_data[type].fir2[i]);
-
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */
- msp_init_data[type].mode_reg);
-
- msp3400c_setcarrier(client, msp_init_data[type].cdo1,
- msp_init_data[type].cdo2);
-
- msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
-
- if (dolby) {
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
- 0x0520); /* I2S1 */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
- 0x0620); /* I2S2 */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
- msp_init_data[type].dfp_src);
- } else {
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
- msp_init_data[type].dfp_src);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
- msp_init_data[type].dfp_src);
- }
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
- msp_init_data[type].dfp_src);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
- msp_init_data[type].dfp_matrix);
-
- if (msp->nicam) {
- /* nicam prescale */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
- }
-}
-
-/* turn on/off nicam + stereo */
-static void msp3400c_setstereo(struct i2c_client *client, int mode)
-{
- struct msp3400c *msp = client->data;
- int nicam=0; /* channel source: FM/AM or nicam */
- int src=0;
-
- /* switch demodulator */
- switch (msp->mode) {
- case MSP_MODE_FM_TERRA:
- dprintk("msp3400: FM setstereo: %d\n",mode);
- msp3400c_setcarrier(client,msp->second,msp->main);
- switch (mode) {
- case VIDEO_SOUND_STEREO:
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
- break;
- case VIDEO_SOUND_MONO:
- case VIDEO_SOUND_LANG1:
- case VIDEO_SOUND_LANG2:
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000);
- break;
- }
- break;
- case MSP_MODE_FM_SAT:
- dprintk("msp3400: SAT setstereo: %d\n",mode);
- switch (mode) {
- case VIDEO_SOUND_MONO:
- msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
- break;
- case VIDEO_SOUND_STEREO:
- msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
- break;
- case VIDEO_SOUND_LANG1:
- msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
- break;
- case VIDEO_SOUND_LANG2:
- msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
- break;
- }
- break;
- case MSP_MODE_FM_NICAM1:
- case MSP_MODE_FM_NICAM2:
- case MSP_MODE_AM_NICAM:
- dprintk("msp3400: NICAM setstereo: %d\n",mode);
- msp3400c_setcarrier(client,msp->second,msp->main);
- if (msp->nicam_on)
- nicam=0x0100;
- break;
- case MSP_MODE_BTSC:
- dprintk("msp3400: BTSC setstereo: %d\n",mode);
- nicam=0x0300;
- break;
- default:
- dprintk("msp3400: mono setstereo\n");
- return;
- }
-
- /* switch audio */
- switch (mode) {
- case VIDEO_SOUND_STEREO:
- src = 0x0020 | nicam;
-#if 0
- /* spatial effect */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000);
-#endif
- break;
- case VIDEO_SOUND_MONO:
- if (msp->mode == MSP_MODE_AM_NICAM) {
- dprintk("msp3400: switching to AM mono\n");
- /* AM mono decoding is handled by tuner, not MSP chip */
- /* so let's redirect sound from tuner via SCART */
- /* volume prescale for SCART */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
- /* SCART switching control register*/
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, 0xe900);
- src = 0x0200;
- break;
- }
- case VIDEO_SOUND_LANG1:
- src = 0x0000 | nicam;
- break;
- case VIDEO_SOUND_LANG2:
- src = 0x0010 | nicam;
- break;
- }
- if (dolby) {
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
- } else {
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
- }
-}
-
-static void
-msp3400c_print_mode(struct msp3400c *msp)
-{
- if (msp->main == msp->second) {
- printk("msp3400: mono sound carrier: %d.%03d MHz\n",
- msp->main/910000,(msp->main/910)%1000);
- } else {
- printk("msp3400: main sound carrier: %d.%03d MHz\n",
- msp->main/910000,(msp->main/910)%1000);
- }
- if (msp->mode == MSP_MODE_FM_NICAM1 ||
- msp->mode == MSP_MODE_FM_NICAM2)
- printk("msp3400: NICAM/FM carrier : %d.%03d MHz\n",
- msp->second/910000,(msp->second/910)%1000);
- if (msp->mode == MSP_MODE_AM_NICAM)
- printk("msp3400: NICAM/AM carrier : %d.%03d MHz\n",
- msp->second/910000,(msp->second/910)%1000);
- if (msp->mode == MSP_MODE_FM_TERRA &&
- msp->main != msp->second) {
- printk("msp3400: FM-stereo carrier : %d.%03d MHz\n",
- msp->second/910000,(msp->second/910)%1000);
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct REGISTER_DUMP {
- int addr;
- char *name;
-};
-
-struct REGISTER_DUMP d1[] = {
- { 0x007e, "autodetect" },
- { 0x0023, "C_AD_BITS " },
- { 0x0038, "ADD_BITS " },
- { 0x003e, "CIB_BITS " },
- { 0x0057, "ERROR_RATE" },
-};
-
-static int
-autodetect_stereo(struct i2c_client *client)
-{
- struct msp3400c *msp = client->data;
- int val;
- int newstereo = msp->stereo;
- int newnicam = msp->nicam_on;
- int update = 0;
-
- switch (msp->mode) {
- case MSP_MODE_FM_TERRA:
- val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
- if (val > 32768)
- val -= 65536;
- dprintk("msp34xx: stereo detect register: %d\n",val);
-
- if (val > 4096) {
- newstereo = VIDEO_SOUND_STEREO | VIDEO_SOUND_MONO;
- } else if (val < -4096) {
- newstereo = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
- } else {
- newstereo = VIDEO_SOUND_MONO;
- }
- newnicam = 0;
- break;
- case MSP_MODE_FM_NICAM1:
- case MSP_MODE_FM_NICAM2:
- case MSP_MODE_AM_NICAM:
- val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
- dprintk("msp34xx: nicam sync=%d, mode=%d\n",val & 1, (val & 0x1e) >> 1);
-
- if (val & 1) {
- /* nicam synced */
- switch ((val & 0x1e) >> 1) {
- case 0:
- case 8:
- newstereo = VIDEO_SOUND_STEREO;
- break;
- case 1:
- case 9:
- newstereo = VIDEO_SOUND_MONO
- | VIDEO_SOUND_LANG1;
- break;
- case 2:
- case 10:
- newstereo = VIDEO_SOUND_MONO
- | VIDEO_SOUND_LANG1
- | VIDEO_SOUND_LANG2;
- break;
- default:
- newstereo = VIDEO_SOUND_MONO;
- break;
- }
- newnicam=1;
- } else {
- newnicam = 0;
- newstereo = VIDEO_SOUND_MONO;
- }
- break;
- case MSP_MODE_BTSC:
- val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
- dprintk("msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
- val,
- (val & 0x0002) ? "no" : "yes",
- (val & 0x0004) ? "no" : "yes",
- (val & 0x0040) ? "stereo" : "mono",
- (val & 0x0080) ? ", nicam 2nd mono" : "",
- (val & 0x0100) ? ", bilingual/SAP" : "");
- newstereo = VIDEO_SOUND_MONO;
- if (val & 0x0040) newstereo |= VIDEO_SOUND_STEREO;
- if (val & 0x0100) newstereo |= VIDEO_SOUND_LANG1;
- break;
- }
- if (newstereo != msp->stereo) {
- update = 1;
- dprintk("msp34xx: watch: stereo %d => %d\n",
- msp->stereo,newstereo);
- msp->stereo = newstereo;
- }
- if (newnicam != msp->nicam_on) {
- update = 1;
- dprintk("msp34xx: watch: nicam %d => %d\n",
- msp->nicam_on,newnicam);
- msp->nicam_on = newnicam;
- }
- return update;
-}
-
-/*
- * A kernel thread for msp3400 control -- we don't want to block the
- * in the ioctl while doing the sound carrier & stereo detect
- */
-
-static void msp3400c_stereo_wake(unsigned long data)
-{
- struct msp3400c *msp = (struct msp3400c*)data; /* XXX alpha ??? */
-
- wake_up_interruptible(&msp->wq);
-}
-
-/* stereo/multilang monitoring */
-static void watch_stereo(struct i2c_client *client)
-{
- struct msp3400c *msp = client->data;
-
- if (autodetect_stereo(client)) {
- if (msp->stereo & VIDEO_SOUND_STEREO)
- msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
- else if (msp->stereo & VIDEO_SOUND_LANG1)
- msp3400c_setstereo(client,VIDEO_SOUND_LANG1);
- else
- msp3400c_setstereo(client,VIDEO_SOUND_MONO);
- }
- if (once)
- msp->watch_stereo = 0;
- if (msp->watch_stereo)
- mod_timer(&msp->wake_stereo, jiffies+5*HZ);
-}
-
-static int msp3400c_thread(void *data)
-{
- struct i2c_client *client = data;
- struct msp3400c *msp = client->data;
-
- struct CARRIER_DETECT *cd;
- int count, max1,max2,val1,val2, val,this;
-
-#ifdef CONFIG_SMP
- lock_kernel();
-#endif
-
- daemonize();
- sigfillset(&current->blocked);
- strcpy(current->comm,"msp3400");
-
- msp->thread = current;
-
-#ifdef CONFIG_SMP
- unlock_kernel();
-#endif
-
- printk("msp3400: daemon started\n");
- if(msp->notify != NULL)
- up(msp->notify);
-
- for (;;) {
- if (msp->rmmod)
- goto done;
- if (debug > 1)
- printk("msp3400: thread: sleep\n");
- interruptible_sleep_on(&msp->wq);
- if (debug > 1)
- printk("msp3400: thread: wakeup\n");
- if (msp->rmmod || signal_pending(current))
- goto done;
-
- if (VIDEO_MODE_RADIO == msp->norm)
- continue; /* nothing to do */
-
- msp->active = 1;
-
- if (msp->watch_stereo) {
- watch_stereo(client);
- msp->active = 0;
- continue;
- }
-
- /* some time for the tuner to sync */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/5);
- if (signal_pending(current))
- goto done;
-
- restart:
- msp->restart = 0;
- msp3400c_setvolume(client, 0, 0);
- msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
- val1 = val2 = 0;
- max1 = max2 = -1;
- del_timer(&msp->wake_stereo);
- msp->watch_stereo = 0;
-
- /* carrier detect pass #1 -- main carrier */
- cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
-
- if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
- /* autodetect doesn't work well with AM ... */
- max1 = 3;
- count = 0;
- dprintk("msp3400: AM sound override\n");
- }
-
- for (this = 0; this < count; this++) {
- msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
- if (signal_pending(current))
- goto done;
- if (msp->restart)
- msp->restart = 0;
-
- val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
- if (val > 32768)
- val -= 65536;
- if (val1 < val)
- val1 = val, max1 = this;
- dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name);
- }
-
- /* carrier detect pass #2 -- second (stereo) carrier */
- switch (max1) {
- case 1: /* 5.5 */
- cd = carrier_detect_55; count = CARRIER_COUNT(carrier_detect_55);
- break;
- case 3: /* 6.5 */
- cd = carrier_detect_65; count = CARRIER_COUNT(carrier_detect_65);
- break;
- case 0: /* 4.5 */
- case 2: /* 6.0 */
- default:
- cd = NULL; count = 0;
- break;
- }
-
- if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
- /* autodetect doesn't work well with AM ... */
- cd = NULL; count = 0; max2 = 0;
- }
- for (this = 0; this < count; this++) {
- msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
- if (signal_pending(current))
- goto done;
- if (msp->restart)
- goto restart;
-
- val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
- if (val > 32768)
- val -= 65536;
- if (val2 < val)
- val2 = val, max2 = this;
- dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name);
- }
-
- /* programm the msp3400 according to the results */
- msp->main = carrier_detect_main[max1].cdo;
- switch (max1) {
- case 1: /* 5.5 */
- if (max2 == 0) {
- /* B/G FM-stereo */
- msp->second = carrier_detect_55[max2].cdo;
- msp3400c_setmode(client, MSP_MODE_FM_TERRA);
- msp->nicam_on = 0;
- msp3400c_setstereo(client, VIDEO_SOUND_MONO);
- msp->watch_stereo = 1;
- } else if (max2 == 1 && msp->nicam) {
- /* B/G NICAM */
- msp->second = carrier_detect_55[max2].cdo;
- msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
- msp->nicam_on = 1;
- msp3400c_setcarrier(client, msp->second, msp->main);
- msp->watch_stereo = 1;
- } else {
- goto no_second;
- }
- break;
- case 2: /* 6.0 */
- /* PAL I NICAM */
- msp->second = MSP_CARRIER(6.552);
- msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
- msp->nicam_on = 1;
- msp3400c_setcarrier(client, msp->second, msp->main);
- msp->watch_stereo = 1;
- break;
- case 3: /* 6.5 */
- if (max2 == 1 || max2 == 2) {
- /* D/K FM-stereo */
- msp->second = carrier_detect_65[max2].cdo;
- msp3400c_setmode(client, MSP_MODE_FM_TERRA);
- msp->nicam_on = 0;
- msp3400c_setstereo(client, VIDEO_SOUND_MONO);
- msp->watch_stereo = 1;
- } else if (max2 == 0 &&
- msp->norm == VIDEO_MODE_SECAM) {
- /* L NICAM or AM-mono */
- msp->second = carrier_detect_65[max2].cdo;
- msp3400c_setmode(client, MSP_MODE_AM_NICAM);
- msp->nicam_on = 0;
- msp3400c_setstereo(client, VIDEO_SOUND_MONO);
- msp3400c_setcarrier(client, msp->second, msp->main);
- msp->watch_stereo = 1;
- } else if (max2 == 0 && msp->nicam) {
- /* D/K NICAM */
- msp->second = carrier_detect_65[max2].cdo;
- msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
- msp->nicam_on = 1;
- msp3400c_setcarrier(client, msp->second, msp->main);
- msp->watch_stereo = 1;
- } else {
- goto no_second;
- }
- break;
- case 0: /* 4.5 */
- default:
- no_second:
- msp->second = carrier_detect_main[max1].cdo;
- msp3400c_setmode(client, MSP_MODE_FM_TERRA);
- msp->nicam_on = 0;
- msp3400c_setcarrier(client, msp->second, msp->main);
- msp->stereo = VIDEO_SOUND_MONO;
- msp3400c_setstereo(client, VIDEO_SOUND_MONO);
- break;
- }
-
- /* unmute */
- msp3400c_setvolume(client, msp->left, msp->right);
-
- if (msp->watch_stereo)
- mod_timer(&msp->wake_stereo, jiffies+5*HZ);
-
- if (debug)
- msp3400c_print_mode(msp);
-
- msp->active = 0;
- }
-
-done:
- dprintk("msp3400: thread: exit\n");
- msp->active = 0;
- msp->thread = NULL;
-
- if(msp->notify != NULL)
- up(msp->notify);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-/* this one uses the automatic sound standard detection of newer */
-/* msp34xx chip versions */
-
-static struct MODES {
- int retval;
- int main, second;
- char *name;
-} modelist[] = {
- { 0x0000, 0, 0, "ERROR" },
- { 0x0001, 0, 0, "autodetect start" },
- { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" },
- { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" },
- { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
- { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
- { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
- { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
- { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
- { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
- { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
- { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
- { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
- { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
- { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
- { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" },
- { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" },
- { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" },
- { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" },
- { -1, 0, 0, NULL }, /* EOF */
-};
-
-static int msp3410d_thread(void *data)
-{
- struct i2c_client *client = data;
- struct msp3400c *msp = client->data;
- int mode,val,i,std;
-
-#ifdef CONFIG_SMP
- lock_kernel();
-#endif
-
- daemonize();
- sigfillset(&current->blocked);
- strcpy(current->comm,"msp3410 [auto]");
-
- msp->thread = current;
-
-#ifdef CONFIG_SMP
- unlock_kernel();
-#endif
-
- printk("msp3410: daemon started\n");
- if(msp->notify != NULL)
- up(msp->notify);
-
- for (;;) {
- if (msp->rmmod)
- goto done;
- if (debug > 1)
- printk("msp3410: thread: sleep\n");
- interruptible_sleep_on(&msp->wq);
- if (debug > 1)
- printk("msp3410: thread: wakeup\n");
- if (msp->rmmod || signal_pending(current))
- goto done;
-
- if (VIDEO_MODE_RADIO == msp->norm)
- continue; /* nothing to do */
-
- msp->active = 1;
-
- if (msp->watch_stereo) {
- watch_stereo(client);
- msp->active = 0;
- continue;
- }
-
- /* some time for the tuner to sync */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/5);
- if (signal_pending(current))
- goto done;
-
- restart:
- msp->restart = 0;
- del_timer(&msp->wake_stereo);
- msp->watch_stereo = 0;
-
- /* put into sane state (and mute) */
- msp3400c_reset(client);
-
- /* start autodetect */
- switch (msp->norm) {
- case VIDEO_MODE_PAL:
- mode = 0x1003;
- std = 1;
- break;
- case VIDEO_MODE_NTSC: /* BTSC */
- mode = 0x2003;
- std = 0x0020;
- break;
- case VIDEO_MODE_SECAM:
- mode = 0x0003;
- std = 1;
- break;
- default:
- mode = 0x0003;
- std = 1;
- break;
- }
- msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
- msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403);
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00);
- if (debug) {
- int i;
- for (i = 0; modelist[i].name != NULL; i++)
- if (modelist[i].retval == std)
- break;
- printk("msp3410: setting mode: %s (0x%04x)\n",
- modelist[i].name ? modelist[i].name : "unknown",std);
- }
-
- if (std != 1) {
- /* programmed some specific mode */
- val = std;
- } else {
- /* triggered autodetect */
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
- if (signal_pending(current))
- goto done;
- if (msp->restart)
- goto restart;
-
- /* check results */
- val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
- if (val < 0x07ff)
- break;
- dprintk("msp3410: detection still in progress\n");
- }
- }
- for (i = 0; modelist[i].name != NULL; i++)
- if (modelist[i].retval == val)
- break;
- dprintk("msp3410: current mode: %s (0x%04x)\n",
- modelist[i].name ? modelist[i].name : "unknown",
- val);
- msp->main = modelist[i].main;
- msp->second = modelist[i].second;
-
- if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
- /* autodetection has failed, let backup */
- dprintk("msp3410: autodetection failed, switching to backup mode: %s (0x%04x)\n",
- modelist[8].name ? modelist[8].name : "unknown",val);
- val = 0x0009;
- msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
- }
-
- /* set prescale / stereo */
- switch (val) {
- case 0x0009:
- msp->mode = MSP_MODE_AM_NICAM;
- msp->stereo = VIDEO_SOUND_MONO;
- msp3400c_setstereo(client,VIDEO_SOUND_MONO);
- msp->watch_stereo = 1;
- break;
- case 0x0020: /* BTSC */
- /* just turn on stereo */
- msp->mode = MSP_MODE_BTSC;
- msp->stereo = VIDEO_SOUND_STEREO;
- msp->watch_stereo = 1;
- msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
- /* set prescale */
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
- break;
- case 0x0003:
- msp->mode = MSP_MODE_FM_TERRA;
- msp->stereo = VIDEO_SOUND_MONO;
- msp->watch_stereo = 1;
- /* fall */
- default:
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* NICAM */
- break;
- }
-
- /* unmute */
- msp3400c_setbass(client, msp->bass);
- msp3400c_settreble(client, msp->treble);
- msp3400c_setvolume(client, msp->left, msp->right);
-
- if (msp->watch_stereo)
- mod_timer(&msp->wake_stereo, jiffies+HZ);
-
- msp->active = 0;
- }
-
-done:
- dprintk("msp3410: thread: exit\n");
- msp->active = 0;
- msp->thread = NULL;
-
- if(msp->notify != NULL)
- up(msp->notify);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int msp_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind);
-static int msp_detach(struct i2c_client *client);
-static int msp_probe(struct i2c_adapter *adap);
-static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
-
-static struct i2c_driver driver = {
- "i2c msp3400 driver",
- I2C_DRIVERID_MSP3400,
- I2C_DF_NOTIFY,
- msp_probe,
- msp_detach,
- msp_command,
-};
-
-static struct i2c_client client_template =
-{
- "unset",
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-static int msp_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- DECLARE_MUTEX_LOCKED(sem);
- struct msp3400c *msp;
- struct i2c_client *c;
- int rev1,rev2,i;
-
- client_template.adapter = adap;
- client_template.addr = addr;
-
- if (-1 == msp3400c_reset(&client_template)) {
- dprintk("msp3400: no chip found\n");
- return -1;
- }
-
- if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
- return -ENOMEM;
- memcpy(c,&client_template,sizeof(struct i2c_client));
- if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
- kfree(c);
- return -ENOMEM;
- }
-
- memset(msp,0,sizeof(struct msp3400c));
- msp->left = 65535;
- msp->right = 65535;
- msp->bass = 32768;
- msp->treble = 32768;
- c->data = msp;
- init_waitqueue_head(&msp->wq);
-
- if (-1 == msp3400c_reset(c)) {
- kfree(msp);
- dprintk("msp3400: no chip found\n");
- return -1;
- }
-
- rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e);
- rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f);
- if (0 == rev1 && 0 == rev2) {
- kfree(msp);
- printk("msp3400: error while reading chip version\n");
- return -1;
- }
-
-#if 0
- /* this will turn on a 1kHz beep - might be useful for debugging... */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0014, 0x1040);
-#endif
-
- sprintf(c->name,"MSP34%02d%c-%c%d",
- (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
- msp->nicam = (((rev2>>8)&0xff) != 00) ? 1 : 0;
-
- if (simple == -1) {
- /* default mode */
- /* msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; */
- msp->simple = ((rev1&0xff)+'@' > 'C');
- } else {
- /* use insmod option */
- msp->simple = simple;
- }
-
- /* timer for stereo checking */
- msp->wake_stereo.function = msp3400c_stereo_wake;
- msp->wake_stereo.data = (unsigned long)msp;
-
- /* hello world :-) */
- printk(KERN_INFO "msp3400: init: chip=%s",c->name);
- if (msp->nicam)
- printk(", has NICAM support");
- printk("\n");
-
- /* startup control thread */
- MOD_INC_USE_COUNT;
- msp->notify = &sem;
- kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread,
- (void *)c, 0);
- down(&sem);
- msp->notify = NULL;
- wake_up_interruptible(&msp->wq);
-
-#ifdef REGISTER_MIXER
- if ((msp->mixer_num = register_sound_mixer(&msp3400c_mixer_fops,mixer)) < 0)
- printk(KERN_ERR "msp3400c: cannot allocate mixer device\n");
-#endif
-
- /* update our own array */
- for (i = 0; i < MSP3400_MAX; i++) {
- if (NULL == msps[i]) {
- msps[i] = c;
- break;
- }
- }
-
- /* done */
- i2c_attach_client(c);
- return 0;
-}
-
-static int msp_detach(struct i2c_client *client)
-{
- DECLARE_MUTEX_LOCKED(sem);
- struct msp3400c *msp = (struct msp3400c*)client->data;
- int i;
-
-#ifdef REGISTER_MIXER
- if (msp->mixer_num >= 0)
- unregister_sound_mixer(msp->mixer_num);
-#endif
-
- /* shutdown control thread */
- del_timer(&msp->wake_stereo);
- if (msp->thread)
- {
- msp->notify = &sem;
- msp->rmmod = 1;
- wake_up_interruptible(&msp->wq);
- down(&sem);
- msp->notify = NULL;
- }
- msp3400c_reset(client);
-
- /* update our own array */
- for (i = 0; i < MSP3400_MAX; i++) {
- if (client == msps[i]) {
- msps[i] = NULL;
- break;
- }
- }
-
- i2c_detach_client(client);
- kfree(msp);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int msp_probe(struct i2c_adapter *adap)
-{
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, msp_attach);
- return 0;
-}
-
-static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
-{
- struct msp3400c *msp = (struct msp3400c*)client->data;
-#if 0
- int *iarg = (int*)arg;
- __u16 *sarg = arg;
-#endif
-
- switch (cmd) {
-
- case AUDC_SET_RADIO:
- msp->norm = VIDEO_MODE_RADIO;
- msp->watch_stereo=0;
- del_timer(&msp->wake_stereo);
- if (msp->simple) {
- msp3400c_reset(client);
- msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, 0x0003); /* automatic */
- msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, 0x0040); /* FM Radio */
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM prescale */
- msp3400c_setbass(client, msp->bass);
- msp3400c_settreble(client, msp->treble);
- msp3400c_setvolume(client, msp->left, msp->right);
- } else {
- msp3400c_setmode(client,MSP_MODE_FM_RADIO);
- msp3400c_setcarrier(client, MSP_CARRIER(10.7),MSP_CARRIER(10.7));
- msp3400c_setvolume(client,msp->left, msp->right);
- }
- break;
-
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- va->flags |= VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
- va->volume=MAX(msp->left,msp->right);
- va->balance=(32768*MIN(msp->left,msp->right))/
- (va->volume ? va->volume : 1);
- va->balance=(msp->left<msp->right)?
- (65535-va->balance) : va->balance;
- va->bass = msp->bass;
- va->treble = msp->treble;
-
- autodetect_stereo(client);
- va->mode = msp->stereo;
- break;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
-
- msp->left = (MIN(65536 - va->balance,32768) *
- va->volume) / 32768;
- msp->right = (MIN(va->balance,32768) *
- va->volume) / 32768;
- msp->bass = va->bass;
- msp->treble = va->treble;
- msp3400c_setvolume(client,msp->left, msp->right);
- msp3400c_setbass(client,msp->bass);
- msp3400c_settreble(client,msp->treble);
-
- if (va->mode != 0) {
- msp->watch_stereo=0;
- del_timer(&msp->wake_stereo);
- msp->stereo = va->mode;
- msp3400c_setstereo(client,va->mode);
- }
- break;
- }
- case VIDIOCSCHAN:
- {
- struct video_channel *vc = arg;
-
- msp->norm = vc->norm;
- break;
- }
- case VIDIOCSFREQ:
- {
- /* new channel -- kick audio carrier scan */
- msp3400c_setvolume(client,0,0);
- msp->watch_stereo=0;
- del_timer(&msp->wake_stereo);
- if (msp->active)
- msp->restart = 1;
- wake_up_interruptible(&msp->wq);
- break;
- }
-
- /* --- v4l2 ioctls --- */
- /* NOT YET */
-
-#if 0
- /* --- old, obsolete interface --- */
- case AUDC_SET_TVNORM:
- msp->norm = *iarg;
- break;
- case AUDC_SWITCH_MUTE:
- /* channels switching step one -- mute */
- msp->watch_stereo=0;
- del_timer(&msp->wake_stereo);
- msp3400c_setvolume(client,0,0);
- break;
- case AUDC_NEWCHANNEL:
- /* channels switching step two -- trigger sound carrier scan */
- msp->watch_stereo=0;
- del_timer(&msp->wake_stereo);
- if (msp->active)
- msp->restart = 1;
- wake_up_interruptible(&msp->wq);
- break;
-
- case AUDC_GET_VOLUME_LEFT:
- *sarg = msp->left;
- break;
- case AUDC_GET_VOLUME_RIGHT:
- *sarg = msp->right;
- break;
- case AUDC_SET_VOLUME_LEFT:
- msp->left = *sarg;
- msp3400c_setvolume(client,msp->left, msp->right);
- break;
- case AUDC_SET_VOLUME_RIGHT:
- msp->right = *sarg;
- msp3400c_setvolume(client,msp->left, msp->right);
- break;
-
- case AUDC_GET_BASS:
- *sarg = msp->bass;
- break;
- case AUDC_SET_BASS:
- msp->bass = *sarg;
- msp3400c_setbass(client,msp->bass);
- break;
-
- case AUDC_GET_TREBLE:
- *sarg = msp->treble;
- break;
- case AUDC_SET_TREBLE:
- msp->treble = *sarg;
- msp3400c_settreble(client,msp->treble);
- break;
-
- case AUDC_GET_STEREO:
- autodetect_stereo(client);
- *sarg = msp->stereo;
- break;
- case AUDC_SET_STEREO:
- if (*sarg) {
- msp->watch_stereo=0;
- del_timer(&msp->wake_stereo);
- msp->stereo = *sarg;
- msp3400c_setstereo(client,*sarg);
- }
- break;
-
- case AUDC_GET_DC:
- if (msp->simple)
- break; /* fixme */
- *sarg = ((int)msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b) +
- (int)msp3400c_read(client, I2C_MSP3400C_DFP, 0x1c));
- break;
-#endif
- default:
- /* nothing */
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-int msp3400_init_module(void)
-{
- i2c_add_driver(&driver);
- return 0;
-}
-
-void msp3400_cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-
-module_init(msp3400_init_module);
-module_exit(msp3400_cleanup_module);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 8cf8a15a7..e99d92856 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -19,6 +19,8 @@
#include <asm/uaccess.h>
#include <asm/irq.h>
+#include <asm/mach-types.h>
+
#define __NWBUTTON_C /* Tell the header file who we are */
#include "nwbutton.h"
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index 5be07b769..8b5c266a6 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -18,6 +18,7 @@
#include <asm/dec21285.h>
#include <asm/io.h>
#include <asm/leds.h>
+#include <asm/mach-types.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/pcxx.c b/drivers/char/pcxx.c
index 757af9c14..7629e24ad 100644
--- a/drivers/char/pcxx.c
+++ b/drivers/char/pcxx.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/char/pcxe.c
+ * linux/drivers/char/pcxx.c
*
* Written by Troy De Jongh, November, 1994
*
@@ -12,13 +12,11 @@
* This driver does NOT support DigiBoard's fastcook FEP option and
* does not support the transparent print (i.e. digiprint) option.
*
- * This Driver is currently maintained by Christoph Lameter (clameter@fuller.edu)
- * Please contact the mailing list for problems first.
+ * This Driver is currently maintained by Christoph Lameter (christoph@lameter.com)
*
- * Sources of Information:
- * 1. The Linux Digiboard Page at http://private.fuller.edu/clameter/digi.html
- * 2. The Linux Digiboard Mailing list at digiboard@list.fuller.edu
- * (Simply write a message to introduce yourself to subscribe)
+ * Please contact digi for support issues at digilnux@dgii.com. Some
+ * information (mostly of historical interest) can be found at
+ * http://lameter.com/digi.
*
* 1.5.2 Fall 1995 Bug fixes by David Nugent
* 1.5.3 March 9, 1996 Christoph Lameter: Fixed 115.2K Support. Memory
@@ -39,6 +37,8 @@
* verbose messages to assist user during card configuration.
* Currently only tested on a PC/Xi card, but should work on Xe
* and Xeve also.
+ * 1.6.2 August, 7, 2000: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * get rid of panics, release previously allocated resources
*
*/
@@ -81,7 +81,7 @@
#include <asm/bitops.h>
#include <asm/semaphore.h>
-#define VERSION "1.6.1"
+#define VERSION "1.6.2"
#include "digi.h"
#include "fep.h"
@@ -193,6 +193,30 @@ static inline void assertmemoff(struct channel *ch);
#define TZ_BUFSZ 4096
/* function definitions */
+
+/*****************************************************************************/
+
+static void cleanup_board_resources(void)
+{
+ int crd, i;
+ struct board_info *bd;
+ struct channel *ch;
+
+ for(crd = 0; crd < numcards; crd++) {
+ bd = &boards[crd];
+ ch = digi_channels + bd->first_minor;
+
+ if (bd->region)
+ release_region(bd->port, 4);
+
+ for(i = 0; i < bd->numports; i++, ch++)
+ if (ch->tmp_buf)
+ kfree(ch->tmp_buf);
+ }
+}
+
+/*****************************************************************************/
+
#ifdef MODULE
/*
@@ -209,10 +233,7 @@ void cleanup_module()
{
unsigned long flags;
- int crd, i;
int e1, e2;
- struct board_info *bd;
- struct channel *ch;
printk(KERN_NOTICE "Unloading PC/Xx version %s\n", VERSION);
@@ -226,14 +247,7 @@ void cleanup_module()
if ((e2 = tty_unregister_driver(&pcxe_callout)))
printk("SERIAL: failed to unregister callout driver (%d)\n",e2);
- for(crd=0; crd < numcards; crd++) {
- bd = &boards[crd];
- ch = digi_channels+bd->first_minor;
- for(i=0; i < bd->numports; i++, ch++) {
- kfree(ch->tmp_buf);
- }
- release_region(bd->port, 4);
- }
+ cleanup_board_resources();
kfree(digi_channels);
kfree(pcxe_termios_locked);
kfree(pcxe_termios);
@@ -620,7 +634,7 @@ static void pcxe_close(struct tty_struct * tty, struct file * filp)
** worth noting that while I'm not sure what this hunk of code is supposed
** to do, it is not present in the serial.c driver. Hmmm. If you know,
** please send me a note. brian@ilinx.com
-** Don't know either what this is supposed to do clameter@waterf.org.
+** Don't know either what this is supposed to do christoph@lameter.com.
*/
if(tty->ldisc.num != ldiscs[N_TTY].num) {
if(tty->ldisc.close)
@@ -1090,6 +1104,7 @@ int __init pcxe_init(void)
{
ulong memory_seg=0, memory_size=0;
int lowwater, enabled_cards=0, i, crd, shrinkmem=0, topwin = 0xff00L, botwin=0x100L;
+ int ret = -ENOMEM;
unchar *fepos, *memaddr, *bios, v;
volatile struct global_data *gd;
volatile struct board_chan *bc;
@@ -1099,7 +1114,7 @@ int __init pcxe_init(void)
printk(KERN_NOTICE "Digiboard PC/X{i,e,eve} driver v%s\n", VERSION);
#ifdef MODULE
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < MAX_DIGI_BOARDS; i++) {
if (io[i]) {
numcards = 0;
break;
@@ -1108,7 +1123,7 @@ int __init pcxe_init(void)
if (numcards == 0) {
int first_minor = 0;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < MAX_DIGI_BOARDS; i++) {
if (io[i] == 0) {
boards[i].port = 0;
boards[i].status = DISABLED;
@@ -1139,6 +1154,7 @@ int __init pcxe_init(void)
else
boards[i].numports = 16;
+ boards[i].region = NULL;
first_minor += boards[i].numports;
}
}
@@ -1178,23 +1194,31 @@ int __init pcxe_init(void)
* unused spaces.
*/
digi_channels = kmalloc(sizeof(struct channel) * nbdevs, GFP_KERNEL);
- if (!digi_channels)
- panic("Unable to allocate digi_channel struct");
+ if (!digi_channels) {
+ printk(KERN_ERR "Unable to allocate digi_channel struct\n");
+ return -ENOMEM;
+ }
memset(digi_channels, 0, sizeof(struct channel) * nbdevs);
pcxe_table = kmalloc(sizeof(struct tty_struct *) * nbdevs, GFP_KERNEL);
- if (!pcxe_table)
- panic("Unable to allocate pcxe_table struct");
+ if (!pcxe_table) {
+ printk(KERN_ERR "Unable to allocate pcxe_table struct\n");
+ goto cleanup_digi_channels;
+ }
memset(pcxe_table, 0, sizeof(struct tty_struct *) * nbdevs);
pcxe_termios = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL);
- if (!pcxe_termios)
- panic("Unable to allocate pcxe_termios struct");
+ if (!pcxe_termios) {
+ printk(KERN_ERR "Unable to allocate pcxe_termios struct\n");
+ goto cleanup_pcxe_table;
+ }
memset(pcxe_termios,0,sizeof(struct termios *)*nbdevs);
pcxe_termios_locked = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL);
- if (!pcxe_termios_locked)
- panic("Unable to allocate pcxe_termios_locked struct");
+ if (!pcxe_termios_locked) {
+ printk(KERN_ERR "Unable to allocate pcxe_termios_locked struct\n");
+ goto cleanup_pcxe_termios;
+ }
memset(pcxe_termios_locked,0,sizeof(struct termios *)*nbdevs);
init_bh(DIGI_BH,do_pcxe_bh);
@@ -1512,7 +1536,13 @@ load_fep:
if((bd->type == PCXEVE) && (*(ushort *)((ulong)memaddr+NPORT) < 3))
shrinkmem = 1;
- request_region(bd->port, 4, "PC/Xx");
+ bd->region = request_region(bd->port, 4, "PC/Xx");
+
+ if (!bd->region) {
+ printk(KERN_ERR "I/O port 0x%x is already used\n", bd->port);
+ ret = -EBUSY;
+ goto cleanup_boards;
+ }
for(i=0; i < bd->numports; i++, ch++, bc++) {
if(((ushort *)((ulong)memaddr + PORTBASE))[i] == 0) {
@@ -1562,6 +1592,12 @@ load_fep:
ch->txbufsize = bc->tmax + 1;
ch->rxbufsize = bc->rmax + 1;
ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
+
+ if (!ch->tmp_buf) {
+ printk(KERN_ERR "Unable to allocate memory for temp buffers\n");
+ goto cleanup_boards;
+ }
+
lowwater = ch->txbufsize >= 2000 ? 1024 : ch->txbufsize/2;
fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);
fepcmd(ch, SRXLWATER, ch->rxbufsize/4, 0, 10, 0);
@@ -1608,14 +1644,21 @@ load_fep:
if (enabled_cards <= 0) {
printk(KERN_NOTICE "PC/Xx: No cards enabled, no driver.\n");
- return -EIO;
+ ret = -EIO;
+ goto cleanup_boards;
}
- if(tty_register_driver(&pcxe_driver))
- panic("Couldn't register PC/Xe driver");
+ ret = tty_register_driver(&pcxe_driver);
+ if(ret) {
+ printk(KERN_ERR "Couldn't register PC/Xe driver\n");
+ goto cleanup_boards;
+ }
- if(tty_register_driver(&pcxe_callout))
- panic("Couldn't register PC/Xe callout");
+ ret = tty_register_driver(&pcxe_callout);
+ if(ret) {
+ printk(KERN_ERR "Couldn't register PC/Xe callout\n");
+ goto cleanup_pcxe_driver;
+ }
/*
* Start up the poller to check for events on all enabled boards
@@ -1626,6 +1669,13 @@ load_fep:
printk(KERN_NOTICE "PC/Xx: Driver with %d card(s) ready.\n", enabled_cards);
return 0;
+cleanup_pcxe_driver: tty_unregister_driver(&pcxe_driver);
+cleanup_boards: cleanup_board_resources();
+ kfree(pcxe_termios_locked);
+cleanup_pcxe_termios: kfree(pcxe_termios);
+cleanup_pcxe_table: kfree(pcxe_table);
+cleanup_digi_channels: kfree(digi_channels);
+ return ret;
}
diff --git a/drivers/char/pcxx.h b/drivers/char/pcxx.h
index 6d7a08b85..464fbe061 100644
--- a/drivers/char/pcxx.h
+++ b/drivers/char/pcxx.h
@@ -51,6 +51,7 @@ struct board_info {
ulong membase;
ulong memsize;
ushort first_minor;
+ void *region;
};
diff --git a/drivers/char/planb.c b/drivers/char/planb.c
deleted file mode 100644
index 94707619d..000000000
--- a/drivers/char/planb.c
+++ /dev/null
@@ -1,2341 +0,0 @@
-/*
- planb - PlanB frame grabber driver
-
- PlanB is used in the 7x00/8x00 series of PowerMacintosh
- Computers as video input DMA controller.
-
- Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
- Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
-
- Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
-
- 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 of the License, 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.
-*/
-
-/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */
-
-#include <linux/version.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/malloc.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/wrapper.h>
-#include <linux/tqueue.h>
-#include <linux/videodev.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/dbdma.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-
-#include "planb.h"
-#include "saa7196.h"
-
-
-/* Would you mind for some ugly debugging? */
-//#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
-#define DEBUG(x...) /* Don't debug driver */
-//#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
-#define IDEBUG(x...) /* Don't debug interrupt part */
-
-/* Ever seen a Mac with more than 1 of these? */
-#define PLANB_MAX 1
-
-static int planb_num;
-static struct planb planbs[PLANB_MAX];
-static volatile struct planb_registers *planb_regs;
-
-static int def_norm = PLANB_DEF_NORM; /* default norm */
-
-MODULE_PARM(def_norm, "i");
-MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
-
-/* ------------------ PlanB Exported Functions ------------------ */
-static long planb_write(struct video_device *, const char *, unsigned long, int);
-static long planb_read(struct video_device *, char *, unsigned long, int);
-static int planb_open(struct video_device *, int);
-static void planb_close(struct video_device *);
-static int planb_ioctl(struct video_device *, unsigned int, void *);
-static int planb_init_done(struct video_device *);
-static int planb_mmap(struct video_device *, const char *, unsigned long);
-static void planb_irq(int, void *, struct pt_regs *);
-static void release_planb(void);
-int init_planbs(struct video_init *);
-
-/* ------------------ PlanB Internal Functions ------------------ */
-static int planb_prepare_open(struct planb *);
-static void planb_prepare_close(struct planb *);
-static void saa_write_reg(unsigned char, unsigned char);
-static unsigned char saa_status(int, struct planb *);
-static void saa_set(unsigned char, unsigned char, struct planb *);
-static void saa_init_regs(struct planb *);
-static int grabbuf_alloc(struct planb *);
-static int vgrab(struct planb *, struct video_mmap *);
-static void add_clip(struct planb *, struct video_clip *);
-static void fill_cmd_buff(struct planb *);
-static void cmd_buff(struct planb *);
-static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *);
-static void overlay_start(struct planb *);
-static void overlay_stop(struct planb *);
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short,
- unsigned int);
-static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int,
- unsigned int);
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short,
- unsigned short, unsigned int, unsigned int);
-static int init_planb(struct planb *);
-static int find_planb(void);
-static void planb_pre_capture(int, int, struct planb *);
-static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *,
- int, int, int, int, int, struct planb *);
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *);
-static unsigned int saa_geo_setup(int, int, int, int, struct planb *);
-static inline int overlay_is_active(struct planb *);
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-static int grabbuf_alloc(struct planb *pb)
-{
- int i, npage;
-
- npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1)
-#ifndef PLANB_GSCANLINE
- + MAX_LNUM
-#endif /* PLANB_GSCANLINE */
- );
- if ((pb->rawbuf = (unsigned char**) kmalloc (npage
- * sizeof(unsigned long), GFP_KERNEL)) == 0)
- return -ENOMEM;
- for (i = 0; i < npage; i++) {
- pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL
- |GFP_DMA, 0);
- if (!pb->rawbuf[i])
- break;
- mem_map_reserve(virt_to_page(pb->rawbuf[i]));
- }
- if (i-- < npage) {
- printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n");
- for (; i > 0; i--) {
- mem_map_unreserve(virt_to_page(pb->rawbuf[i]));
- free_pages((unsigned long)pb->rawbuf[i], 0);
- }
- kfree(pb->rawbuf);
- return -ENOBUFS;
- }
- pb->rawbuf_size = npage;
- return 0;
-}
-
-/*****************************/
-/* Hardware access functions */
-/*****************************/
-
-static void saa_write_reg(unsigned char addr, unsigned char val)
-{
- planb_regs->saa_addr = addr; eieio();
- planb_regs->saa_regval = val; eieio();
- return;
-}
-
-/* return status byte 0 or 1: */
-static unsigned char saa_status(int byte, struct planb *pb)
-{
- saa_regs[pb->win.norm][SAA7196_STDC] =
- (saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1);
- saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]);
-
- /* Let's wait 30msec for this one */
- current->state = TASK_INTERRUPTIBLE;
-#if LINUX_VERSION_CODE >= 0x02017F
- schedule_timeout(30 * HZ / 1000);
-#else
- current->timeout = jiffies + 30 * HZ / 1000; /* 30 ms */;
- schedule();
-#endif
-
- return (unsigned char)in_8 (&planb_regs->saa_status);
-}
-
-static void saa_set(unsigned char addr, unsigned char val, struct planb *pb)
-{
- if(saa_regs[pb->win.norm][addr] != val) {
- saa_regs[pb->win.norm][addr] = val;
- saa_write_reg (addr, val);
- }
- return;
-}
-
-static void saa_init_regs(struct planb *pb)
-{
- int i;
-
- for (i = 0; i < SAA7196_NUMREGS; i++)
- saa_write_reg (i, saa_regs[pb->win.norm][i]);
-}
-
-static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp,
- struct planb *pb)
-{
- int ht, norm = pb->win.norm;
-
- switch(bpp) {
- case 2:
- /* RGB555+a 1x16-bit + 16-bit transparent */
- saa_regs[norm][SAA7196_FMTS] &= ~0x3;
- break;
- case 1:
- case 4:
- /* RGB888 1x24-bit + 8-bit transparent */
- saa_regs[norm][SAA7196_FMTS] &= ~0x1;
- saa_regs[norm][SAA7196_FMTS] |= 0x2;
- break;
- default:
- return -EINVAL;
- }
- ht = (interlace ? height / 2 : height);
- saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff);
- saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3)
- | (width >> 8 & 0x3);
- saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff);
- saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3)
- | (ht >> 8 & 0x3);
- /* feed both fields if interlaced, or else feed only even fields */
- saa_regs[norm][SAA7196_FMTS] = (interlace) ?
- (saa_regs[norm][SAA7196_FMTS] & ~0x60)
- : (saa_regs[norm][SAA7196_FMTS] | 0x60);
- /* transparent mode; extended format enabled */
- saa_regs[norm][SAA7196_DPATH] |= 0x3;
-
- return 0;
-}
-
-/***************************/
-/* DBDMA support functions */
-/***************************/
-
-static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch)
-{
- out_le32(&ch->control, PLANB_CLR(RUN));
- out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE));
-}
-
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch)
-{
- int i = 0;
-
- out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH));
- while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
- IDEBUG("PlanB: waiting for DMA to stop\n");
- i++;
- }
-}
-
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch,
- unsigned short command, unsigned int cmd_dep)
-{
- st_le16(&ch->command, command);
- st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static inline void tab_cmd_store(volatile struct dbdma_cmd *ch,
- unsigned int phy_addr, unsigned int cmd_dep)
-{
- st_le16(&ch->command, STORE_WORD | KEY_SYSTEM);
- st_le16(&ch->req_count, 4);
- st_le32(&ch->phy_addr, phy_addr);
- st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch,
- unsigned short command, unsigned short req_count,
- unsigned int phy_addr, unsigned int cmd_dep)
-{
- st_le16(&ch->command, command);
- st_le16(&ch->req_count, req_count);
- st_le32(&ch->phy_addr, phy_addr);
- st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static volatile struct dbdma_cmd *cmd_geo_setup(
- volatile struct dbdma_cmd *c1, int width, int height, int interlace,
- int bpp, int clip, struct planb *pb)
-{
- int norm = pb->win.norm;
-
- if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0)
- return (volatile struct dbdma_cmd *)NULL;
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_FMTS);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_FMTS]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_DPATH);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_DPATH]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even),
- bpp | ((clip)? PLANB_CLIPMASK: 0));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd),
- bpp | ((clip)? PLANB_CLIPMASK: 0));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_OUTPIX);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_OUTPIX]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_HFILT);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_HFILT]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_OUTLINE);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_OUTLINE]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_VYP);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_VYP]);
- return c1;
-}
-
-/******************************/
-/* misc. supporting functions */
-/******************************/
-
-static void __planb_wait(struct planb *pb)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&pb->lockq, &wait);
-repeat:
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (pb->lock) {
- schedule();
- goto repeat;
- }
- remove_wait_queue(&pb->lockq, &wait);
- current->state = TASK_RUNNING;
-}
-
-static inline void planb_wait(struct planb *pb)
-{
- DEBUG("PlanB: planb_wait\n");
- if(pb->lock)
- __planb_wait(pb);
-}
-
-static inline void planb_lock(struct planb *pb)
-{
- DEBUG("PlanB: planb_lock\n");
- if(pb->lock)
- __planb_wait(pb);
- pb->lock = 1;
-}
-
-static inline void planb_unlock(struct planb *pb)
-{
- DEBUG("PlanB: planb_unlock\n");
- pb->lock = 0;
- wake_up(&pb->lockq);
-}
-
-/***************/
-/* Driver Core */
-/***************/
-
-static int planb_prepare_open(struct planb *pb)
-{
- int i, size;
-
- /* allocate memory for two plus alpha command buffers (size: max lines,
- plus 40 commands handling, plus 1 alignment), plus dummy command buf,
- plus clipmask buffer, plus frame grabbing status */
- size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS
- * PLANB_DUMMY)*sizeof(struct dbdma_cmd)
- +(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8
- +MAX_GBUFFERS*sizeof(unsigned int);
- if ((pb->priv_space = kmalloc (size, GFP_KERNEL)) == 0)
- return -ENOMEM;
- memset ((void *) pb->priv_space, 0, size);
- pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *)
- DBDMA_ALIGN (pb->priv_space);
- pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size;
- pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd);
- pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size;
- pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR;
- for (i = 1; i < MAX_GBUFFERS; i++) {
- pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY;
- pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR;
- }
- pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1]
- + PLANB_DUMMY);
- pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS);
-
- pb->rawbuf = NULL;
- pb->rawbuf_size = 0;
- pb->grabbing = 0;
- for (i = 0; i < MAX_GBUFFERS; i++) {
- pb->frame_stat[i] = GBUFFER_UNUSED;
- pb->gwidth[i] = 0;
- pb->gheight[i] = 0;
- pb->gfmt[i] = 0;
- pb->gnorm_switch[i] = 0;
-#ifndef PLANB_GSCANLINE
- pb->lsize[i] = 0;
- pb->lnum[i] = 0;
-#endif /* PLANB_GSCANLINE */
- }
- pb->gcount = 0;
- pb->suspend = 0;
- pb->last_fr = -999;
- pb->prev_last_fr = -999;
-
- /* Reset DMA controllers */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
-
- return 0;
-}
-
-static void planb_prepare_close(struct planb *pb)
-{
- int i;
-
- /* make sure the dma's are idle */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- /* free kernel memory of command buffers */
- if(pb->priv_space != 0) {
- kfree (pb->priv_space);
- pb->priv_space = 0;
- pb->cmd_buff_inited = 0;
- }
- if(pb->rawbuf) {
- for (i = 0; i < pb->rawbuf_size; i++) {
- mem_map_unreserve(virt_to_page(pb->rawbuf[i]));
- free_pages((unsigned long)pb->rawbuf[i], 0);
- }
- kfree(pb->rawbuf);
- }
- pb->rawbuf = NULL;
-}
-
-/*****************************/
-/* overlay support functions */
-/*****************************/
-
-static void overlay_start(struct planb *pb)
-{
-
- DEBUG("PlanB: overlay_start()\n");
-
- if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
-
- DEBUG("PlanB: presumably, grabbing is in progress...\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- out_le32 (&pb->planb_base->ch2.cmdptr,
- virt_to_bus(pb->ch2_cmd));
- planb_dbdma_restart(&pb->planb_base->ch2);
- st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
- tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->ch1_cmd));
- eieio();
- pb->prev_last_fr = pb->last_fr;
- pb->last_fr = -2;
- if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
- IDEBUG("PlanB: became inactive "
- "in the mean time... reactivating\n");
- planb_dbdma_stop(&pb->planb_base->ch1);
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->ch1_cmd));
- planb_dbdma_restart(&pb->planb_base->ch1);
- }
- } else {
-
- DEBUG("PlanB: currently idle, so can do whatever\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- st_le32 (&pb->planb_base->ch2.cmdptr,
- virt_to_bus(pb->ch2_cmd));
- st_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->ch1_cmd));
- out_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
- planb_dbdma_restart(&pb->planb_base->ch2);
- planb_dbdma_restart(&pb->planb_base->ch1);
- pb->last_fr = -1;
- }
- return;
-}
-
-static void overlay_stop(struct planb *pb)
-{
- DEBUG("PlanB: overlay_stop()\n");
-
- if(pb->last_fr == -1) {
-
- DEBUG("PlanB: no grabbing, it seems...\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- pb->last_fr = -999;
- } else if(pb->last_fr == -2) {
- unsigned int cmd_dep;
- tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0);
- eieio();
- cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep);
- if(overlay_is_active(pb)) {
-
- DEBUG("PlanB: overlay is currently active\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- if(cmd_dep != pb->ch1_cmd_phys) {
- out_le32(&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->overlay_last1));
- planb_dbdma_restart(&pb->planb_base->ch1);
- }
- }
- pb->last_fr = pb->prev_last_fr;
- pb->prev_last_fr = -999;
- }
- return;
-}
-
-static void suspend_overlay(struct planb *pb)
-{
- int fr = -1;
- struct dbdma_cmd last;
-
- DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend);
-
- if(pb->suspend++)
- return;
- if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
- if(pb->last_fr == -2) {
- fr = pb->prev_last_fr;
- memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last));
- tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
- }
- if(overlay_is_active(pb)) {
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- pb->suspended.overlay = 1;
- pb->suspended.frame = fr;
- memcpy(&pb->suspended.cmd, &last, sizeof(last));
- return;
- }
- }
- pb->suspended.overlay = 0;
- pb->suspended.frame = fr;
- memcpy(&pb->suspended.cmd, &last, sizeof(last));
- return;
-}
-
-static void resume_overlay(struct planb *pb)
-{
-
- DEBUG("PlanB: resume_overlay: %d\n", pb->suspend);
-
- if(pb->suspend > 1)
- return;
- if(pb->suspended.frame != -1) {
- memcpy((void*)pb->last_cmd[pb->suspended.frame],
- &pb->suspended.cmd, sizeof(pb->suspended.cmd));
- }
- if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
- goto finish;
- }
- if(pb->suspended.overlay) {
-
- DEBUG("PlanB: overlay being resumed\n");
-
- st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
- st_le16 (&pb->ch2_cmd->command, DBDMA_NOP);
- /* Set command buffer addresses */
- st_le32(&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->overlay_last1));
- out_le32(&pb->planb_base->ch2.cmdptr,
- virt_to_bus(pb->overlay_last2));
- /* Start the DMA controller */
- out_le32 (&pb->planb_base->ch2.control,
- PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
- out_le32 (&pb->planb_base->ch1.control,
- PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
- } else if(pb->suspended.frame != -1) {
- out_le32(&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->last_cmd[pb->suspended.frame]));
- out_le32 (&pb->planb_base->ch1.control,
- PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
- }
-
-finish:
- pb->suspend--;
- wake_up_interruptible(&pb->suspendq);
-}
-
-static void add_clip(struct planb *pb, struct video_clip *clip)
-{
- volatile unsigned char *base;
- int xc = clip->x, yc = clip->y;
- int wc = clip->width, hc = clip->height;
- int ww = pb->win.width, hw = pb->win.height;
- int x, y, xtmp1, xtmp2;
-
- DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);
-
- if(xc < 0) {
- wc += xc;
- xc = 0;
- }
- if(yc < 0) {
- hc += yc;
- yc = 0;
- }
- if(xc + wc > ww)
- wc = ww - xc;
- if(wc <= 0) /* Nothing to do */
- return;
- if(yc + hc > hw)
- hc = hw - yc;
-
- for (y = yc; y < yc+hc; y++) {
- xtmp1=xc>>3;
- xtmp2=(xc+wc)>>3;
- base = pb->mask + y*96;
- if(xc != 0 || wc >= 8)
- *(base + xtmp1) &= (unsigned char)(0x00ff &
- (0xff00 >> (xc&7)));
- for (x = xtmp1 + 1; x < xtmp2; x++) {
- *(base + x) = 0;
- }
- if(xc < (ww & ~0x7))
- *(base + xtmp2) &= (unsigned char)(0x00ff >>
- ((xc+wc) & 7));
- }
-
- return;
-}
-
-static void fill_cmd_buff(struct planb *pb)
-{
- int restore = 0;
- volatile struct dbdma_cmd last;
-
- DEBUG("PlanB: fill_cmd_buff()\n");
-
- if(pb->overlay_last1 != pb->ch1_cmd) {
- restore = 1;
- last = *(pb->overlay_last1);
- }
- memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size
- * sizeof(struct dbdma_cmd));
- cmd_buff (pb);
- if(restore)
- *(pb->overlay_last1) = last;
- if(pb->suspended.overlay) {
- unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep);
- if(jump_addr != pb->ch1_cmd_phys) {
- int i;
-
- DEBUG("PlanB: adjusting ch1's jump address\n");
-
- for(i = 0; i < MAX_GBUFFERS; i++) {
- if(pb->need_pre_capture[i]) {
- if(jump_addr == virt_to_bus(pb->pre_cmd[i]))
- goto found;
- } else {
- if(jump_addr == virt_to_bus(pb->cap_cmd[i]))
- goto found;
- }
- }
-
- DEBUG("PlanB: not found...\n");
-
- goto out;
-found:
- if(pb->need_pre_capture[i])
- out_le32(&pb->pre_cmd[i]->phy_addr,
- virt_to_bus(pb->overlay_last1));
- else
- out_le32(&pb->cap_cmd[i]->phy_addr,
- virt_to_bus(pb->overlay_last1));
- }
- }
-out:
- pb->cmd_buff_inited = 1;
-
- return;
-}
-
-static void cmd_buff(struct planb *pb)
-{
- int i, bpp, count, nlines, stepsize, interlace;
- unsigned long base, jump, addr_com, addr_dep;
- volatile struct dbdma_cmd *c1 = pb->ch1_cmd;
- volatile struct dbdma_cmd *c2 = pb->ch2_cmd;
-
- interlace = pb->win.interlace;
- bpp = pb->win.bpp;
- count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ?
- (pb->win.swidth - pb->win.x) : pb->win.width));
- nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ?
- (pb->win.sheight - pb->win.y) : pb->win.height);
-
- /* Do video in: */
-
- /* Preamble commands: */
- addr_com = virt_to_bus(c1);
- addr_dep = virt_to_bus(&c1->cmd_dep);
- tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
- jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */
- if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
- bpp, 1, pb)) == NULL) {
- printk(KERN_WARNING "PlanB: encountered serious problems\n");
- tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0);
- tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0);
- return;
- }
- tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);
- tab_cmd_store(c1++, addr_dep, jump);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
- PLANB_SET(FIELD_SYNC));
- /* (1) wait for field sync to be set */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- /* wait for field sync to be cleared */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- /* if not odd field, wait until field sync is set again */
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
- /* assert ch_sync to ch2 */
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
- PLANB_SET(CH_SYNC));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl
- + pb->win.pad) + pb->win.x * bpp);
-
- if (interlace) {
- stepsize = 2;
- jump = virt_to_bus(c1 + (nlines + 1) / 2);
- } else {
- stepsize = 1;
- jump = virt_to_bus(c1 + nlines);
- }
-
- /* even field data: */
- for (i=0; i < nlines; i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
- count, base + i * (pb->win.bpl + pb->win.pad), jump);
-
- /* For non-interlaced, we use even fields only */
- if (!interlace)
- goto cmd_tab_data_end;
-
- /* Resync to odd field */
- /* (2) wait for field sync to be set */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- /* wait for field sync to be cleared */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- /* if not odd field, wait until field sync is set again */
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
- /* assert ch_sync to ch2 */
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
- PLANB_SET(CH_SYNC));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- /* odd field data: */
- jump = virt_to_bus(c1 + nlines / 2);
- for (i=1; i < nlines; i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
- base + i * (pb->win.bpl + pb->win.pad), jump);
-
- /* And jump back to the start */
-cmd_tab_data_end:
- pb->overlay_last1 = c1; /* keep a pointer to the last command */
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd));
-
- /* Clipmask command buffer */
-
- /* Preamble commands: */
- tab_cmd_dbdma(c2++, DBDMA_NOP, 0);
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
- PLANB_SET(CH_SYNC));
- /* wait until ch1 asserts ch_sync */
- tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
- /* clear ch_sync asserted by ch1 */
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control),
- PLANB_CLR(CH_SYNC));
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
- PLANB_SET(FIELD_SYNC));
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
- PLANB_SET(ODD_FIELD));
-
- /* jump to end of even field if appropriate */
- /* this points to (interlace)? pos. C: pos. B */
- jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2):
- virt_to_bus(c2 + nlines + 2);
- /* if odd field, skip over to odd field clipmasking */
- tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);
-
- /* even field mask: */
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
- PLANB_SET(DMA_ABORT));
- /* this points to pos. B */
- jump = (interlace) ? virt_to_bus(c2 + nlines + 1):
- virt_to_bus(c2 + nlines);
- base = virt_to_bus(pb->mask);
- for (i=0; i < nlines; i += stepsize, c2++)
- tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
- base + i * 96, jump);
-
- /* For non-interlaced, we use only even fields */
- if(!interlace)
- goto cmd_tab_mask_end;
-
- /* odd field mask: */
-/* C */ tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
- PLANB_SET(DMA_ABORT));
- /* this points to pos. B */
- jump = virt_to_bus(c2 + nlines / 2);
- base = virt_to_bus(pb->mask);
- for (i=1; i < nlines; i += 2, c2++) /* abort if set */
- tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
- base + i * 96, jump);
-
- /* Inform channel 1 and jump back to start */
-cmd_tab_mask_end:
- /* ok, I just realized this is kind of flawed. */
- /* this part is reached only after odd field clipmasking. */
- /* wanna clean up? */
- /* wait for field sync to be set */
- /* corresponds to fsync (1) of ch1 */
-/* B */ tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
- /* restart ch1, meant to clear any dead bit or something */
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
- PLANB_CLR(RUN));
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
- PLANB_SET(RUN));
- pb->overlay_last2 = c2; /* keep a pointer to the last command */
- /* start over even field clipmasking */
- tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd));
-
- eieio();
- return;
-}
-
-/*********************************/
-/* grabdisplay support functions */
-/*********************************/
-
-static int palette2fmt[] = {
- 0,
- PLANB_GRAY,
- 0,
- 0,
- 0,
- PLANB_COLOUR32,
- PLANB_COLOUR15,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
-};
-
-#define PLANB_PALETTE_MAX 15
-
-static inline int overlay_is_active(struct planb *pb)
-{
- unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd);
- unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr);
-
- return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys)
- && (caddr < (pb->ch1_cmd_phys + size))
- && (caddr >= (unsigned)pb->ch1_cmd_phys);
-}
-
-static int vgrab(struct planb *pb, struct video_mmap *mp)
-{
- unsigned int fr = mp->frame;
- unsigned int format;
-
- if(pb->rawbuf==NULL) {
- int err;
- if((err=grabbuf_alloc(pb)))
- return err;
- }
-
- IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing,
- mp->width, mp->height, fr);
-
- if(pb->grabbing >= MAX_GBUFFERS)
- return -ENOBUFS;
- if(fr > (MAX_GBUFFERS - 1) || fr < 0)
- return -EINVAL;
- if(mp->height <= 0 || mp->width <= 0)
- return -EINVAL;
- if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX)
- return -EINVAL;
- if((format = palette2fmt[mp->format]) == 0)
- return -EINVAL;
- if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */
- return -EINVAL;
-
- planb_lock(pb);
- if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] ||
- format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) {
- int i;
-#ifndef PLANB_GSCANLINE
- unsigned int osize = pb->gwidth[fr] * pb->gheight[fr]
- * pb->gfmt[fr];
- unsigned int nsize = mp->width * mp->height * format;
-#endif
-
- IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n",
- mp->width, mp->height, mp->format);
-
-#ifndef PLANB_GSCANLINE
- if(pb->gnorm_switch[fr])
- nsize = 0;
- if (nsize < osize) {
- for(i = pb->gbuf_idx[fr]; osize > 0; i++) {
- memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
- osize -= PAGE_SIZE;
- }
- }
- for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr]
- + pb->lnum[fr]; i++)
- memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
-#else
-/* XXX TODO */
-/*
- if(pb->gnorm_switch[fr])
- memset((void *)pb->gbuffer[fr], 0,
- pb->gbytes_per_line * pb->gheight[fr]);
- else {
- if(mp->
- for(i = 0; i < pb->gheight[fr]; i++) {
- memset((void *)(pb->gbuffer[fr]
- + pb->gbytes_per_line * i
- }
- }
-*/
-#endif
- pb->gwidth[fr] = mp->width;
- pb->gheight[fr] = mp->height;
- pb->gfmt[fr] = format;
- pb->last_cmd[fr] = setup_grab_cmd(fr, pb);
- planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */
- pb->need_pre_capture[fr] = 1;
- pb->gnorm_switch[fr] = 0;
- } else
- pb->need_pre_capture[fr] = 0;
- pb->frame_stat[fr] = GBUFFER_GRABBING;
- if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-
- IDEBUG("PlanB: ch1 inactive, initiating grabbing\n");
-
- planb_dbdma_stop(&pb->planb_base->ch1);
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->pre_cmd[fr]));
- } else {
- tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
- tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
- /* let's be on the safe side. here is not timing critical. */
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0);
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->cap_cmd[fr]));
- }
- planb_dbdma_restart(&pb->planb_base->ch1);
- pb->last_fr = fr;
- } else {
- int i;
-
- IDEBUG("PlanB: ch1 active, grabbing being queued\n");
-
- if((pb->last_fr == -1) || ((pb->last_fr == -2) &&
- overlay_is_active(pb))) {
-
- IDEBUG("PlanB: overlay is active, grabbing defered\n");
-
- tab_cmd_dbdma(pb->last_cmd[fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->ch1_cmd));
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- tab_cmd_store(pb->pre_cmd[fr],
- virt_to_bus(&pb->overlay_last1->cmd_dep),
- virt_to_bus(pb->ch1_cmd));
- eieio();
- out_le32 (&pb->overlay_last1->cmd_dep,
- virt_to_bus(pb->pre_cmd[fr]));
- } else {
- tab_cmd_store(pb->cap_cmd[fr],
- virt_to_bus(&pb->overlay_last1->cmd_dep),
- virt_to_bus(pb->ch1_cmd));
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP, 0);
- eieio();
- out_le32 (&pb->overlay_last1->cmd_dep,
- virt_to_bus(pb->cap_cmd[fr]));
- }
- for(i = 0; overlay_is_active(pb) && i < 999; i++)
- IDEBUG("PlanB: waiting for overlay done\n");
- tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
- pb->prev_last_fr = fr;
- pb->last_fr = -2;
- } else if(pb->last_fr == -2) {
-
- IDEBUG("PlanB: mixed mode detected, grabbing"
- " will be done before activating overlay\n");
-
- tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->pre_cmd[fr]));
- eieio();
- } else {
- tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
- if(pb->gwidth[pb->prev_last_fr] !=
- pb->gwidth[fr]
- || pb->gheight[pb->prev_last_fr] !=
- pb->gheight[fr]
- || pb->gfmt[pb->prev_last_fr] !=
- pb->gfmt[fr])
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP, 0);
- else
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr] + 16));
- tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr]));
- eieio();
- }
- tab_cmd_dbdma(pb->last_cmd[fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->ch1_cmd));
- eieio();
- pb->prev_last_fr = fr;
- pb->last_fr = -2;
- } else {
-
- IDEBUG("PlanB: active grabbing session detected\n");
-
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->pre_cmd[fr]));
- eieio();
- } else {
- tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
- tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
- if(pb->gwidth[pb->last_fr] != pb->gwidth[fr]
- || pb->gheight[pb->last_fr] !=
- pb->gheight[fr]
- || pb->gfmt[pb->last_fr] !=
- pb->gfmt[fr])
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP, 0);
- else
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr] + 16));
- tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr]));
- eieio();
- }
- pb->last_fr = fr;
- }
- if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-
- IDEBUG("PlanB: became inactive in the mean time..."
- "reactivating\n");
-
- planb_dbdma_stop(&pb->planb_base->ch1);
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->cap_cmd[fr]));
- planb_dbdma_restart(&pb->planb_base->ch1);
- }
- }
- pb->grabbing++;
- planb_unlock(pb);
-
- return 0;
-}
-
-static void planb_pre_capture(int fr, int bpp, struct planb *pb)
-{
- volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr];
- int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
-
- tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
- if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
- bpp, 0, pb)) == NULL) {
- printk(KERN_WARNING "PlanB: encountered some problems\n");
- tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0);
- return;
- }
- /* Sync to even field */
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
- PLANB_SET(FIELD_SYNC));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
- tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
- /* For non-interlaced, we use even fields only */
- if (pb->gheight[fr] <= pb->maxlines/2)
- goto cmd_tab_data_end;
- /* Sync to odd field */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-cmd_tab_data_end:
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr]));
-
- eieio();
-}
-
-static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb)
-{
- int i, bpp, count, nlines, stepsize, interlace;
-#ifdef PLANB_GSCANLINE
- int scanline;
-#else
- int nlpp, leftover1;
- unsigned long base;
-#endif
- unsigned long jump;
- int pagei;
- volatile struct dbdma_cmd *c1;
- volatile struct dbdma_cmd *jump_addr;
-
- c1 = pb->cap_cmd[fr];
- interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
- bpp = pb->gfmt[fr]; /* gfmt = bpp */
- count = bpp * pb->gwidth[fr];
- nlines = pb->gheight[fr];
-#ifdef PLANB_GSCANLINE
- scanline = pb->gbytes_per_line;
-#else
- pb->lsize[fr] = count;
- pb->lnum[fr] = 0;
-#endif
-
- /* Do video in: */
-
- /* Preamble commands: */
- tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++;
- if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
- bpp, 0, pb)) == NULL) {
- printk(KERN_WARNING "PlanB: encountered serious problems\n");
- tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0);
- return (pb->cap_cmd[fr] + 2);
- }
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
- PLANB_SET(FIELD_SYNC));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
- tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- if (interlace) {
- stepsize = 2;
- jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2;
- } else {
- stepsize = 1;
- jump_addr = c1 + TAB_FACTOR * nlines;
- }
- jump = virt_to_bus(jump_addr);
-
- /* even field data: */
-
- pagei = pb->gbuf_idx[fr];
-#ifdef PLANB_GSCANLINE
- for (i = 0; i < nlines; i += stepsize) {
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pagei
- + i * scanline / PAGE_SIZE]), jump);
- }
-#else
- i = 0;
- leftover1 = 0;
- do {
- int j;
-
- base = virt_to_bus(pb->rawbuf[pagei]);
- nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
- for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
- count, base + count * j * stepsize + leftover1, jump);
- if(i < nlines) {
- int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
-
- if(lov0 == 0)
- leftover1 = 0;
- else {
- if(lov0 >= count) {
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base
- + count * nlpp * stepsize + leftover1, jump);
- } else {
- pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
- + count * nlpp * stepsize + leftover1;
- pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
- pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0;
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
- + pb->lnum[fr]]), jump);
- if(++pb->lnum[fr] > MAX_LNUM)
- pb->lnum[fr]--;
- }
- leftover1 = count * stepsize - lov0;
- i += stepsize;
- }
- }
- pagei++;
- } while(i < nlines);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
- c1 = jump_addr;
-#endif /* PLANB_GSCANLINE */
-
- /* For non-interlaced, we use even fields only */
- if (!interlace)
- goto cmd_tab_data_end;
-
- /* Sync to odd field */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- /* odd field data: */
- jump_addr = c1 + TAB_FACTOR * nlines / 2;
- jump = virt_to_bus(jump_addr);
-#ifdef PLANB_GSCANLINE
- for (i = 1; i < nlines; i += stepsize) {
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pagei
- + i * scanline / PAGE_SIZE]), jump);
- }
-#else
- i = 1;
- leftover1 = 0;
- pagei = pb->gbuf_idx[fr];
- if(nlines <= 1)
- goto skip;
- do {
- int j;
-
- base = virt_to_bus(pb->rawbuf[pagei]);
- nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
- if(leftover1 >= count) {
- tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
- base + leftover1 - count, jump);
- i += stepsize;
- }
- for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
- base + count * (j * stepsize + 1) + leftover1, jump);
- if(i < nlines) {
- int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
-
- if(lov0 == 0)
- leftover1 = 0;
- else {
- if(lov0 > count) {
- pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
- + count * (nlpp * stepsize + 1) + leftover1;
- pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
- pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize
- - lov0;
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
- + pb->lnum[fr]]), jump);
- if(++pb->lnum[fr] > MAX_LNUM)
- pb->lnum[fr]--;
- i += stepsize;
- }
- leftover1 = count * stepsize - lov0;
- }
- }
- pagei++;
- } while(i < nlines);
-skip:
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
- c1 = jump_addr;
-#endif /* PLANB_GSCANLINE */
-
-cmd_tab_data_end:
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat),
- (fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ);
- /* stop it */
- tab_cmd_dbdma(c1, DBDMA_STOP, 0);
-
- eieio();
- return c1;
-}
-
-static void planb_irq(int irq, void *dev_id, struct pt_regs * regs)
-{
- unsigned int stat, astat;
- struct planb *pb = (struct planb *)dev_id;
-
- IDEBUG("PlanB: planb_irq()\n");
-
- /* get/clear interrupt status bits */
- eieio();
- stat = in_le32(&pb->planb_base->intr_stat);
- astat = stat & pb->intr_mask;
- out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ
- & ~astat & stat & ~PLANB_GEN_IRQ);
- IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat);
-
- if(astat & PLANB_FRM_IRQ) {
- unsigned int fr = stat >> 9;
-#ifndef PLANB_GSCANLINE
- int i;
-#endif
- IDEBUG("PlanB: PLANB_FRM_IRQ\n");
-
- pb->gcount++;
-
- IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n",
- pb->grabbing, fr, pb->gcount);
-#ifndef PLANB_GSCANLINE
- IDEBUG("PlanB: %d * %d bytes are being copied over\n",
- pb->lnum[fr], pb->lsize[fr]);
- for(i = 0; i < pb->lnum[fr]; i++) {
- int first = pb->lsize[fr] - pb->l_to_next_size[fr][i];
-
- memcpy(pb->l_to_addr[fr][i],
- pb->rawbuf[pb->l_fr_addr_idx[fr] + i],
- first);
- memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]],
- pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first,
- pb->l_to_next_size[fr][i]);
- }
-#endif
- pb->frame_stat[fr] = GBUFFER_DONE;
- pb->grabbing--;
- wake_up_interruptible(&pb->capq);
- return;
- }
- /* incorrect interrupts? */
- pb->intr_mask = PLANB_CLR_IRQ;
- out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
- printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts"
- " unconditionally\n");
-}
-
-/*******************************
- * Device Operations functions *
- *******************************/
-
-static int planb_open(struct video_device *dev, int mode)
-{
- struct planb *pb = (struct planb *)dev;
-
- if (pb->user == 0) {
- int err;
- if((err = planb_prepare_open(pb)) != 0)
- return err;
- }
- pb->user++;
-
- DEBUG("PlanB: device opened\n");
-
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void planb_close(struct video_device *dev)
-{
- struct planb *pb = (struct planb *)dev;
-
- if(pb->user < 1) /* ??? */
- return;
- planb_lock(pb);
- if (pb->user == 1) {
- if (pb->overlay) {
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- pb->overlay = 0;
- }
- planb_prepare_close(pb);
- }
- pb->user--;
- planb_unlock(pb);
-
- DEBUG("PlanB: device closed\n");
-
- MOD_DEC_USE_COUNT;
-}
-
-static long planb_read(struct video_device *v, char *buf, unsigned long count,
- int nonblock)
-{
- DEBUG("planb: read request\n");
- return -EINVAL;
-}
-
-static long planb_write(struct video_device *v, const char *buf,
- unsigned long count, int nonblock)
-{
- DEBUG("planb: write request\n");
- return -EINVAL;
-}
-
-static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct planb *pb=(struct planb *)dev;
-
- switch (cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability b;
-
- DEBUG("PlanB: IOCTL VIDIOCGCAP\n");
-
- strcpy (b.name, pb->video_dev.name);
- b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
- VID_TYPE_FRAMERAM | VID_TYPE_SCALES |
- VID_TYPE_CAPTURE;
- b.channels = 2; /* composite & svhs */
- b.audios = 0;
- b.maxwidth = PLANB_MAXPIXELS;
- b.maxheight = PLANB_MAXLINES;
- b.minwidth = 32; /* wild guess */
- b.minheight = 32;
- if (copy_to_user(arg,&b,sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
- unsigned short bpp;
- unsigned int fmt;
-
- DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
-
- if (!capable(CAP_SYS_ADMIN)
- || !capable(CAP_SYS_RAWIO))
- return -EPERM;
- if (copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- planb_lock(pb);
- switch(v.depth) {
- case 8:
- bpp = 1;
- fmt = PLANB_GRAY;
- break;
- case 15:
- case 16:
- bpp = 2;
- fmt = PLANB_COLOUR15;
- break;
- case 24:
- case 32:
- bpp = 4;
- fmt = PLANB_COLOUR32;
- break;
- default:
- planb_unlock(pb);
- return -EINVAL;
- }
- if (bpp * v.width > v.bytesperline) {
- planb_unlock(pb);
- return -EINVAL;
- }
- pb->win.bpp = bpp;
- pb->win.color_fmt = fmt;
- pb->frame_buffer_phys = (unsigned long) v.base;
- pb->win.sheight = v.height;
- pb->win.swidth = v.width;
- pb->picture.depth = pb->win.depth = v.depth;
- pb->win.bpl = pb->win.bpp * pb->win.swidth;
- pb->win.pad = v.bytesperline - pb->win.bpl;
-
- DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
- " bpl %d (+ %d)\n", v.base, v.width,v.height,
- pb->win.bpp, pb->win.bpl, pb->win.pad);
-
- pb->cmd_buff_inited = 0;
- if(pb->overlay) {
- suspend_overlay(pb);
- fill_cmd_buff(pb);
- resume_overlay(pb);
- }
- planb_unlock(pb);
- return 0;
- }
- case VIDIOCGFBUF:
- {
- struct video_buffer v;
-
- DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
-
- v.base = (void *)pb->frame_buffer_phys;
- v.height = pb->win.sheight;
- v.width = pb->win.swidth;
- v.depth = pb->win.depth;
- v.bytesperline = pb->win.bpl + pb->win.pad;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- {
- int i;
-
- if(copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
- if(i==0) {
- DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
-
- if (!(pb->overlay))
- return 0;
- planb_lock(pb);
- pb->overlay = 0;
- overlay_stop(pb);
- planb_unlock(pb);
- } else {
- DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n");
-
- if (pb->frame_buffer_phys == 0 ||
- pb->win.width == 0 ||
- pb->win.height == 0)
- return -EINVAL;
- if (pb->overlay)
- return 0;
- planb_lock(pb);
- pb->overlay = 1;
- if(!(pb->cmd_buff_inited))
- fill_cmd_buff(pb);
- overlay_start(pb);
- planb_unlock(pb);
- }
- return 0;
- }
- case VIDIOCGCHAN:
- {
- struct video_channel v;
-
- DEBUG("PlanB: IOCTL VIDIOCGCHAN\n");
-
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- v.flags = 0;
- v.tuners = 0;
- v.type = VIDEO_TYPE_CAMERA;
- v.norm = pb->win.norm;
- switch(v.channel)
- {
- case 0:
- strcpy(v.name,"Composite");
- break;
- case 1:
- strcpy(v.name,"SVHS");
- break;
- default:
- return -EINVAL;
- break;
- }
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
-
- return 0;
- }
- case VIDIOCSCHAN:
- {
- struct video_channel v;
-
- DEBUG("PlanB: IOCTL VIDIOCSCHAN\n");
-
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
-
- if (v.norm != pb->win.norm) {
- int i, maxlines;
-
- switch (v.norm)
- {
- case VIDEO_MODE_PAL:
- case VIDEO_MODE_SECAM:
- maxlines = PLANB_MAXLINES;
- break;
- case VIDEO_MODE_NTSC:
- maxlines = PLANB_NTSC_MAXLINES;
- break;
- default:
- return -EINVAL;
- break;
- }
- planb_lock(pb);
- /* empty the grabbing queue */
- while(pb->grabbing)
- interruptible_sleep_on(&pb->capq);
- pb->maxlines = maxlines;
- pb->win.norm = v.norm;
- /* Stop overlay if running */
- suspend_overlay(pb);
- for(i = 0; i < MAX_GBUFFERS; i++)
- pb->gnorm_switch[i] = 1;
- /* I know it's an overkill, but.... */
- fill_cmd_buff(pb);
- /* ok, now init it accordingly */
- saa_init_regs (pb);
- /* restart overlay if it was running */
- resume_overlay(pb);
- planb_unlock(pb);
- }
-
- switch(v.channel)
- {
- case 0: /* Composite */
- saa_set (SAA7196_IOCC,
- ((saa_regs[pb->win.norm][SAA7196_IOCC] &
- ~7) | 3), pb);
- break;
- case 1: /* SVHS */
- saa_set (SAA7196_IOCC,
- ((saa_regs[pb->win.norm][SAA7196_IOCC] &
- ~7) | 4), pb);
- break;
- default:
- return -EINVAL;
- break;
- }
-
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture vp = pb->picture;
-
- DEBUG("PlanB: IOCTL VIDIOCGPICT\n");
-
- switch(pb->win.color_fmt) {
- case PLANB_GRAY:
- vp.palette = VIDEO_PALETTE_GREY;
- case PLANB_COLOUR15:
- vp.palette = VIDEO_PALETTE_RGB555;
- break;
- case PLANB_COLOUR32:
- vp.palette = VIDEO_PALETTE_RGB32;
- break;
- default:
- vp.palette = 0;
- break;
- }
-
- if(copy_to_user(arg,&vp,sizeof(vp)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture vp;
-
- DEBUG("PlanB: IOCTL VIDIOCSPICT\n");
-
- if(copy_from_user(&vp,arg,sizeof(vp)))
- return -EFAULT;
- pb->picture = vp;
- /* Should we do sanity checks here? */
- saa_set (SAA7196_BRIG, (unsigned char)
- ((pb->picture.brightness) >> 8), pb);
- saa_set (SAA7196_HUEC, (unsigned char)
- ((pb->picture.hue) >> 8) ^ 0x80, pb);
- saa_set (SAA7196_CSAT, (unsigned char)
- ((pb->picture.colour) >> 9), pb);
- saa_set (SAA7196_CONT, (unsigned char)
- ((pb->picture.contrast) >> 9), pb);
-
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- struct video_clip clip;
- int i;
-
- DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
-
- if(copy_from_user(&vw,arg,sizeof(vw)))
- return -EFAULT;
-
- planb_lock(pb);
- /* Stop overlay if running */
- suspend_overlay(pb);
- pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0;
- if (pb->win.x != vw.x ||
- pb->win.y != vw.y ||
- pb->win.width != vw.width ||
- pb->win.height != vw.height ||
- !pb->cmd_buff_inited) {
- pb->win.x = vw.x;
- pb->win.y = vw.y;
- pb->win.width = vw.width;
- pb->win.height = vw.height;
- fill_cmd_buff(pb);
- }
- /* Reset clip mask */
- memset ((void *) pb->mask, 0xff, (pb->maxlines
- * ((PLANB_MAXPIXELS + 7) & ~7)) / 8);
- /* Add any clip rects */
- for (i = 0; i < vw.clipcount; i++) {
- if (copy_from_user(&clip, vw.clips + i,
- sizeof(struct video_clip)))
- return -EFAULT;
- add_clip(pb, &clip);
- }
- /* restart overlay if it was running */
- resume_overlay(pb);
- planb_unlock(pb);
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
-
- DEBUG("PlanB: IOCTL VIDIOCGWIN\n");
-
- vw.x=pb->win.x;
- vw.y=pb->win.y;
- vw.width=pb->win.width;
- vw.height=pb->win.height;
- vw.chromakey=0;
- vw.flags=0;
- if(pb->win.interlace)
- vw.flags|=VIDEO_WINDOW_INTERLACE;
- if(copy_to_user(arg,&vw,sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSYNC: {
- int i;
-
- IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
-
- if(copy_from_user((void *)&i,arg,sizeof(int)))
- return -EFAULT;
-
- IDEBUG("PlanB: sync to frame %d\n", i);
-
- if(i > (MAX_GBUFFERS - 1) || i < 0)
- return -EINVAL;
-chk_grab:
- switch (pb->frame_stat[i]) {
- case GBUFFER_UNUSED:
- return -EINVAL;
- case GBUFFER_GRABBING:
- IDEBUG("PlanB: waiting for grab"
- " done (%d)\n", i);
- interruptible_sleep_on(&pb->capq);
- if(signal_pending(current))
- return -EINTR;
- goto chk_grab;
- case GBUFFER_DONE:
- pb->frame_stat[i] = GBUFFER_UNUSED;
- break;
- }
- return 0;
- }
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap vm;
- volatile unsigned int status;
-
- IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
-
- if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
- return -EFAULT;
- status = pb->frame_stat[vm.frame];
- if (status != GBUFFER_UNUSED)
- return -EBUSY;
-
- return vgrab(pb, &vm);
- }
-
- case VIDIOCGMBUF:
- {
- int i;
- struct video_mbuf vm;
-
- DEBUG("PlanB: IOCTL VIDIOCGMBUF\n");
-
- memset(&vm, 0 , sizeof(vm));
- vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;
- vm.frames = MAX_GBUFFERS;
- for(i = 0; i<MAX_GBUFFERS; i++)
- vm.offsets[i] = PLANB_MAX_FBUF * i;
- if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
- return -EFAULT;
- return 0;
- }
-
- case PLANBIOCGSAAREGS:
- {
- struct planb_saa_regs preg;
-
- DEBUG("PlanB: IOCTL PLANBIOCGSAAREGS\n");
-
- if(copy_from_user(&preg, arg, sizeof(preg)))
- return -EFAULT;
- if(preg.addr >= SAA7196_NUMREGS)
- return -EINVAL;
- preg.val = saa_regs[pb->win.norm][preg.addr];
- if(copy_to_user((void *)arg, (void *)&preg,
- sizeof(preg)))
- return -EFAULT;
- return 0;
- }
-
- case PLANBIOCSSAAREGS:
- {
- struct planb_saa_regs preg;
-
- DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n");
-
- if(copy_from_user(&preg, arg, sizeof(preg)))
- return -EFAULT;
- if(preg.addr >= SAA7196_NUMREGS)
- return -EINVAL;
- saa_set (preg.addr, preg.val, pb);
- return 0;
- }
-
- case PLANBIOCGSTAT:
- {
- struct planb_stat_regs pstat;
-
- DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n");
-
- pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status);
- pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status);
- pstat.saa_stat0 = saa_status(0, pb);
- pstat.saa_stat1 = saa_status(1, pb);
-
- if(copy_to_user((void *)arg, (void *)&pstat,
- sizeof(pstat)))
- return -EFAULT;
- return 0;
- }
-
- case PLANBIOCSMODE: {
- int v;
-
- DEBUG("PlanB: IOCTL PLANBIOCSMODE\n");
-
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
-
- switch(v)
- {
- case PLANB_TV_MODE:
- saa_set (SAA7196_STDC,
- (saa_regs[pb->win.norm][SAA7196_STDC] &
- 0x7f), pb);
- break;
- case PLANB_VTR_MODE:
- saa_set (SAA7196_STDC,
- (saa_regs[pb->win.norm][SAA7196_STDC] |
- 0x80), pb);
- break;
- default:
- return -EINVAL;
- break;
- }
- pb->win.mode = v;
- return 0;
- }
- case PLANBIOCGMODE: {
- int v=pb->win.mode;
-
- DEBUG("PlanB: IOCTL PLANBIOCGMODE\n");
-
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
-#ifdef PLANB_GSCANLINE
- case PLANBG_GRAB_BPL: {
- int v=pb->gbytes_per_line;
-
- DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n");
-
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
-#endif /* PLANB_GSCANLINE */
- case PLANB_INTR_DEBUG: {
- int i;
-
- DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n");
-
- if(copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
-
- /* avoid hang ups all together */
- for (i = 0; i < MAX_GBUFFERS; i++) {
- if(pb->frame_stat[i] == GBUFFER_GRABBING) {
- pb->frame_stat[i] = GBUFFER_DONE;
- }
- }
- if(pb->grabbing)
- pb->grabbing--;
- wake_up_interruptible(&pb->capq);
- return 0;
- }
- case PLANB_INV_REGS: {
- int i;
- struct planb_any_regs any;
-
- DEBUG("PlanB: IOCTL PLANB_INV_REGS\n");
-
- if(copy_from_user(&any, arg, sizeof(any)))
- return -EFAULT;
- if(any.offset < 0 || any.offset + any.bytes > 0x400)
- return -EINVAL;
- if(any.bytes > 128)
- return -EINVAL;
- for (i = 0; i < any.bytes; i++) {
- any.data[i] =
- in_8((unsigned char *)pb->planb_base
- + any.offset + i);
- }
- if(copy_to_user(arg,&any,sizeof(any)))
- return -EFAULT;
- return 0;
- }
- default:
- {
- DEBUG("PlanB: Unimplemented IOCTL\n");
- return -ENOIOCTLCMD;
- }
- /* Some IOCTLs are currently unsupported on PlanB */
- case VIDIOCGTUNER: {
- DEBUG("PlanB: IOCTL VIDIOCGTUNER\n");
- goto unimplemented; }
- case VIDIOCSTUNER: {
- DEBUG("PlanB: IOCTL VIDIOCSTUNER\n");
- goto unimplemented; }
- case VIDIOCSFREQ: {
- DEBUG("PlanB: IOCTL VIDIOCSFREQ\n");
- goto unimplemented; }
- case VIDIOCGFREQ: {
- DEBUG("PlanB: IOCTL VIDIOCGFREQ\n");
- goto unimplemented; }
- case VIDIOCKEY: {
- DEBUG("PlanB: IOCTL VIDIOCKEY\n");
- goto unimplemented; }
- case VIDIOCSAUDIO: {
- DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n");
- goto unimplemented; }
- case VIDIOCGAUDIO: {
- DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n");
- goto unimplemented; }
-unimplemented:
- DEBUG(" Unimplemented\n");
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static int planb_mmap(struct video_device *dev, const char *adr, unsigned long size)
-{
- int i;
- struct planb *pb = (struct planb *)dev;
- unsigned long start = (unsigned long)adr;
-
- if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
- return -EINVAL;
- if (!pb->rawbuf) {
- int err;
- if((err=grabbuf_alloc(pb)))
- return err;
- }
- for (i = 0; i < pb->rawbuf_size; i++) {
- if (remap_page_range(start, virt_to_phys((void *)pb->rawbuf[i]),
- PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
- start += PAGE_SIZE;
- if (size <= PAGE_SIZE)
- break;
- size -= PAGE_SIZE;
- }
- return 0;
-}
-
-/* This gets called upon device registration */
-/* we could do some init here */
-static int planb_init_done(struct video_device *dev)
-{
- return 0;
-}
-
-static struct video_device planb_template=
-{
- PLANB_DEVICE_NAME,
- VID_TYPE_OVERLAY,
- VID_HARDWARE_PLANB,
- planb_open,
- planb_close,
- planb_read,
- planb_write,
-#if LINUX_VERSION_CODE >= 0x020100
- NULL, /* poll */
-#endif
- planb_ioctl,
- planb_mmap, /* mmap? */
- planb_init_done,
- NULL, /* pointer to private data */
- 0,
- 0
-};
-
-static int init_planb(struct planb *pb)
-{
- unsigned char saa_rev;
- int i, result;
- unsigned long flags;
-
- memset ((void *) &pb->win, 0, sizeof (struct planb_window));
- /* Simple sanity check */
- if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) {
- printk(KERN_ERR "PlanB: Option(s) invalid\n");
- return -2;
- }
- pb->win.norm = def_norm;
- pb->win.mode = PLANB_TV_MODE; /* TV mode */
- pb->win.interlace=1;
- pb->win.x=0;
- pb->win.y=0;
- pb->win.width=768; /* 640 */
- pb->win.height=576; /* 480 */
- pb->maxlines=576;
-#if 0
- btv->win.cropwidth=768; /* 640 */
- btv->win.cropheight=576; /* 480 */
- btv->win.cropx=0;
- btv->win.cropy=0;
-#endif
- pb->win.pad=0;
- pb->win.bpp=4;
- pb->win.depth=32;
- pb->win.color_fmt=PLANB_COLOUR32;
- pb->win.bpl=1024*pb->win.bpp;
- pb->win.swidth=1024;
- pb->win.sheight=768;
-#ifdef PLANB_GSCANLINE
- if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE
- || (pb->gbytes_per_line <= 0))
- return -3;
- else {
- /* page align pb->gbytes_per_line for DMA purpose */
- for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);)
- i>>=1;
- pb->gbytes_per_line = i;
- }
-#endif
- pb->tab_size = PLANB_MAXLINES + 40;
- pb->suspend = 0;
- pb->lock = 0;
- init_waitqueue_head(&pb->lockq);
- pb->ch1_cmd = 0;
- pb->ch2_cmd = 0;
- pb->mask = 0;
- pb->priv_space = 0;
- pb->offset = 0;
- pb->user = 0;
- pb->overlay = 0;
- init_waitqueue_head(&pb->suspendq);
- pb->cmd_buff_inited = 0;
- pb->frame_buffer_phys = 0;
-
- /* Reset DMA controllers */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
-
- saa_rev = (saa_status(0, pb) & 0xf0) >> 4;
- printk(KERN_INFO "PlanB: SAA7196 video processor rev. %d\n", saa_rev);
- /* Initialize the SAA registers in memory and on chip */
- saa_init_regs (pb);
-
- /* clear interrupt mask */
- pb->intr_mask = PLANB_CLR_IRQ;
-
- save_flags(flags); cli();
- result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
- if (result < 0) {
- if (result==-EINVAL)
- printk(KERN_ERR "PlanB: Bad irq number (%d) "
- "or handler\n", (int)pb->irq);
- else if (result==-EBUSY)
- printk(KERN_ERR "PlanB: I don't know why, "
- "but IRQ %d is busy\n", (int)pb->irq);
- restore_flags(flags);
- return result;
- }
- disable_irq(pb->irq);
- restore_flags(flags);
-
- /* Now add the template and register the device unit. */
- memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
-
- pb->picture.brightness=0x90<<8;
- pb->picture.contrast = 0x70 << 8;
- pb->picture.colour = 0x70<<8;
- pb->picture.hue = 0x8000;
- pb->picture.whiteness = 0;
- pb->picture.depth = pb->win.depth;
-
- pb->frame_stat=NULL;
- init_waitqueue_head(&pb->capq);
- for(i=0; i<MAX_GBUFFERS; i++) {
- pb->gbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE;
- pb->gwidth[i]=0;
- pb->gheight[i]=0;
- pb->gfmt[i]=0;
- pb->cap_cmd[i]=NULL;
-#ifndef PLANB_GSCANLINE
- pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF
- / PAGE_SIZE + 1) + MAX_LNUM * i;
- pb->lsize[i] = 0;
- pb->lnum[i] = 0;
-#endif
- }
- pb->rawbuf=NULL;
- pb->grabbing=0;
-
- /* enable interrupts */
- out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
- pb->intr_mask = PLANB_FRM_IRQ;
- enable_irq(pb->irq);
-
- if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER)<0)
- return -1;
-
- return 0;
-}
-
-/*
- * Scan for a PlanB controller, request the irq and map the io memory
- */
-
-static int find_planb(void)
-{
- struct planb *pb;
- struct device_node *planb_devices;
- unsigned char dev_fn, confreg, bus;
- unsigned int old_base, new_base;
- unsigned int irq;
- struct pci_dev *pdev;
-
- if (_machine != _MACH_Pmac)
- return 0;
-
- planb_devices = find_devices("planb");
- if (planb_devices == 0) {
- planb_num=0;
- printk(KERN_WARNING "PlanB: no device found!\n");
- return planb_num;
- }
-
- if (planb_devices->next != NULL)
- printk(KERN_ERR "Warning: only using first PlanB device!\n");
- pb = &planbs[0];
- planb_num = 1;
-
- if (planb_devices->n_addrs != 1) {
- printk (KERN_WARNING "PlanB: expecting 1 address for planb "
- "(got %d)", planb_devices->n_addrs);
- return 0;
- }
-
- if (planb_devices->n_intrs == 0) {
- printk(KERN_WARNING "PlanB: no intrs for device %s\n",
- planb_devices->full_name);
- return 0;
- } else {
- irq = planb_devices->intrs[0].line;
- }
-
- /* Initialize PlanB's PCI registers */
-
- /* There is a bug with the way OF assigns addresses
- to the devices behind the chaos bridge.
- control needs only 0x1000 of space, but decodes only
- the upper 16 bits. It therefore occupies a full 64K.
- OF assigns the planb controller memory within this space;
- so we need to change that here in order to access planb. */
-
- /* We remap to 0xf1000000 in hope that nobody uses it ! */
-
- bus = (planb_devices->addrs[0].space >> 16) & 0xff;
- dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff;
- confreg = planb_devices->addrs[0].space & 0xff;
- old_base = planb_devices->addrs[0].address;
- new_base = 0xf1000000;
-
- DEBUG("PlanB: Found on bus %d, dev %d, func %d, "
- "membase 0x%x (base reg. 0x%x)\n",
- bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
-
- pdev = pci_find_slot (bus, dev_fn);
- if (!pdev) {
- printk(KERN_ERR "cannot find slot\n");
- /* XXX handle error */
- }
-
- /* Enable response in memory space, bus mastering,
- use memory write and invalidate */
- pci_write_config_word (pdev, PCI_COMMAND,
- PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
- PCI_COMMAND_INVALIDATE);
- /* Set PCI Cache line size & latency timer */
- pci_write_config_byte (pdev, PCI_CACHE_LINE_SIZE, 0x8);
- pci_write_config_byte (pdev, PCI_LATENCY_TIMER, 0x40);
-
- /* Set the new base address */
- pci_write_config_dword (pdev, confreg, new_base);
-
- planb_regs = (volatile struct planb_registers *)
- ioremap (new_base, 0x400);
- pb->planb_base = planb_regs;
- pb->planb_base_phys = (struct planb_registers *)new_base;
- pb->irq = irq;
-
- return planb_num;
-}
-
-static void release_planb(void)
-{
- int i;
- struct planb *pb;
-
- for (i=0;i<planb_num; i++)
- {
- pb=&planbs[i];
-
- /* stop and flash DMAs unconditionally */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
-
- /* clear and free interrupts */
- pb->intr_mask = PLANB_CLR_IRQ;
- out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
- free_irq(pb->irq, pb);
-
- /* make sure all allocated memory are freed */
- planb_prepare_close(pb);
-
- printk(KERN_INFO "PlanB: unregistering with v4l\n");
- video_unregister_device(&pb->video_dev);
-
- /* note that iounmap() does nothing on the PPC right now */
- iounmap ((void *)pb->planb_base);
- }
-}
-
-#ifdef MODULE
-
-int init_module(void)
-{
-#else
-int __init init_planbs(struct video_init *unused)
-{
-#endif
- int i;
-
- if (find_planb()<=0)
- return -EIO;
-
- for (i=0; i<planb_num; i++) {
- if (init_planb(&planbs[i])<0) {
- printk(KERN_ERR "PlanB: error registering device %d"
- " with v4l\n", i);
- release_planb();
- return -EIO;
- }
- printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
- }
- return 0;
-}
-
-#ifdef MODULE
-
-void cleanup_module(void)
-{
- release_planb();
-}
-
-#endif
diff --git a/drivers/char/planb.h b/drivers/char/planb.h
deleted file mode 100644
index 98d5697c9..000000000
--- a/drivers/char/planb.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- planb - PlanB frame grabber driver
-
- PlanB is used in the 7x00/8x00 series of PowerMacintosh
- Computers as video input DMA controller.
-
- Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
- Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
-
- Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
-
-
- 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 of the License, 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.
-*/
-
-/* $Id: planb.h,v 1.13 1999/05/03 19:28:56 mlan Exp $ */
-
-#ifndef _PLANB_H_
-#define _PLANB_H_
-
-#ifdef __KERNEL__
-#include <asm/dbdma.h>
-#include "saa7196.h"
-#endif /* __KERNEL__ */
-
-#define PLANB_DEVICE_NAME "Apple PlanB Video-In"
-#define PLANB_REV "1.0"
-
-#ifdef __KERNEL__
-//#define PLANB_GSCANLINE /* use this if apps have the notion of */
- /* grab buffer scanline */
-/* This should be safe for both PAL and NTSC */
-#define PLANB_MAXPIXELS 768
-#define PLANB_MAXLINES 576
-#define PLANB_NTSC_MAXLINES 480
-
-/* Uncomment your preferred norm ;-) */
-#define PLANB_DEF_NORM VIDEO_MODE_PAL
-//#define PLANB_DEF_NORM VIDEO_MODE_NTSC
-//#define PLANB_DEF_NORM VIDEO_MODE_SECAM
-
-/* fields settings */
-#define PLANB_GRAY 0x1 /* 8-bit mono? */
-#define PLANB_COLOUR15 0x2 /* 16-bit mode */
-#define PLANB_COLOUR32 0x4 /* 32-bit mode */
-#define PLANB_CLIPMASK 0x8 /* hardware clipmasking */
-
-/* misc. flags for PlanB DMA operation */
-#define CH_SYNC 0x1 /* synchronize channels (set by ch1;
- cleared by ch2) */
-#define FIELD_SYNC 0x2 /* used for the start of each field
- (0 -> 1 -> 0 for ch1; 0 -> 1 for ch2) */
-#define EVEN_FIELD 0x0 /* even field is detected if unset */
-#define DMA_ABORT 0x2 /* error or just out of sync if set */
-#define ODD_FIELD 0x4 /* odd field is detected if set */
-
-/* for capture operations */
-#define MAX_GBUFFERS 2
-/* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */
-#ifdef PLANB_GSCANLINE
-#define PLANB_MAX_FBUF 0x240000 /* 576 * 1024 * 4 */
-#define TAB_FACTOR (1)
-#else
-#define PLANB_MAX_FBUF 0x1b0000 /* 576 * 768 * 4 */
-#define TAB_FACTOR (2)
-#endif
-#endif /* __KERNEL__ */
-
-struct planb_saa_regs {
- unsigned char addr;
- unsigned char val;
-};
-
-struct planb_stat_regs {
- unsigned int ch1_stat;
- unsigned int ch2_stat;
- unsigned char saa_stat0;
- unsigned char saa_stat1;
-};
-
-struct planb_any_regs {
- unsigned int offset;
- unsigned int bytes;
- unsigned char data[128];
-};
-
-/* planb private ioctls */
-#define PLANBIOCGSAAREGS _IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs) /* Read a saa7196 reg value */
-#define PLANBIOCSSAAREGS _IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs) /* Set a saa7196 reg value */
-#define PLANBIOCGSTAT _IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs) /* Read planb status */
-#define PLANB_TV_MODE 1
-#define PLANB_VTR_MODE 2
-#define PLANBIOCGMODE _IOR('v', BASE_VIDIOCPRIVATE + 3, int) /* Get TV/VTR mode */
-#define PLANBIOCSMODE _IOW('v', BASE_VIDIOCPRIVATE + 4, int) /* Set TV/VTR mode */
-
-#ifdef PLANB_GSCANLINE
-#define PLANBG_GRAB_BPL _IOR('v', BASE_VIDIOCPRIVATE + 5, int) /* # of bytes per scanline in grab buffer */
-#endif
-
-/* call wake_up_interruptible() with appropriate actions */
-#define PLANB_INTR_DEBUG _IOW('v', BASE_VIDIOCPRIVATE + 20, int)
-/* investigate which reg does what */
-#define PLANB_INV_REGS _IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs)
-
-#ifdef __KERNEL__
-
-/* Potentially useful macros */
-#define PLANB_SET(x) ((x) << 16 | (x))
-#define PLANB_CLR(x) ((x) << 16)
-
-/* This represents the physical register layout */
-struct planb_registers {
- volatile struct dbdma_regs ch1; /* 0x00: video in */
- volatile unsigned int even; /* 0x40: even field setting */
- volatile unsigned int odd; /* 0x44; odd field setting */
- unsigned int pad1[14]; /* empty? */
- volatile struct dbdma_regs ch2; /* 0x80: clipmask out */
- unsigned int pad2[16]; /* 0xc0: empty? */
- volatile unsigned int reg3; /* 0x100: ???? */
- volatile unsigned int intr_stat; /* 0x104: irq status */
-#define PLANB_CLR_IRQ 0x00 /* clear Plan B interrupt */
-#define PLANB_GEN_IRQ 0x01 /* assert Plan B interrupt */
-#define PLANB_FRM_IRQ 0x0100 /* end of frame */
- unsigned int pad3[1]; /* empty? */
- volatile unsigned int reg5; /* 0x10c: ??? */
- unsigned int pad4[60]; /* empty? */
- volatile unsigned char saa_addr; /* 0x200: SAA subadr */
- char pad5[3];
- volatile unsigned char saa_regval; /* SAA7196 write reg. val */
- char pad6[3];
- volatile unsigned char saa_status; /* SAA7196 status byte */
- /* There is more unused stuff here */
-};
-
-struct planb_window {
- int x, y;
- ushort width, height;
- ushort bpp, bpl, depth, pad;
- ushort swidth, sheight;
- int norm;
- int interlace;
- u32 color_fmt;
- int chromakey;
- int mode; /* used to switch between TV/VTR modes */
-};
-
-struct planb_suspend {
- int overlay;
- int frame;
- struct dbdma_cmd cmd;
-};
-
-struct planb {
- struct video_device video_dev;
- struct video_picture picture; /* Current picture params */
- struct video_audio audio_dev; /* Current audio params */
-
- volatile struct planb_registers *planb_base; /* virt base of planb */
- struct planb_registers *planb_base_phys; /* phys base of planb */
- void *priv_space; /* Org. alloc. mem for kfree */
- int user;
- unsigned int tab_size;
- int maxlines;
- int lock;
- wait_queue_head_t lockq;
- unsigned int irq; /* interrupt number */
- volatile unsigned int intr_mask;
-
- int overlay; /* overlay running? */
- struct planb_window win;
- unsigned long frame_buffer_phys; /* We need phys for DMA */
- int offset; /* offset of pixel 1 */
- volatile struct dbdma_cmd *ch1_cmd; /* Video In DMA cmd buffer */
- volatile struct dbdma_cmd *ch2_cmd; /* Clip Out DMA cmd buffer */
- volatile struct dbdma_cmd *overlay_last1;
- volatile struct dbdma_cmd *overlay_last2;
- unsigned long ch1_cmd_phys;
- volatile unsigned char *mask; /* Clipmask buffer */
- int suspend;
- wait_queue_head_t suspendq;
- struct planb_suspend suspended;
- int cmd_buff_inited; /* cmd buffer inited? */
-
- int grabbing;
- unsigned int gcount;
- wait_queue_head_t capq;
- int last_fr;
- int prev_last_fr;
- unsigned char **rawbuf;
- int rawbuf_size;
- int gbuf_idx[MAX_GBUFFERS];
- volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS];
- volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS];
- volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS];
- int need_pre_capture[MAX_GBUFFERS];
-#define PLANB_DUMMY 40 /* # of command buf's allocated for pre-capture seq. */
- int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
- unsigned int gfmt[MAX_GBUFFERS];
- int gnorm_switch[MAX_GBUFFERS];
- volatile unsigned int *frame_stat;
-#define GBUFFER_UNUSED 0x00U
-#define GBUFFER_GRABBING 0x01U
-#define GBUFFER_DONE 0x02U
-#ifdef PLANB_GSCANLINE
- int gbytes_per_line;
-#else
-#define MAX_LNUM 431 /* change this if PLANB_MAXLINES or */
- /* PLANB_MAXPIXELS changes */
- int l_fr_addr_idx[MAX_GBUFFERS];
- unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM];
- int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM];
- int l_to_next_size[MAX_GBUFFERS][MAX_LNUM];
- int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS];
-#endif
-};
-
-#endif /* __KERNEL__ */
-
-#endif /* _PLANB_H_ */
diff --git a/drivers/char/pms.c b/drivers/char/pms.c
deleted file mode 100644
index 1e50880a0..000000000
--- a/drivers/char/pms.c
+++ /dev/null
@@ -1,1074 +0,0 @@
-/*
- * Media Vision Pro Movie Studio
- * or
- * "all you need is an I2C bus some RAM and a prayer"
- *
- * This draws heavily on code
- *
- * (c) Wolfgang Koehler, wolf@first.gmd.de, Dec. 1994
- * Kiefernring 15
- * 14478 Potsdam, Germany
- *
- * Most of this code is directly derived from his userspace driver.
- * His driver works so send any reports to alan@redhat.com unless the
- * userspace driver also doesnt work for you...
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/sched.h>
-#include <linux/videodev.h>
-#include <linux/version.h>
-#include <asm/uaccess.h>
-
-
-#define MOTOROLA 1
-#define PHILIPS2 2
-#define PHILIPS1 3
-#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
-
-struct pms_device
-{
- struct video_device v;
- struct video_picture picture;
- int height;
- int width;
-};
-
-struct i2c_info
-{
- u8 slave;
- u8 sub;
- u8 data;
- u8 hits;
-};
-
-static int i2c_count = 0;
-static struct i2c_info i2cinfo[64];
-
-static int decoder = PHILIPS2;
-static int standard = 0; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
-
-/*
- * I/O ports and Shared Memory
- */
-
-static int io_port = 0x250;
-static int data_port = 0x251;
-static int mem_base = 0xC8000;
-
-
-
-extern __inline__ void mvv_write(u8 index, u8 value)
-{
- outw(index|(value<<8), io_port);
-}
-
-extern __inline__ u8 mvv_read(u8 index)
-{
- outb(index, io_port);
- return inb(data_port);
-}
-
-static int pms_i2c_stat(u8 slave)
-{
- int counter;
- int i;
-
- outb(0x28, io_port);
-
- counter=0;
- while((inb(data_port)&0x01)==0)
- if(counter++==256)
- break;
-
- while((inb(data_port)&0x01)!=0)
- if(counter++==256)
- break;
-
- outb(slave, io_port);
-
- counter=0;
- while((inb(data_port)&0x01)==0)
- if(counter++==256)
- break;
-
- while((inb(data_port)&0x01)!=0)
- if(counter++==256)
- break;
-
- for(i=0;i<12;i++)
- {
- char st=inb(data_port);
- if((st&2)!=0)
- return -1;
- if((st&1)==0)
- break;
- }
- outb(0x29, io_port);
- return inb(data_port);
-}
-
-static int pms_i2c_write(u16 slave, u16 sub, u16 data)
-{
- int skip=0;
- int count;
- int i;
-
- for(i=0;i<i2c_count;i++)
- {
- if((i2cinfo[i].slave==slave) &&
- (i2cinfo[i].sub == sub))
- {
- if(i2cinfo[i].data==data)
- skip=1;
- i2cinfo[i].data=data;
- i=i2c_count+1;
- }
- }
-
- if(i==i2c_count && i2c_count<64)
- {
- i2cinfo[i2c_count].slave=slave;
- i2cinfo[i2c_count].sub=sub;
- i2cinfo[i2c_count].data=data;
- i2c_count++;
- }
-
- if(skip)
- return 0;
-
- mvv_write(0x29, sub);
- mvv_write(0x2A, data);
- mvv_write(0x28, slave);
-
- outb(0x28, io_port);
-
- count=0;
- while((inb(data_port)&1)==0)
- if(count>255)
- break;
- while((inb(data_port)&1)!=0)
- if(count>255)
- break;
-
- count=inb(data_port);
-
- if(count&2)
- return -1;
- return count;
-}
-
-static int pms_i2c_read(int slave, int sub)
-{
- int i=0;
- for(i=0;i<i2c_count;i++)
- {
- if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub)
- return i2cinfo[i].data;
- }
- return 0;
-}
-
-
-static void pms_i2c_andor(int slave, int sub, int and, int or)
-{
- u8 tmp;
-
- tmp=pms_i2c_read(slave, sub);
- tmp = (tmp&and)|or;
- pms_i2c_write(slave, sub, tmp);
-}
-
-/*
- * Control functions
- */
-
-
-static void pms_videosource(short source)
-{
- mvv_write(0x2E, source?0x31:0x30);
-}
-
-static void pms_hue(short hue)
-{
- switch(decoder)
- {
- case MOTOROLA:
- pms_i2c_write(0x8A, 0x00, hue);
- break;
- case PHILIPS2:
- pms_i2c_write(0x8A, 0x07, hue);
- break;
- case PHILIPS1:
- pms_i2c_write(0x42, 0x07, hue);
- break;
- }
-}
-
-static void pms_colour(short colour)
-{
- switch(decoder)
- {
- case MOTOROLA:
- pms_i2c_write(0x8A, 0x00, colour);
- break;
- case PHILIPS1:
- pms_i2c_write(0x42, 0x12, colour);
- break;
- }
-}
-
-
-static void pms_contrast(short contrast)
-{
- switch(decoder)
- {
- case MOTOROLA:
- pms_i2c_write(0x8A, 0x00, contrast);
- break;
- case PHILIPS1:
- pms_i2c_write(0x42, 0x13, contrast);
- break;
- }
-}
-
-static void pms_brightness(short brightness)
-{
- switch(decoder)
- {
- case MOTOROLA:
- pms_i2c_write(0x8A, 0x00, brightness);
- pms_i2c_write(0x8A, 0x00, brightness);
- pms_i2c_write(0x8A, 0x00, brightness);
- break;
- case PHILIPS1:
- pms_i2c_write(0x42, 0x19, brightness);
- break;
- }
-}
-
-
-static void pms_format(short format)
-{
- int target;
- standard = format;
-
- if(decoder==PHILIPS1)
- target=0x42;
- else if(decoder==PHILIPS2)
- target=0x8A;
- else
- return;
-
- switch(format)
- {
- case 0: /* Auto */
- pms_i2c_andor(target, 0x0D, 0xFE,0x00);
- pms_i2c_andor(target, 0x0F, 0x3F,0x80);
- break;
- case 1: /* NTSC */
- pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
- pms_i2c_andor(target, 0x0F, 0x3F, 0x40);
- break;
- case 2: /* PAL */
- pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
- pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
- break;
- case 3: /* SECAM */
- pms_i2c_andor(target, 0x0D, 0xFE, 0x01);
- pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
- break;
- }
-}
-
-#ifdef FOR_FUTURE_EXPANSION
-
-/*
- * These features of the PMS card are not currently exposes. They
- * could become a private v4l ioctl for PMSCONFIG or somesuch if
- * people need it. We also don't yet use the PMS interrupt.
- */
-
-static void pms_hstart(short start)
-{
- switch(decoder)
- {
- case PHILIPS1:
- pms_i2c_write(0x8A, 0x05, start);
- pms_i2c_write(0x8A, 0x18, start);
- break;
- case PHILIPS2:
- pms_i2c_write(0x42, 0x05, start);
- pms_i2c_write(0x42, 0x18, start);
- break;
- }
-}
-
-/*
- * Bandpass filters
- */
-
-static void pms_bandpass(short pass)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4);
-}
-
-static void pms_antisnow(short snow)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2);
-}
-
-static void pms_sharpness(short sharp)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03);
-}
-
-static void pms_chromaagc(short agc)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5);
-}
-
-static void pms_vertnoise(short noise)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x10, 0xFC, noise&3);
-}
-
-static void pms_forcecolour(short colour)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7);
-}
-
-static void pms_antigamma(short gamma)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7);
-}
-
-static void pms_prefilter(short filter)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6);
-}
-
-static void pms_hfilter(short filter)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5);
-}
-
-static void pms_vfilter(short filter)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5);
-}
-
-static void pms_killcolour(short colour)
-{
- if(decoder==PHILIPS2)
- {
- pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3);
- pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3);
- }
- else if(decoder==PHILIPS1)
- {
- pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
- pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
- }
-}
-
-static void pms_chromagain(short chroma)
-{
- if(decoder==PHILIPS2)
- {
- pms_i2c_write(0x8A, 0x11, chroma);
- }
- else if(decoder==PHILIPS1)
- {
- pms_i2c_write(0x42, 0x11, chroma);
- }
-}
-
-
-static void pms_spacialcompl(short data)
-{
- mvv_write(0x3B, data);
-}
-
-static void pms_spacialcomph(short data)
-{
- mvv_write(0x3A, data);
-}
-
-static void pms_vstart(short start)
-{
- mvv_write(0x16, start);
- mvv_write(0x17, (start>>8)&0x01);
-}
-
-#endif
-
-static void pms_secamcross(short cross)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5);
-}
-
-
-static void pms_swsense(short sense)
-{
- if(decoder==PHILIPS2)
- {
- pms_i2c_write(0x8A, 0x0A, sense);
- pms_i2c_write(0x8A, 0x0B, sense);
- }
- else if(decoder==PHILIPS1)
- {
- pms_i2c_write(0x42, 0x0A, sense);
- pms_i2c_write(0x42, 0x0B, sense);
- }
-}
-
-
-static void pms_framerate(short frr)
-{
- int fps=(standard==1)?30:25;
- if(frr==0)
- return;
- fps=fps/frr;
- mvv_write(0x14,0x80|fps);
- mvv_write(0x15,1);
-}
-
-static void pms_vert(u8 deciden, u8 decinum)
-{
- mvv_write(0x1C, deciden); /* Denominator */
- mvv_write(0x1D, decinum); /* Numerator */
-}
-
-/*
- * Turn 16bit ratios into best small ratio the chipset can grok
- */
-
-static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
-{
- /* Knock it down by /5 once */
- if(decinum%5==0)
- {
- deciden/=5;
- decinum/=5;
- }
- /*
- * 3's
- */
- while(decinum%3==0 && deciden%3==0)
- {
- deciden/=3;
- decinum/=3;
- }
- /*
- * 2's
- */
- while(decinum%2==0 && deciden%2==0)
- {
- decinum/=2;
- deciden/=2;
- }
- /*
- * Fudgyify
- */
- while(deciden>32)
- {
- deciden/=2;
- decinum=(decinum+1)/2;
- }
- if(deciden==32)
- deciden--;
- pms_vert(deciden,decinum);
-}
-
-static void pms_horzdeci(short decinum, short deciden)
-{
- if(decinum<=512)
- {
- if(decinum%5==0)
- {
- decinum/=5;
- deciden/=5;
- }
- }
- else
- {
- decinum=512;
- deciden=640; /* 768 would be ideal */
- }
-
- while(((decinum|deciden)&1)==0)
- {
- decinum>>=1;
- deciden>>=1;
- }
- while(deciden>32)
- {
- deciden>>=1;
- decinum=(decinum+1)>>1;
- }
- if(deciden==32)
- deciden--;
-
- mvv_write(0x24, 0x80|deciden);
- mvv_write(0x25, decinum);
-}
-
-static void pms_resolution(short width, short height)
-{
- int fg_height;
-
- fg_height=height;
- if(fg_height>280)
- fg_height=280;
-
- mvv_write(0x18, fg_height);
- mvv_write(0x19, fg_height>>8);
-
- if(standard==1)
- {
- mvv_write(0x1A, 0xFC);
- mvv_write(0x1B, 0x00);
- if(height>fg_height)
- pms_vertdeci(240,240);
- else
- pms_vertdeci(fg_height,240);
- }
- else
- {
- mvv_write(0x1A, 0x1A);
- mvv_write(0x1B, 0x01);
- if(fg_height>256)
- pms_vertdeci(270,270);
- else
- pms_vertdeci(fg_height, 270);
- }
- mvv_write(0x12,0);
- mvv_write(0x13, MVVMEMORYWIDTH);
- mvv_write(0x42, 0x00);
- mvv_write(0x43, 0x00);
- mvv_write(0x44, MVVMEMORYWIDTH);
-
- mvv_write(0x22, width+8);
- mvv_write(0x23, (width+8)>> 8);
-
- if(standard==1)
- pms_horzdeci(width,640);
- else
- pms_horzdeci(width+8, 768);
-
- mvv_write(0x30, mvv_read(0x30)&0xFE);
- mvv_write(0x08, mvv_read(0x08)|0x01);
- mvv_write(0x01, mvv_read(0x01)&0xFD);
- mvv_write(0x32, 0x00);
- mvv_write(0x33, MVVMEMORYWIDTH);
-}
-
-
-/*
- * Set Input
- */
-
-static void pms_vcrinput(short input)
-{
- if(decoder==PHILIPS2)
- pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7);
- else if(decoder==PHILIPS1)
- pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7);
-}
-
-
-static int pms_capture(struct pms_device *dev, char *buf, int rgb555, int count)
-{
- int y;
- int dw = 2*dev->width;
- u32 src = mem_base;
-
- char tmp[dw+32]; /* using a temp buffer is faster than direct */
- int cnt = 0;
- int len=0;
- unsigned char r8 = 0x5; /* value for reg8 */
-
- if (rgb555)
- r8 |= 0x20; /* else use untranslated rgb = 565 */
- mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */
-
-/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
-
- for (y = 0; y < dev->height; y++ )
- {
- isa_writeb(0, src); /* synchronisiert neue Zeile */
-
- /*
- * This is in truth a fifo, be very careful as if you
- * forgot this odd things will occur 8)
- */
-
- isa_memcpy_fromio(tmp, src, dw+32); /* discard 16 word */
- cnt -= dev->height;
- while (cnt <= 0)
- {
- /*
- * Don't copy too far
- */
- int dt=dw;
- if(dt+len>count)
- dt=count-len;
- cnt += dev->height;
- copy_to_user(buf, tmp+32, dt);
- buf += dt;
- len += dt;
- }
- }
- return len;
-}
-
-
-/*
- * Video4linux interfacing
- */
-
-static int pms_open(struct video_device *dev, int flags)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void pms_close(struct video_device *dev)
-{
- MOD_DEC_USE_COUNT;
-}
-
-static int pms_init_done(struct video_device *dev)
-{
- return 0;
-}
-
-static long pms_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
-{
- return -EINVAL;
-}
-
-static int pms_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct pms_device *pd=(struct pms_device *)dev;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability b;
- strcpy(b.name, "Mediavision PMS");
- b.type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
- b.channels = 4;
- b.audios = 0;
- b.maxwidth = 640;
- b.maxheight = 480;
- b.minwidth = 16;
- b.minheight = 16;
- if(copy_to_user(arg, &b,sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGCHAN:
- {
- struct video_channel v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.channel<0 || v.channel>3)
- return -EINVAL;
- v.flags=0;
- v.tuners=1;
- /* Good question.. its composite or SVHS so.. */
- v.type = VIDEO_TYPE_CAMERA;
- switch(v.channel)
- {
- case 0:
- strcpy(v.name, "Composite");break;
- case 1:
- strcpy(v.name, "SVideo");break;
- case 2:
- strcpy(v.name, "Composite(VCR)");break;
- case 3:
- strcpy(v.name, "SVideo(VCR)");break;
- }
- if(copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSCHAN:
- {
- int v;
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- if(v<0 || v>3)
- return -EINVAL;
- pms_videosource(v&1);
- pms_vcrinput(v>>1);
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner)
- return -EINVAL;
- strcpy(v.name, "Format");
- v.rangelow=0;
- v.rangehigh=0;
- v.flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
- switch(standard)
- {
- case 0:
- v.mode = VIDEO_MODE_AUTO;
- break;
- case 1:
- v.mode = VIDEO_MODE_NTSC;
- break;
- case 2:
- v.mode = VIDEO_MODE_PAL;
- break;
- case 3:
- v.mode = VIDEO_MODE_SECAM;
- break;
- }
- if(copy_to_user(arg,&v,sizeof(v))!=0)
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner)
- return -EINVAL;
- switch(v.mode)
- {
- case VIDEO_MODE_AUTO:
- pms_framerate(25);
- pms_secamcross(0);
- pms_format(0);
- break;
- case VIDEO_MODE_NTSC:
- pms_framerate(30);
- pms_secamcross(0);
- pms_format(1);
- break;
- case VIDEO_MODE_PAL:
- pms_framerate(25);
- pms_secamcross(0);
- pms_format(2);
- break;
- case VIDEO_MODE_SECAM:
- pms_framerate(25);
- pms_secamcross(1);
- pms_format(2);
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture p=pd->picture;
- if(copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture p;
- if(copy_from_user(&p, arg, sizeof(p)))
- return -EFAULT;
- if(!((p.palette==VIDEO_PALETTE_RGB565 && p.depth==16)
- ||(p.palette==VIDEO_PALETTE_RGB555 && p.depth==15)))
- return -EINVAL;
- pd->picture=p;
-
- /*
- * Now load the card.
- */
-
- pms_brightness(p.brightness>>8);
- pms_hue(p.hue>>8);
- pms_colour(p.colour>>8);
- pms_contrast(p.contrast>>8);
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- if(copy_from_user(&vw, arg,sizeof(vw)))
- return -EFAULT;
- if(vw.flags)
- return -EINVAL;
- if(vw.clipcount)
- return -EINVAL;
- if(vw.height<16||vw.height>480)
- return -EINVAL;
- if(vw.width<16||vw.width>640)
- return -EINVAL;
- pd->width=vw.width;
- pd->height=vw.height;
- pms_resolution(pd->width, pd->height);
- /* Ok we figured out what to use from our wide choice */
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
- vw.x=0;
- vw.y=0;
- vw.width=pd->width;
- vw.height=pd->height;
- vw.chromakey=0;
- vw.flags=0;
- if(copy_to_user(arg, &vw, sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- return -EINVAL;
- case VIDIOCGFBUF:
- return -EINVAL;
- case VIDIOCSFBUF:
- return -EINVAL;
- case VIDIOCKEY:
- return 0;
- case VIDIOCGFREQ:
- return -EINVAL;
- case VIDIOCSFREQ:
- return -EINVAL;
- case VIDIOCGAUDIO:
- return -EINVAL;
- case VIDIOCSAUDIO:
- return -EINVAL;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static long pms_read(struct video_device *v, char *buf, unsigned long count, int noblock)
-{
- struct pms_device *pd=(struct pms_device *)v;
- int len;
-
- /* FIXME: semaphore this */
- len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
- return len;
-}
-
-
-struct video_device pms_template=
-{
- "Mediavision PMS",
- VID_TYPE_CAPTURE,
- VID_HARDWARE_PMS,
- pms_open,
- pms_close,
- pms_read,
- pms_write,
- NULL, /* FIXME - we can use POLL on this board with the irq */
- pms_ioctl,
- NULL,
- pms_init_done,
- NULL,
- 0,
- 0
-};
-
-struct pms_device pms_device;
-
-
-/*
- * Probe for and initialise the Mediavision PMS
- */
-
-static int init_mediavision(void)
-{
- int id;
- int idec, decst;
- int i;
-
- unsigned char i2c_defs[]={
- 0x4C,0x30,0x00,0xE8,
- 0xB6,0xE2,0x00,0x00,
- 0xFF,0xFF,0x00,0x00,
- 0x00,0x00,0x78,0x98,
- 0x00,0x00,0x00,0x00,
- 0x34,0x0A,0xF4,0xCE,
- 0xE4
- };
-
- if(check_region(0x9A01,1))
- {
- printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
- return -EBUSY;
- }
- if(check_region(io_port,3))
- {
- printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port);
- return -EBUSY;
- }
- outb(0xB8, 0x9A01); /* Unlock */
- outb(io_port>>4, 0x9A01); /* Set IO port */
-
-
- id=mvv_read(3);
- decst=pms_i2c_stat(0x43);
-
- if(decst!=-1)
- idec=2;
- else if(pms_i2c_stat(0xb9)!=-1)
- idec=3;
- else if(pms_i2c_stat(0x8b)!=-1)
- idec=1;
- else
- idec=0;
-
- printk(KERN_INFO "PMS type is %d\n", idec);
- if(idec==0)
- return -ENODEV;
-
- /*
- * Ok we have a PMS of some sort
- */
-
- request_region(io_port,3, "Mediavision PMS");
- request_region(0x9A01, 1, "Mediavision PMS config");
-
- mvv_write(0x04, mem_base>>12); /* Set the memory area */
-
- /* Ok now load the defaults */
-
- for(i=0;i<0x19;i++)
- {
- if(i2c_defs[i]==0xFF)
- pms_i2c_andor(0x8A, i, 0x07,0x00);
- else
- pms_i2c_write(0x8A, i, i2c_defs[i]);
- }
-
- pms_i2c_write(0xB8,0x00,0x12);
- pms_i2c_write(0xB8,0x04,0x00);
- pms_i2c_write(0xB8,0x07,0x00);
- pms_i2c_write(0xB8,0x08,0x00);
- pms_i2c_write(0xB8,0x09,0xFF);
- pms_i2c_write(0xB8,0x0A,0x00);
- pms_i2c_write(0xB8,0x0B,0x10);
- pms_i2c_write(0xB8,0x10,0x03);
-
- mvv_write(0x01, 0x00);
- mvv_write(0x05, 0xA0);
- mvv_write(0x08, 0x25);
- mvv_write(0x09, 0x00);
- mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
-
- mvv_write(0x10, 0x02);
- mvv_write(0x1E, 0x0C);
- mvv_write(0x1F, 0x03);
- mvv_write(0x26, 0x06);
-
- mvv_write(0x2B, 0x00);
- mvv_write(0x2C, 0x20);
- mvv_write(0x2D, 0x00);
- mvv_write(0x2F, 0x70);
- mvv_write(0x32, 0x00);
- mvv_write(0x33, MVVMEMORYWIDTH);
- mvv_write(0x34, 0x00);
- mvv_write(0x35, 0x00);
- mvv_write(0x3A, 0x80);
- mvv_write(0x3B, 0x10);
- mvv_write(0x20, 0x00);
- mvv_write(0x21, 0x00);
- mvv_write(0x30, 0x22);
- return 0;
-}
-
-/*
- * Initialization and module stuff
- */
-
-static int __init init_pms_cards(void)
-{
- printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
-
- data_port = io_port +1;
-
- if(init_mediavision())
- {
- printk(KERN_INFO "Board not found.\n");
- return -ENODEV;
- }
- memcpy(&pms_device, &pms_template, sizeof(pms_template));
- pms_device.height=240;
- pms_device.width=320;
- pms_swsense(75);
- pms_resolution(320,240);
- return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER);
-}
-
-MODULE_PARM(io_port,"i");
-MODULE_PARM(mem_base,"i");
-
-static void __exit shutdown_mediavision(void)
-{
- release_region(io_port,3);
- release_region(0x9A01, 1);
-}
-
-static void __exit cleanup_pms_module(void)
-{
- shutdown_mediavision();
- video_unregister_device((struct video_device *)&pms_device);
-}
-
-module_init(init_pms_cards);
-module_exit(cleanup_pms_module);
-
diff --git a/drivers/char/radio-aimslab.c b/drivers/char/radio-aimslab.c
deleted file mode 100644
index d716c54bd..000000000
--- a/drivers/char/radio-aimslab.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/* radiotrack (radioreveal) driver for Linux radio support
- * (c) 1997 M. Kirkwood
- * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
- * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
- *
- * History:
- * 1999-02-24 Russell Kroll <rkroll@exploits.org>
- * Fine tuning/VIDEO_TUNER_LOW
- * Frequency range expanded to start at 87 MHz
- *
- * TODO: Allow for more than one of these foolish entities :-)
- *
- * Notes on the hardware (reverse engineered from other peoples'
- * reverse engineering of AIMS' code :-)
- *
- * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
- *
- * The signal strength query is unsurprisingly inaccurate. And it seems
- * to indicate that (on my card, at least) the frequency setting isn't
- * too great. (I have to tune up .025MHz from what the freq should be
- * to get a report that the thing is tuned.)
- *
- * Volume control is (ugh) analogue:
- * out(port, start_increasing_volume);
- * wait(a_wee_while);
- * out(port, stop_changing_the_volume);
- *
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */
-#include <asm/semaphore.h> /* Lock for the I/O */
-
-#ifndef CONFIG_RADIO_RTRACK_PORT
-#define CONFIG_RADIO_RTRACK_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_RTRACK_PORT;
-static int users = 0;
-static struct semaphore lock;
-
-struct rt_device
-{
- int port;
- int curvol;
- unsigned long curfreq;
- int muted;
-};
-
-
-/* local things */
-
-static void sleep_delay(long n)
-{
- /* Sleep nicely for 'n' uS */
- int d=n/(1000000/HZ);
- if(!d)
- udelay(n);
- else
- {
- /* Yield CPU time */
- unsigned long x=jiffies;
- while((jiffies-x)<=d)
- schedule();
- }
-}
-
-static void rt_decvol(void)
-{
- outb(0x58, io); /* volume down + sigstr + on */
- sleep_delay(100000);
- outb(0xd8, io); /* volume steady + sigstr + on */
-}
-
-static void rt_incvol(void)
-{
- outb(0x98, io); /* volume up + sigstr + on */
- sleep_delay(100000);
- outb(0xd8, io); /* volume steady + sigstr + on */
-}
-
-static void rt_mute(struct rt_device *dev)
-{
- dev->muted = 1;
- down(&lock);
- outb(0xd0, io); /* volume steady, off */
- up(&lock);
-}
-
-static int rt_setvol(struct rt_device *dev, int vol)
-{
- int i;
-
- down(&lock);
-
- if(vol == dev->curvol) { /* requested volume = current */
- if (dev->muted) { /* user is unmuting the card */
- dev->muted = 0;
- outb (0xd8, io); /* enable card */
- }
- up(&lock);
- return 0;
- }
-
- if(vol == 0) { /* volume = 0 means mute the card */
- outb(0x48, io); /* volume down but still "on" */
- sleep_delay(2000000); /* make sure it's totally down */
- outb(0xd0, io); /* volume steady, off */
- dev->curvol = 0; /* track the volume state! */
- up(&lock);
- return 0;
- }
-
- dev->muted = 0;
- if(vol > dev->curvol)
- for(i = dev->curvol; i < vol; i++)
- rt_incvol();
- else
- for(i = dev->curvol; i > vol; i--)
- rt_decvol();
-
- dev->curvol = vol;
- up(&lock);
- return 0;
-}
-
-/* the 128+64 on these outb's is to keep the volume stable while tuning
- * without them, the volume _will_ creep up with each frequency change
- * and bit 4 (+16) is to keep the signal strength meter enabled
- */
-
-void send_0_byte(int port, struct rt_device *dev)
-{
- if ((dev->curvol == 0) || (dev->muted)) {
- outb_p(128+64+16+ 1, port); /* wr-enable + data low */
- outb_p(128+64+16+2+1, port); /* clock */
- }
- else {
- outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */
- outb_p(128+64+16+8+2+1, port); /* clock */
- }
- sleep_delay(1000);
-}
-
-void send_1_byte(int port, struct rt_device *dev)
-{
- if ((dev->curvol == 0) || (dev->muted)) {
- outb_p(128+64+16+4 +1, port); /* wr-enable+data high */
- outb_p(128+64+16+4+2+1, port); /* clock */
- }
- else {
- outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */
- outb_p(128+64+16+8+4+2+1, port); /* clock */
- }
-
- sleep_delay(1000);
-}
-
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
-{
- int i;
-
- /* adapted from radio-aztech.c */
-
- /* now uses VIDEO_TUNER_LOW for fine tuning */
-
- freq += 171200; /* Add 10.7 MHz IF */
- freq /= 800; /* Convert to 50 kHz units */
-
- down(&lock); /* Stop other ops interfering */
-
- send_0_byte (io, dev); /* 0: LSB of frequency */
-
- for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
- if (freq & (1 << i))
- send_1_byte (io, dev);
- else
- send_0_byte (io, dev);
-
- send_0_byte (io, dev); /* 14: test bit - always 0 */
- send_0_byte (io, dev); /* 15: test bit - always 0 */
-
- send_0_byte (io, dev); /* 16: band data 0 - always 0 */
- send_0_byte (io, dev); /* 17: band data 1 - always 0 */
- send_0_byte (io, dev); /* 18: band data 2 - always 0 */
- send_0_byte (io, dev); /* 19: time base - always 0 */
-
- send_0_byte (io, dev); /* 20: spacing (0 = 25 kHz) */
- send_1_byte (io, dev); /* 21: spacing (1 = 25 kHz) */
- send_0_byte (io, dev); /* 22: spacing (0 = 25 kHz) */
- send_1_byte (io, dev); /* 23: AM/FM (FM = 1, always) */
-
- if ((dev->curvol == 0) || (dev->muted))
- outb (0xd0, io); /* volume steady + sigstr */
- else
- outb (0xd8, io); /* volume steady + sigstr + on */
-
- up(&lock);
-
- return 0;
-}
-
-static int rt_getsigstr(struct rt_device *dev)
-{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
-
-static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct rt_device *rt=dev->priv;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type=VID_TYPE_TUNER;
- v.channels=1;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- strcpy(v.name, "RadioTrack");
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow=(87*16000);
- v.rangehigh=(108*16000);
- v.flags=VIDEO_TUNER_LOW;
- v.mode=VIDEO_MODE_AUTO;
- strcpy(v.name, "FM");
- v.signal=0xFFFF*rt_getsigstr(rt);
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&rt->curfreq, arg,sizeof(rt->curfreq)))
- return -EFAULT;
- rt_setfreq(rt, rt->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- v.volume=rt->curvol * 6554;
- v.step=6554;
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
-
- if(v.flags&VIDEO_AUDIO_MUTE)
- rt_mute(rt);
- else
- rt_setvol(rt,v.volume/6554);
-
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int rt_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void rt_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct rt_device rtrack_unit;
-
-static struct video_device rtrack_radio=
-{
- "RadioTrack radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_RTRACK,
- rt_open,
- rt_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* No poll */
- rt_ioctl,
- NULL,
- NULL
-};
-
-static int __init rtrack_init(void)
-{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
- return -EINVAL;
- }
-
- if (check_region(io, 2))
- {
- printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
- return -EBUSY;
- }
-
- rtrack_radio.priv=&rtrack_unit;
-
- if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- request_region(io, 2, "rtrack");
- printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n");
-
- /* Set up the I/O locking */
-
- init_MUTEX(&lock);
-
- /* mute card - prevents noisy bootups */
-
- /* this ensures that the volume is all the way down */
- outb(0x48, io); /* volume down but still "on" */
- sleep_delay(2000000); /* make sure it's totally down */
- outb(0xc0, io); /* steady volume, mute card */
- rtrack_unit.curvol = 0;
-
- return 0;
-}
-
-MODULE_AUTHOR("M.Kirkwood");
-MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit cleanup_rtrack_module(void)
-{
- video_unregister_device(&rtrack_radio);
- release_region(io,2);
-}
-
-module_init(rtrack_init);
-module_exit(cleanup_rtrack_module);
-
diff --git a/drivers/char/radio-aztech.c b/drivers/char/radio-aztech.c
deleted file mode 100644
index 2fb8714ad..000000000
--- a/drivers/char/radio-aztech.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* radio-aztech.c - Aztech radio card driver for Linux 2.2
- *
- * Adapted to support the Video for Linux API by
- * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
- *
- * Quay Ly
- * Donald Song
- * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
- * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
- * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
- *
- * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
- * along with more information on the card itself.
- *
- * History:
- * 1999-02-24 Russell Kroll <rkroll@exploits.org>
- * Fine tuning/VIDEO_TUNER_LOW
- * Range expanded to 87-108 MHz (from 87.9-107.8)
- *
- * Notable changes from the original source:
- * - includes stripped down to the essentials
- * - for loops used as delays replaced with udelay()
- * - #defines removed, changed to static values
- * - tuning structure changed - no more character arrays, other changes
-*/
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */
-
-/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
-
-#ifndef CONFIG_RADIO_AZTECH_PORT
-#define CONFIG_RADIO_AZTECH_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_AZTECH_PORT;
-static int radio_wait_time = 1000;
-static int users = 0;
-static struct semaphore lock;
-
-struct az_device
-{
- int curvol;
- unsigned long curfreq;
- int stereo;
-};
-
-static int volconvert(int level)
-{
- level>>=14; /* Map 16bits down to 2 bit */
- level&=3;
-
- /* convert to card-friendly values */
- switch (level)
- {
- case 0:
- return 0;
- case 1:
- return 1;
- case 2:
- return 4;
- case 3:
- return 5;
- }
- return 0; /* Quieten gcc */
-}
-
-static void send_0_byte (struct az_device *dev)
-{
- udelay(radio_wait_time);
- outb_p(2+volconvert(dev->curvol), io);
- outb_p(64+2+volconvert(dev->curvol), io);
-}
-
-static void send_1_byte (struct az_device *dev)
-{
- udelay (radio_wait_time);
- outb_p(128+2+volconvert(dev->curvol), io);
- outb_p(128+64+2+volconvert(dev->curvol), io);
-}
-
-static int az_setvol(struct az_device *dev, int vol)
-{
- down(&lock);
- outb (volconvert(vol), io);
- up(&lock);
- return 0;
-}
-
-/* thanks to Michael Dwyer for giving me a dose of clues in
- * the signal strength department..
- *
- * This card has a stereo bit - bit 0 set = mono, not set = stereo
- * It also has a "signal" bit - bit 1 set = bad signal, not set = good
- *
- */
-
-static int az_getsigstr(struct az_device *dev)
-{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
-
-static int az_getstereo(struct az_device *dev)
-{
- if (inb(io) & 1) /* bit set = mono */
- return 0;
- return 1; /* stereo */
-}
-
-static int az_setfreq(struct az_device *dev, unsigned long frequency)
-{
- int i;
-
- frequency += 171200; /* Add 10.7 MHz IF */
- frequency /= 800; /* Convert to 50 kHz units */
-
- down(&lock);
-
- send_0_byte (dev); /* 0: LSB of frequency */
-
- for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
- if (frequency & (1 << i))
- send_1_byte (dev);
- else
- send_0_byte (dev);
-
- send_0_byte (dev); /* 14: test bit - always 0 */
- send_0_byte (dev); /* 15: test bit - always 0 */
- send_0_byte (dev); /* 16: band data 0 - always 0 */
- if (dev->stereo) /* 17: stereo (1 to enable) */
- send_1_byte (dev);
- else
- send_0_byte (dev);
-
- send_1_byte (dev); /* 18: band data 1 - unknown */
- send_0_byte (dev); /* 19: time base - always 0 */
- send_0_byte (dev); /* 20: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 21: spacing (1 = 25 kHz) */
- send_0_byte (dev); /* 22: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 23: AM/FM (FM = 1, always) */
-
- /* latch frequency */
-
- udelay (radio_wait_time);
- outb_p(128+64+volconvert(dev->curvol), io);
-
- up(&lock);
-
- return 0;
-}
-
-static int az_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct az_device *az=dev->priv;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type=VID_TYPE_TUNER;
- v.channels=1;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- strcpy(v.name, "Aztech Radio");
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow=(87*16000);
- v.rangehigh=(108*16000);
- v.flags=VIDEO_TUNER_LOW;
- v.mode=VIDEO_MODE_AUTO;
- v.signal=0xFFFF*az_getsigstr(az);
- if(az_getstereo(az))
- v.flags|=VIDEO_TUNER_STEREO_ON;
- strcpy(v.name, "FM");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &az->curfreq, sizeof(az->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&az->curfreq, arg,sizeof(az->curfreq)))
- return -EFAULT;
- az_setfreq(az, az->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- if(az->stereo)
- v.mode=VIDEO_SOUND_STEREO;
- else
- v.mode=VIDEO_SOUND_MONO;
- v.volume=az->curvol;
- v.step=16384;
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
- az->curvol=v.volume;
-
- az->stereo=(v.mode&VIDEO_SOUND_STEREO)?1:0;
- if(v.flags&VIDEO_AUDIO_MUTE)
- az_setvol(az,0);
- else
- az_setvol(az,az->curvol);
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int az_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void az_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct az_device aztech_unit;
-
-static struct video_device aztech_radio=
-{
- "Aztech radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_AZTECH,
- az_open,
- az_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* No poll */
- az_ioctl,
- NULL,
- NULL
-};
-
-static int __init aztech_init(void)
-{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
- return -EINVAL;
- }
-
- if (check_region(io, 2))
- {
- printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
- return -EBUSY;
- }
-
- init_MUTEX(&lock);
- aztech_radio.priv=&aztech_unit;
-
- if(video_register_device(&aztech_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- request_region(io, 2, "aztech");
- printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
- /* mute card - prevents noisy bootups */
- outb (0, io);
- return 0;
-}
-
-MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Aztech radio card.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit aztech_cleanup(void)
-{
- video_unregister_device(&aztech_radio);
- release_region(io,2);
-}
-
-module_init(aztech_init);
-module_exit(aztech_cleanup);
diff --git a/drivers/char/radio-cadet.c b/drivers/char/radio-cadet.c
deleted file mode 100644
index ed2056dea..000000000
--- a/drivers/char/radio-cadet.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/* radio-cadet.c - A video4linux driver for the ADS Cadet AM/FM Radio Card
- *
- * by Fred Gleason <fredg@wava.com>
- * Version 0.3.3
- *
- * (Loosely) based on code for the Aztech radio card by
- *
- * Russell Kroll (rkroll@exploits.org)
- * Quay Ly
- * Donald Song
- * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
- * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
- * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
- *
-*/
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_CADET_PORT */
-#include <linux/param.h>
-
-#ifndef CONFIG_RADIO_CADET_PORT
-#define CONFIG_RADIO_CADET_PORT 0x330
-#endif
-#define RDS_BUFFER 256
-
-static int io=CONFIG_RADIO_CADET_PORT;
-static int users=0;
-static int curtuner=0;
-static int tunestat=0;
-static int sigstrength=0;
-static wait_queue_head_t tunerq,rdsq,readq;
-struct timer_list tunertimer,rdstimer,readtimer;
-static __u8 rdsin=0,rdsout=0,rdsstat=0;
-static unsigned char rdsbuf[RDS_BUFFER];
-static int cadet_lock=0;
-
-/*
- * Signal Strength Threshold Values
- * The V4L API spec does not define any particular unit for the signal
- * strength value. These values are in microvolts of RF at the tuner's input.
- */
-static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
-
-
-
-void cadet_wake(unsigned long qnum)
-{
- switch(qnum) {
- case 0: /* cadet_setfreq */
- wake_up(&tunerq);
- break;
- case 1: /* cadet_getrds */
- wake_up(&rdsq);
- break;
- }
-}
-
-
-
-static int cadet_getrds(void)
-{
- int rdsstat=0;
-
- cadet_lock++;
- outb(3,io); /* Select Decoder Control/Status */
- outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */
- cadet_lock--;
- init_timer(&rdstimer);
- rdstimer.function=cadet_wake;
- rdstimer.data=(unsigned long)1;
- rdstimer.expires=jiffies+(HZ/10);
- init_waitqueue_head(&rdsq);
- add_timer(&rdstimer);
- sleep_on(&rdsq);
-
- cadet_lock++;
- outb(3,io); /* Select Decoder Control/Status */
- if((inb(io+1)&0x80)!=0) {
- rdsstat|=VIDEO_TUNER_RDS_ON;
- }
- if((inb(io+1)&0x10)!=0) {
- rdsstat|=VIDEO_TUNER_MBS_ON;
- }
- cadet_lock--;
- return rdsstat;
-}
-
-
-
-
-static int cadet_getstereo(void)
-{
- if(curtuner!=0) { /* Only FM has stereo capability! */
- return 0;
- }
- cadet_lock++;
- outb(7,io); /* Select tuner control */
- if((inb(io+1)&0x40)==0) {
- cadet_lock--;
- return 1; /* Stereo pilot detected */
- }
- else {
- cadet_lock--;
- return 0; /* Mono */
- }
-}
-
-
-
-static unsigned cadet_gettune(void)
-{
- int curvol,i;
- unsigned fifo=0;
-
- /*
- * Prepare for read
- */
- cadet_lock++;
- outb(7,io); /* Select tuner control */
- curvol=inb(io+1); /* Save current volume/mute setting */
- outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */
- tunestat=0xffff;
-
- /*
- * Read the shift register
- */
- for(i=0;i<25;i++) {
- fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
- if(i<24) {
- outb(0x01,io+1);
- tunestat&=inb(io+1);
- outb(0x00,io+1);
- }
- }
-
- /*
- * Restore volume/mute setting
- */
- outb(curvol,io+1);
- cadet_lock--;
-
- return fifo;
-}
-
-
-
-static unsigned cadet_getfreq(void)
-{
- int i;
- unsigned freq=0,test,fifo=0;
-
- /*
- * Read current tuning
- */
- fifo=cadet_gettune();
-
- /*
- * Convert to actual frequency
- */
- if(curtuner==0) { /* FM */
- test=12500;
- for(i=0;i<14;i++) {
- if((fifo&0x01)!=0) {
- freq+=test;
- }
- test=test<<1;
- fifo=fifo>>1;
- }
- freq-=10700000; /* IF frequency is 10.7 MHz */
- freq=(freq*16)/1000000; /* Make it 1/16 MHz */
- }
- if(curtuner==1) { /* AM */
- freq=((fifo&0x7fff)-2010)*16;
- }
-
- return freq;
-}
-
-
-
-static void cadet_settune(unsigned fifo)
-{
- int i;
- unsigned test;
-
- cadet_lock++;
- outb(7,io); /* Select tuner control */
- /*
- * Write the shift register
- */
- test=0;
- test=(fifo>>23)&0x02; /* Align data for SDO */
- test|=0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */
- outb(7,io); /* Select tuner control */
- outb(test,io+1); /* Initialize for write */
- for(i=0;i<25;i++) {
- test|=0x01; /* Toggle SCK High */
- outb(test,io+1);
- test&=0xfe; /* Toggle SCK Low */
- outb(test,io+1);
- fifo=fifo<<1; /* Prepare the next bit */
- test=0x1c|((fifo>>23)&0x02);
- outb(test,io+1);
- }
- cadet_lock--;
-}
-
-
-
-static void cadet_setfreq(unsigned freq)
-{
- unsigned fifo;
- int i,j,test;
- int curvol;
-
- /*
- * Formulate a fifo command
- */
- fifo=0;
- if(curtuner==0) { /* FM */
- test=102400;
- freq=(freq*1000)/16; /* Make it kHz */
- freq+=10700; /* IF is 10700 kHz */
- for(i=0;i<14;i++) {
- fifo=fifo<<1;
- if(freq>=test) {
- fifo|=0x01;
- freq-=test;
- }
- test=test>>1;
- }
- }
- if(curtuner==1) { /* AM */
- fifo=(freq/16)+2010; /* Make it kHz */
- fifo|=0x100000; /* Select AM Band */
- }
-
- /*
- * Save current volume/mute setting
- */
- cadet_lock++;
- outb(7,io); /* Select tuner control */
- curvol=inb(io+1);
-
- /*
- * Tune the card
- */
- for(j=3;j>-1;j--) {
- cadet_settune(fifo|(j<<16));
- outb(7,io); /* Select tuner control */
- outb(curvol,io+1);
- cadet_lock--;
- init_timer(&tunertimer);
- tunertimer.function=cadet_wake;
- tunertimer.data=(unsigned long)0;
- tunertimer.expires=jiffies+(HZ/10);
- init_waitqueue_head(&tunerq);
- add_timer(&tunertimer);
- sleep_on(&tunerq);
- cadet_gettune();
- if((tunestat&0x40)==0) { /* Tuned */
- sigstrength=sigtable[curtuner][j];
- return;
- }
- cadet_lock++;
- }
- cadet_lock--;
- sigstrength=0;
-}
-
-
-static int cadet_getvol(void)
-{
- cadet_lock++;
- outb(7,io); /* Select tuner control */
- if((inb(io+1)&0x20)!=0) {
- cadet_lock--;
- return 0xffff;
- }
- else {
- cadet_lock--;
- return 0;
- }
-}
-
-
-static void cadet_setvol(int vol)
-{
- cadet_lock++;
- outb(7,io); /* Select tuner control */
- if(vol>0) {
- outb(0x20,io+1);
- }
- else {
- outb(0x00,io+1);
- }
- cadet_lock--;
-}
-
-
-
-void cadet_handler(unsigned long data)
-{
- /*
- * Service the RDS fifo
- */
- if(cadet_lock==0) {
- outb(0x3,io); /* Select RDS Decoder Control */
- if((inb(io+1)&0x20)!=0) {
- printk(KERN_CRIT "cadet: RDS fifo overflow\n");
- }
- outb(0x80,io); /* Select RDS fifo */
- while((inb(io)&0x80)!=0) {
- rdsbuf[rdsin++]=inb(io+1);
- if(rdsin==rdsout) {
- printk(KERN_CRIT "cadet: RDS buffer overflow\n");
- }
- }
- }
-
- /*
- * Service pending read
- */
- if( rdsin!=rdsout) {
- wake_up_interruptible(&readq);
- }
-
- /*
- * Clean up and exit
- */
- init_timer(&readtimer);
- readtimer.function=cadet_handler;
- readtimer.data=(unsigned long)0;
- readtimer.expires=jiffies+(HZ/20);
- add_timer(&readtimer);
-}
-
-
-
-static long cadet_read(struct video_device *v,char *buf,unsigned long count,
- int nonblock)
-{
- int i=0;
- unsigned char readbuf[RDS_BUFFER];
-
- if(rdsstat==0) {
- cadet_lock++;
- rdsstat=1;
- outb(0x80,io); /* Select RDS fifo */
- cadet_lock--;
- init_timer(&readtimer);
- readtimer.function=cadet_handler;
- readtimer.data=(unsigned long)0;
- readtimer.expires=jiffies+(HZ/20);
- add_timer(&readtimer);
- }
- if(rdsin==rdsout) {
- if(nonblock) {
- return -EWOULDBLOCK;
- }
- interruptible_sleep_on(&readq);
- }
- while((i<count)&&(rdsin!=rdsout)) {
- readbuf[i++]=rdsbuf[rdsout++];
- }
- if(copy_to_user(buf,readbuf,i)) {
- return -EFAULT;
- }
- return i;
-}
-
-
-
-static int cadet_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- unsigned freq;
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type=VID_TYPE_TUNER;
- v.channels=2;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- strcpy(v.name, "ADS Cadet");
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg,sizeof(v))!=0) {
- return -EFAULT;
- }
- if((v.tuner<0)||(v.tuner>1)) {
- return -EINVAL;
- }
- switch(v.tuner) {
- case 0:
- strcpy(v.name,"FM");
- v.rangelow=1400; /* 87.5 MHz */
- v.rangehigh=1728; /* 108.0 MHz */
- v.flags=0;
- v.mode=0;
- v.mode|=VIDEO_MODE_AUTO;
- v.signal=sigstrength;
- if(cadet_getstereo()==1) {
- v.flags|=VIDEO_TUNER_STEREO_ON;
- }
- v.flags|=cadet_getrds();
- if(copy_to_user(arg,&v, sizeof(v))) {
- return -EFAULT;
- }
- break;
- case 1:
- strcpy(v.name,"AM");
- v.rangelow=8320; /* 520 kHz */
- v.rangehigh=26400; /* 1650 kHz */
- v.flags=0;
- v.flags|=VIDEO_TUNER_LOW;
- v.mode=0;
- v.mode|=VIDEO_MODE_AUTO;
- v.signal=sigstrength;
- if(copy_to_user(arg,&v, sizeof(v))) {
- return -EFAULT;
- }
- break;
- }
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v))) {
- return -EFAULT;
- }
- if((v.tuner<0)||(v.tuner>1)) {
- return -EINVAL;
- }
- curtuner=v.tuner;
- return 0;
- }
- case VIDIOCGFREQ:
- freq=cadet_getfreq();
- if(copy_to_user(arg, &freq, sizeof(freq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&freq, arg,sizeof(freq)))
- return -EFAULT;
- if((curtuner==0)&&((freq<1400)||(freq>1728))) {
- return -EINVAL;
- }
- if((curtuner==1)&&((freq<8320)||(freq>26400))) {
- return -EINVAL;
- }
- cadet_setfreq(freq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- if(cadet_getstereo()==0) {
- v.mode=VIDEO_SOUND_MONO;
- }
- else {
- v.mode=VIDEO_SOUND_STEREO;
- }
- v.volume=cadet_getvol();
- v.step=0xffff;
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
- cadet_setvol(v.volume);
- if(v.flags&VIDEO_AUDIO_MUTE)
- cadet_setvol(0);
- else
- cadet_setvol(0xffff);
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-
-static int cadet_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- init_waitqueue_head(&readq);
- return 0;
-}
-
-static void cadet_close(struct video_device *dev)
-{
- if(rdsstat==1) {
- del_timer(&readtimer);
- rdsstat=0;
- }
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-
-static struct video_device cadet_radio=
-{
- "Cadet radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_CADET,
- cadet_open,
- cadet_close,
- cadet_read,
- NULL, /* Can't write */
- NULL, /* No poll */
- cadet_ioctl,
- NULL,
- NULL
-};
-
-#ifndef MODULE
-static int cadet_probe(void)
-{
- static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
- int i;
-
- for(i=0;i<8;i++) {
- io=iovals[i];
- if(check_region(io,2)>=0) {
- cadet_setfreq(1410);
- if(cadet_getfreq()==1410) {
- return io;
- }
- }
- }
- return -1;
-}
-#endif
-
-static int __init cadet_init(void)
-{
-#ifndef MODULE
- io = cadet_probe ();
-#endif
-
- if(io < 0) {
-#ifdef MODULE
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
-#endif
- return -EINVAL;
- }
- if (!request_region(io,2,"cadet"))
- return -EBUSY;
- if(video_register_device(&cadet_radio,VFL_TYPE_RADIO)==-1) {
- release_region(io,2);
- return -EINVAL;
- }
- printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
- return 0;
-}
-
-
-
-MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit cadet_cleanup_module(void)
-{
- video_unregister_device(&cadet_radio);
- release_region(io,2);
-}
-
-module_init(cadet_init);
-module_exit(cadet_cleanup_module);
-
diff --git a/drivers/char/radio-gemtek.c b/drivers/char/radio-gemtek.c
deleted file mode 100644
index 8b53dbd0d..000000000
--- a/drivers/char/radio-gemtek.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* GemTek radio card driver for Linux (C) 1998 Jonas Munsin <jmunsin@iki.fi>
- *
- * GemTek hasn't released any specs on the card, so the protocol had to
- * be reverse engineered with dosemu.
- *
- * Besides the protocol changes, this is mostly a copy of:
- *
- * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
- *
- * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
- * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
- *
- * TODO: Allow for more than one of these foolish entities :-)
- *
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */
-#include <linux/spinlock.h>
-
-#ifndef CONFIG_RADIO_GEMTEK_PORT
-#define CONFIG_RADIO_GEMTEK_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_GEMTEK_PORT;
-static int users = 0;
-static spinlock_t lock;
-
-struct gemtek_device
-{
- int port;
- unsigned long curfreq;
- int muted;
-};
-
-
-/* local things */
-
-/* the correct way to mute the gemtek may be to write the last written
- * frequency || 0x10, but just writing 0x10 once seems to do it as well
- */
-static void gemtek_mute(struct gemtek_device *dev)
-{
- if(dev->muted)
- return;
- spin_lock(&lock);
- outb(0x10, io);
- spin_unlock(&lock);
- dev->muted = 1;
-}
-
-static void gemtek_unmute(struct gemtek_device *dev)
-{
- if(dev->muted == 0)
- return;
- spin_lock(&lock);
- outb(0x20, io);
- spin_unlock(&lock);
- dev->muted = 0;
-}
-
-static void zero(void)
-{
- outb_p(0x04, io);
- udelay(5);
- outb_p(0x05, io);
- udelay(5);
-}
-
-static void one(void)
-{
- outb_p(0x06, io);
- udelay(5);
- outb_p(0x07, io);
- udelay(5);
-}
-
-static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
-{
- int i;
-
-/* freq = 78.25*((float)freq/16000.0 + 10.52); */
-
- freq /= 16;
- freq += 10520;
- freq *= 7825;
- freq /= 100000;
-
- spin_lock(&lock);
-
- /* 2 start bits */
- outb_p(0x03, io);
- udelay(5);
- outb_p(0x07, io);
- udelay(5);
-
- /* 28 frequency bits (lsb first) */
- for (i = 0; i < 14; i++)
- if (freq & (1 << i))
- one();
- else
- zero();
- /* 36 unknown bits */
- for (i = 0; i < 11; i++)
- zero();
- one();
- for (i = 0; i < 4; i++)
- zero();
- one();
- zero();
-
- /* 2 end bits */
- outb_p(0x03, io);
- udelay(5);
- outb_p(0x07, io);
- udelay(5);
-
- spin_unlock(&lock);
-
- return 0;
-}
-
-int gemtek_getsigstr(struct gemtek_device *dev)
-{
- spin_lock(&lock);
- inb(io);
- udelay(5);
- spin_unlock(&lock);
- if (inb(io) & 8) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
-
-static int gemtek_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct gemtek_device *rt=dev->priv;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type=VID_TYPE_TUNER;
- v.channels=1;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- strcpy(v.name, "GemTek");
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow=87*16000;
- v.rangehigh=108*16000;
- v.flags=VIDEO_TUNER_LOW;
- v.mode=VIDEO_MODE_AUTO;
- v.signal=0xFFFF*gemtek_getsigstr(rt);
- strcpy(v.name, "FM");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&rt->curfreq, arg,sizeof(rt->curfreq)))
- return -EFAULT;
- /* needs to be called twice in order for getsigstr to work */
- gemtek_setfreq(rt, rt->curfreq);
- gemtek_setfreq(rt, rt->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags|=VIDEO_AUDIO_MUTABLE;
- v.volume=1;
- v.step=65535;
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
-
- if(v.flags&VIDEO_AUDIO_MUTE)
- gemtek_mute(rt);
- else
- gemtek_unmute(rt);
-
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int gemtek_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void gemtek_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct gemtek_device gemtek_unit;
-
-static struct video_device gemtek_radio=
-{
- "GemTek radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_GEMTEK,
- gemtek_open,
- gemtek_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* Can't poll */
- gemtek_ioctl,
- NULL,
- NULL
-};
-
-static int __init gemtek_init(void)
-{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c (io=0x020c or io=0x248 for the combined sound/radiocard)\n");
- return -EINVAL;
- }
-
- if (check_region(io, 4))
- {
- printk(KERN_ERR "gemtek: port 0x%x already in use\n", io);
- return -EBUSY;
- }
-
- gemtek_radio.priv=&gemtek_unit;
-
- if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- request_region(io, 4, "gemtek");
- printk(KERN_INFO "GemTek Radio Card driver.\n");
-
- spin_lock_init(&lock);
- /* mute card - prevents noisy bootups */
- outb(0x10, io);
- udelay(5);
- gemtek_unit.muted = 1;
-
- /* this is _maybe_ unnecessary */
- outb(0x01, io);
-
- return 0;
-}
-
-MODULE_AUTHOR("Jonas Munsin");
-MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (0x20c or 0x248 have been reported to work for the combined sound/radiocard)).");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit gemtek_cleanup(void)
-{
- video_unregister_device(&gemtek_radio);
- release_region(io,4);
-}
-
-module_init(gemtek_init);
-module_exit(gemtek_cleanup);
-
-/*
- Local variables:
- compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c"
- End:
-*/
diff --git a/drivers/char/radio-miropcm20.c b/drivers/char/radio-miropcm20.c
deleted file mode 100644
index 15985380b..000000000
--- a/drivers/char/radio-miropcm20.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* Miro PCM20 radio driver for Linux radio support
- * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
- * Thanks to Norberto Pellici for the ACI device interface specification
- * The API part is based on the radiotrack driver by M. Kirkwood
- * This driver relies on the aci mixer (drivers/sound/lowlevel/aci.c)
- * Look there for further info...
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include "../sound/miroaci.h" /* ACI Control by acimixer */
-
-static int users = 0;
-
-struct pcm20_device
-{
- int port;
- int curvol;
- unsigned long curfreq;
- int muted;
-};
-
-
-/* local things */
-
-
-static void pcm20_mute(struct pcm20_device *dev)
-{
-
- dev->muted = 1;
- aci_write_cmd(0xa3,0x01);
-
-}
-
-static int pcm20_setvol(struct pcm20_device *dev, int vol)
-{
-
- if(vol == dev->curvol) { /* requested volume = current */
- if (dev->muted) { /* user is unmuting the card */
- dev->muted = 0;
- aci_write_cmd(0xa3,0x00); /* enable card */
- }
-
- return 0;
- }
-
- if(vol == 0) { /* volume = 0 means mute the card */
- aci_write_cmd(0x3d, 0x20);
- aci_write_cmd(0x35, 0x20);
- return 0;
- }
-
- dev->muted = 0;
- aci_write_cmd(0x3d, 32-vol); /* Right Channel */
- aci_write_cmd(0x35, 32-vol); /* Left Channel */
- dev->curvol = vol;
-
- return 0;
-}
-
-static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
-{
- unsigned char freql;
- unsigned char freqh;
-
- freq = (freq * 10) / 16;
- freql = freq & 0xff;
- freqh = freq >> 8;
-
-
- aci_write_cmd_d(0xa7, freql, freqh); /* Tune to frequency */
-
- return 0;
-}
-
-int pcm20_getsigstr(struct pcm20_device *dev)
-{
- unsigned char buf;
- aci_indexed_cmd(0xf0, 0x32, &buf);
- if ((buf & 0x80) == 0x80)
- return 0;
- return 1; /* signal present */
-}
-
-static int pcm20_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct pcm20_device *pcm20=dev->priv;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type=VID_TYPE_TUNER;
- strcpy(v.name, "Miro PCM20");
- v.channels=1;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow=(int)(87.5*16);
- v.rangehigh=(int)(108.0*16);
- v.flags=0;
- v.mode=VIDEO_MODE_AUTO;
- v.signal=0xFFFF*pcm20_getsigstr(pcm20);
- strcpy(v.name, "FM");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &pcm20->curfreq, sizeof(pcm20->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&pcm20->curfreq, arg,sizeof(pcm20->curfreq)))
- return -EFAULT;
- pcm20_setfreq(pcm20, pcm20->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- v.volume=pcm20->curvol * 2048;
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
-
- if(v.flags&VIDEO_AUDIO_MUTE)
- pcm20_mute(pcm20);
- else
- pcm20_setvol(pcm20,v.volume/2048);
-
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int pcm20_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void pcm20_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct pcm20_device pcm20_unit;
-
-static struct video_device pcm20_radio=
-{
- "Miro PCM 20 radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_RTRACK,
- pcm20_open,
- pcm20_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* Can't poll */
- pcm20_ioctl,
- NULL,
- NULL
-};
-
-static int __init pcm20_init(void)
-{
-
- pcm20_radio.priv=&pcm20_unit;
-
- if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- printk(KERN_INFO "Miro PCM20 radio card driver.\n");
-
- /* mute card - prevents noisy bootups */
-
- /* this ensures that the volume is all the way down */
-
- pcm20_unit.curvol = 0;
-
- return 0;
-}
-
-MODULE_AUTHOR("Ruurd Reitsma");
-MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit pcm20_cleanup(void)
-{
- video_unregister_device(&pcm20_radio);
-}
-
-module_init(pcm20_init);
-module_exit(pcm20_cleanup);
-
diff --git a/drivers/char/radio-rtrack2.c b/drivers/char/radio-rtrack2.c
deleted file mode 100644
index c060ded4a..000000000
--- a/drivers/char/radio-rtrack2.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
- *
- * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
- * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
- *
- * TODO: Allow for more than one of these foolish entities :-)
- *
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */
-#include <linux/spinlock.h>
-
-#ifndef CONFIG_RADIO_RTRACK2_PORT
-#define CONFIG_RADIO_RTRACK2_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_RTRACK2_PORT;
-static int users = 0;
-static spinlock_t lock;
-
-struct rt_device
-{
- int port;
- unsigned long curfreq;
- int muted;
-};
-
-
-/* local things */
-
-static void rt_mute(struct rt_device *dev)
-{
- if(dev->muted)
- return;
- spin_lock(&lock);
- outb(1, io);
- spin_unlock(&lock);
- dev->muted = 1;
-}
-
-static void rt_unmute(struct rt_device *dev)
-{
- if(dev->muted == 0)
- return;
- spin_lock(&lock);
- outb(0, io);
- spin_unlock(&lock);
- dev->muted = 0;
-}
-
-static void zero(void)
-{
- outb_p(1, io);
- outb_p(3, io);
- outb_p(1, io);
-}
-
-static void one(void)
-{
- outb_p(5, io);
- outb_p(7, io);
- outb_p(5, io);
-}
-
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
-{
- int i;
-
- freq = freq / 200 + 856;
-
- spin_lock(&lock);
-
- outb_p(0xc8, io);
- outb_p(0xc9, io);
- outb_p(0xc9, io);
-
- for (i = 0; i < 10; i++)
- zero ();
-
- for (i = 14; i >= 0; i--)
- if (freq & (1 << i))
- one ();
- else
- zero ();
-
- outb_p(0xc8, io);
- if (!dev->muted)
- outb_p(0, io);
-
- spin_unlock(&lock);
- return 0;
-}
-
-static int rt_getsigstr(struct rt_device *dev)
-{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
-
-static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct rt_device *rt=dev->priv;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type=VID_TYPE_TUNER;
- v.channels=1;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- strcpy(v.name, "RadioTrack II");
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow=88*16000;
- v.rangehigh=108*16000;
- v.flags=VIDEO_TUNER_LOW;
- v.mode=VIDEO_MODE_AUTO;
- v.signal=0xFFFF*rt_getsigstr(rt);
- strcpy(v.name, "FM");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&rt->curfreq, arg,sizeof(rt->curfreq)))
- return -EFAULT;
- rt_setfreq(rt, rt->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags|=VIDEO_AUDIO_MUTABLE;
- v.volume=1;
- v.step=65535;
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
-
- if(v.flags&VIDEO_AUDIO_MUTE)
- rt_mute(rt);
- else
- rt_unmute(rt);
-
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int rt_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void rt_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct rt_device rtrack2_unit;
-
-static struct video_device rtrack2_radio=
-{
- "RadioTrack II radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_RTRACK2,
- rt_open,
- rt_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* Can't poll */
- rt_ioctl,
- NULL,
- NULL
-};
-
-static int __init rtrack2_init(void)
-{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
- return -EINVAL;
- }
- if (check_region(io, 4))
- {
- printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
- return -EBUSY;
- }
-
- rtrack2_radio.priv=&rtrack2_unit;
-
- spin_lock_init(&lock);
- if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- request_region(io, 4, "rtrack2");
- printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
-
- /* mute card - prevents noisy bootups */
- outb(1, io);
- rtrack2_unit.muted = 1;
-
- return 0;
-}
-
-MODULE_AUTHOR("Ben Pfaff");
-MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit rtrack2_cleanup_module(void)
-{
- video_unregister_device(&rtrack2_radio);
- release_region(io,4);
-}
-
-module_init(rtrack2_init);
-module_exit(rtrack2_cleanup_module);
-
-/*
- Local variables:
- compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c"
- End:
-*/
diff --git a/drivers/char/radio-sf16fmi.c b/drivers/char/radio-sf16fmi.c
deleted file mode 100644
index 55328a96f..000000000
--- a/drivers/char/radio-sf16fmi.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* SF16FMI radio driver for Linux radio support
- * heavily based on rtrack driver...
- * (c) 1997 M. Kirkwood
- * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
- *
- * Fitted to new interface by Alan Cox <alan.cox@linux.org>
- * Made working and cleaned up functions <mikael.hedin@irf.se>
- *
- * Notes on the hardware
- *
- * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
- * No volume control - only mute/unmute - you have to use line volume
- * control on SB-part of SF16FMI
- *
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_SF16MI_PORT */
-#include <asm/semaphore.h>
-
-struct fmi_device
-{
- int port;
- int curvol; /* 1 or 0 */
- unsigned long curfreq; /* freq in kHz */
- __u32 flags;
-};
-
-#ifndef CONFIG_RADIO_SF16FMI_PORT
-#define CONFIG_RADIO_SF16FMI_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_SF16FMI_PORT;
-static int users = 0;
-static struct semaphore lock;
-
-/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
-/* It is only usefull to give freq in intervall of 800 (=0.05Mhz),
- * other bits will be truncated, e.g 92.7400016 -> 92.7, but
- * 92.7400017 -> 92.75
- */
-#define RSF16_ENCODE(x) ((x)/800+214)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
-
-static void outbits(int bits, unsigned int data, int port)
-{
- while(bits--) {
- if(data & 1) {
- outb(5, port);
- udelay(6);
- outb(7, port);
- udelay(6);
- } else {
- outb(1, port);
- udelay(6);
- outb(3, port);
- udelay(6);
- }
- data>>=1;
- }
-}
-
-static inline void fmi_mute(int port)
-{
- down(&lock);
- outb(0x00, port);
- up(&lock);
-}
-
-static inline void fmi_unmute(int port)
-{
- down(&lock);
- outb(0x08, port);
- up(&lock);
-}
-
-static inline int fmi_setfreq(struct fmi_device *dev)
-{
- int myport = dev->port;
- unsigned long freq = dev->curfreq;
- int i;
-
- down(&lock);
-
- outbits(16, RSF16_ENCODE(freq), myport);
- outbits(8, 0xC0, myport);
- for(i=0; i< 100; i++)
- {
- udelay(1400);
- if(current->need_resched)
- schedule();
- }
-/* If this becomes allowed use it ...
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ/7);
-*/
-
- up(&lock);
- if (dev->curvol) fmi_unmute(myport);
- return 0;
-}
-
-static inline int fmi_getsigstr(struct fmi_device *dev)
-{
- int val;
- int res;
- int myport = dev->port;
- int i;
-
- down(&lock);
- val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */
- outb(val, myport);
- outb(val | 0x10, myport);
- for(i=0; i< 100; i++)
- {
- udelay(1400);
- if(current->need_resched)
- schedule();
- }
-/* If this becomes allowed use it ...
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ/7);
-*/
- res = (int)inb(myport+1);
- outb(val, myport);
-
- up(&lock);
- return (res & 2) ? 0 : 0xFFFF;
-}
-
-static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct fmi_device *fmi=dev->priv;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- strcpy(v.name, "SF16-FMx radio");
- v.type=VID_TYPE_TUNER;
- v.channels=1;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- int mult;
-
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
- strcpy(v.name, "FM");
- mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000;
- v.rangelow = RSF16_MINFREQ/mult;
- v.rangehigh = RSF16_MAXFREQ/mult;
- v.flags=fmi->flags;
- v.mode=VIDEO_MODE_AUTO;
- v.signal = fmi_getsigstr(fmi);
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- fmi->flags = v.flags & VIDEO_TUNER_LOW;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- {
- unsigned long tmp = fmi->curfreq;
- if (!(fmi->flags & VIDEO_TUNER_LOW))
- tmp /= 1000;
- if(copy_to_user(arg, &tmp, sizeof(tmp)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long tmp;
- if(copy_from_user(&tmp, arg, sizeof(tmp)))
- return -EFAULT;
- if (!(fmi->flags & VIDEO_TUNER_LOW))
- tmp *= 1000;
- if ( tmp<RSF16_MINFREQ || tmp>RSF16_MAXFREQ )
- return -EINVAL;
- /*rounding in steps of 800 to match th freq
- that will be used */
- fmi->curfreq = (tmp/800)*800;
- fmi_setfreq(fmi);
- return 0;
- }
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- v.audio=0;
- v.volume=0;
- v.bass=0;
- v.treble=0;
- v.flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
- strcpy(v.name, "Radio");
- v.mode=VIDEO_SOUND_STEREO;
- v.balance=0;
- v.step=0; /* No volume, just (un)mute */
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
- fmi->curvol= v.flags&VIDEO_AUDIO_MUTE ? 0 : 1;
- fmi->curvol ?
- fmi_unmute(fmi->port) : fmi_mute(fmi->port);
- return 0;
- }
- case VIDIOCGUNIT:
- {
- struct video_unit v;
- v.video=VIDEO_NO_UNIT;
- v.vbi=VIDEO_NO_UNIT;
- v.radio=dev->minor;
- v.audio=0; /* How do we find out this??? */
- v.teletext=VIDEO_NO_UNIT;
- if(copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int fmi_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void fmi_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct fmi_device fmi_unit;
-
-static struct video_device fmi_radio=
-{
- "SF16FMx radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_SF16MI,
- fmi_open,
- fmi_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* Can't poll */
- fmi_ioctl,
- NULL,
- NULL
-};
-
-static int __init fmi_init(void)
-{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
- return -EINVAL;
- }
- if (check_region(io, 2))
- {
- printk(KERN_ERR "fmi: port 0x%x already in use\n", io);
- return -EBUSY;
- }
-
- fmi_unit.port = io;
- fmi_unit.curvol = 0;
- fmi_unit.curfreq = 0;
- fmi_unit.flags = VIDEO_TUNER_LOW;
- fmi_radio.priv = &fmi_unit;
-
- init_MUTEX(&lock);
-
- if(video_register_device(&fmi_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- request_region(io, 2, "fmi");
- printk(KERN_INFO "SF16FMx radio card driver at 0x%x.\n", io);
- printk(KERN_INFO "(c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz.\n");
- /* mute card - prevents noisy bootups */
- fmi_mute(io);
- return 0;
-}
-
-MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
-MODULE_DESCRIPTION("A driver for the SF16MI radio.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit fmi_cleanup_module(void)
-{
- video_unregister_device(&fmi_radio);
- release_region(io,2);
-}
-
-module_init(fmi_init);
-module_exit(fmi_cleanup_module);
-
diff --git a/drivers/char/radio-terratec.c b/drivers/char/radio-terratec.c
deleted file mode 100644
index 1dda1618e..000000000
--- a/drivers/char/radio-terratec.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/* Terratec ActiveRadio ISA Standalone card driver for Linux radio support
- * (c) 1999 R. Offermanns (rolf@offermanns.de)
- * based on the aimslab radio driver from M. Kirkwood
- * many thanks to Michael Becker and Friedhelm Birth (from TerraTec)
- *
- *
- * History:
- * 1999-05-21 First preview release
- *
- * Notes on the hardware:
- * There are two "main" chips on the card:
- * - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf)
- * - Philips SAA6588 (http://www-us.semiconductors.philips.com/acrobat/datasheets/SAA6588_1.pdf)
- * (you can get the datasheet at the above links)
- *
- * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
- * Volume Control is done digitally
- *
- * there is a I2C controlled RDS decoder (SAA6588) onboard, which i would like to support someday
- * (as soon i have understand how to get started :)
- * If you can help me out with that, please contact me!!
- *
- *
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */
-#include <linux/spinlock.h>
-
-#ifndef CONFIG_RADIO_TERRATEC_PORT
-#define CONFIG_RADIO_TERRATEC_PORT 0x590
-#endif
-
-/**************** this ones are for the terratec *******************/
-#define BASEPORT 0x590
-#define VOLPORT 0x591
-#define WRT_DIS 0x00
-#define CLK_OFF 0x00
-#define IIC_DATA 0x01
-#define IIC_CLK 0x02
-#define DATA 0x04
-#define CLK_ON 0x08
-#define WRT_EN 0x10
-/*******************************************************************/
-
-static int io = CONFIG_RADIO_TERRATEC_PORT;
-static int users = 0;
-static spinlock_t lock;
-
-struct tt_device
-{
- int port;
- int curvol;
- unsigned long curfreq;
- int muted;
-};
-
-
-/* local things */
-
-static void cardWriteVol(int volume)
-{
- int i;
- volume = volume+(volume * 32); // change both channels
- spin_lock(&lock);
- for (i=0;i<8;i++)
- {
- if (volume & (0x80>>i))
- outb(0x80, VOLPORT);
- else outb(0x00, VOLPORT);
- }
- spin_unlock(&lock);
-}
-
-
-
-static void tt_mute(struct tt_device *dev)
-{
- dev->muted = 1;
- cardWriteVol(0);
-}
-
-static int tt_setvol(struct tt_device *dev, int vol)
-{
-
-// printk(KERN_ERR "setvol called, vol = %d\n", vol);
-
- if(vol == dev->curvol) { /* requested volume = current */
- if (dev->muted) { /* user is unmuting the card */
- dev->muted = 0;
- cardWriteVol(vol); /* enable card */
- }
-
- return 0;
- }
-
- if(vol == 0) { /* volume = 0 means mute the card */
- cardWriteVol(0); /* "turn off card" by setting vol to 0 */
- dev->curvol = vol; /* track the volume state! */
- return 0;
- }
-
- dev->muted = 0;
-
- cardWriteVol(vol);
-
- dev->curvol = vol;
-
- return 0;
-
-}
-
-
-/* this is the worst part in this driver */
-/* many more or less strange things are going on here, but hey, it works :) */
-
-static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
-{
- int freq;
- int i;
- int p;
- int temp;
- long rest;
-
- unsigned char buffer[25]; /* we have to bit shift 25 registers */
- freq = freq1/160; /* convert the freq. to a nice to handel value */
- for(i=24;i>-1;i--)
- buffer[i]=0;
-
- rest = freq*10+10700; /* i once had understood what is going on here */
- /* maybe some wise guy (friedhelm?) can comment this stuff */
- i=13;
- p=10;
- temp=102400;
- while (rest!=0)
- {
- if (rest%temp == rest)
- buffer[i] = 0;
- else
- {
- buffer[i] = 1;
- rest = rest-temp;
- }
- i--;
- p--;
- temp = temp/2;
- }
-
- spin_lock(&lock);
-
- for (i=24;i>-1;i--) /* bit shift the values to the radiocard */
- {
- if (buffer[i]==1)
- {
- outb(WRT_EN|DATA, BASEPORT);
- outb(WRT_EN|DATA|CLK_ON , BASEPORT);
- outb(WRT_EN|DATA, BASEPORT);
- }
- else
- {
- outb(WRT_EN|0x00, BASEPORT);
- outb(WRT_EN|0x00|CLK_ON , BASEPORT);
- }
- }
- outb(0x00, BASEPORT);
-
- spin_unlock(&lock);
-
- return 0;
-}
-
-int tt_getsigstr(struct tt_device *dev) /* TODO */
-{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
-
-
-/* implement the video4linux api */
-
-static int tt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct tt_device *tt=dev->priv;
-
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type=VID_TYPE_TUNER;
- v.channels=1;
- v.audios=1;
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
- strcpy(v.name, "ActiveRadio");
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow=(87*16000);
- v.rangehigh=(108*16000);
- v.flags=VIDEO_TUNER_LOW;
- v.mode=VIDEO_MODE_AUTO;
- strcpy(v.name, "FM");
- v.signal=0xFFFF*tt_getsigstr(tt);
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &tt->curfreq, sizeof(tt->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&tt->curfreq, arg,sizeof(tt->curfreq)))
- return -EFAULT;
- tt_setfreq(tt, tt->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
- v.volume=tt->curvol * 6554;
- v.step=6554;
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
-
- if(v.flags&VIDEO_AUDIO_MUTE)
- tt_mute(tt);
- else
- tt_setvol(tt,v.volume/6554);
-
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int tt_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void tt_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct tt_device terratec_unit;
-
-static struct video_device terratec_radio=
-{
- "TerraTec ActiveRadio",
- VID_TYPE_TUNER,
- VID_HARDWARE_TERRATEC,
- tt_open,
- tt_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* No poll */
- tt_ioctl,
- NULL,
- NULL
-};
-
-static int __init terratec_init(void)
-{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
- return -EINVAL;
- }
- if (check_region(io, 2))
- {
- printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
- return -EBUSY;
- }
-
- terratec_radio.priv=&terratec_unit;
-
- spin_lock_init(&lock);
-
- if(video_register_device(&terratec_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- request_region(io, 2, "terratec");
- printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
-
- /* mute card - prevents noisy bootups */
-
- /* this ensures that the volume is all the way down */
- cardWriteVol(0);
- terratec_unit.curvol = 0;
-
- return 0;
-}
-
-MODULE_AUTHOR("R.OFFERMANNS & others");
-MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit terratec_cleanup_module(void)
-{
- video_unregister_device(&terratec_radio);
- release_region(io,2);
- printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n");
-}
-
-module_init(terratec_init);
-module_exit(terratec_cleanup_module);
-
diff --git a/drivers/char/radio-trust.c b/drivers/char/radio-trust.c
deleted file mode 100644
index 4e86bda90..000000000
--- a/drivers/char/radio-trust.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/* radio-trust.c - Trust FM Radio card driver for Linux 2.2
- * by Eric Lammerts <eric@scintilla.utwente.nl>
- *
- * Based on radio-aztech.c. Original notes:
- *
- * Adapted to support the Video for Linux API by
- * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
- *
- * Quay Ly
- * Donald Song
- * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
- * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
- * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
- *
- * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
- */
-
-#include <stdarg.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/videodev.h>
-#include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */
-
-/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
-
-#ifndef CONFIG_RADIO_TRUST_PORT
-#define CONFIG_RADIO_TRUST_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_TRUST_PORT;
-static int ioval = 0xf;
-static int users = 0;
-static __u16 curvol;
-static __u16 curbass;
-static __u16 curtreble;
-static unsigned long curfreq;
-static int curstereo;
-static int curmute;
-
-/* i2c addresses */
-#define TDA7318_ADDR 0x88
-#define TSA6060T_ADDR 0xc4
-
-#define TR_DELAY do { inb(io); inb(io); inb(io); } while(0)
-#define TR_SET_SCL outb(ioval |= 2, io)
-#define TR_CLR_SCL outb(ioval &= 0xfd, io)
-#define TR_SET_SDA outb(ioval |= 1, io)
-#define TR_CLR_SDA outb(ioval &= 0xfe, io)
-
-static void write_i2c(int n, ...)
-{
- unsigned char val, mask;
- va_list args;
-
- va_start(args, n);
-
- /* start condition */
- TR_SET_SDA;
- TR_SET_SCL;
- TR_DELAY;
- TR_CLR_SDA;
- TR_CLR_SCL;
- TR_DELAY;
-
- for(; n; n--) {
- val = va_arg(args, unsigned);
- for(mask = 0x80; mask; mask >>= 1) {
- if(val & mask)
- TR_SET_SDA;
- else
- TR_CLR_SDA;
- TR_SET_SCL;
- TR_DELAY;
- TR_CLR_SCL;
- TR_DELAY;
- }
- /* acknowledge bit */
- TR_SET_SDA;
- TR_SET_SCL;
- TR_DELAY;
- TR_CLR_SCL;
- TR_DELAY;
- }
-
- /* stop condition */
- TR_CLR_SDA;
- TR_DELAY;
- TR_SET_SCL;
- TR_DELAY;
- TR_SET_SDA;
- TR_DELAY;
-
- va_end(args);
-}
-
-static void tr_setvol(__u16 vol)
-{
- curvol = vol / 2048;
- write_i2c(2, TDA7318_ADDR, curvol ^ 0x1f);
-}
-
-static int basstreble2chip[15] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
-};
-
-static void tr_setbass(__u16 bass)
-{
- curbass = bass / 4370;
- write_i2c(2, TDA7318_ADDR, 0x60 | basstreble2chip[curbass]);
-}
-
-static void tr_settreble(__u16 treble)
-{
- curtreble = treble / 4370;
- write_i2c(2, TDA7318_ADDR, 0x70 | basstreble2chip[curtreble]);
-}
-
-static void tr_setstereo(int stereo)
-{
- curstereo = !!stereo;
- ioval = (ioval & 0xfb) | (!curstereo << 2);
- outb(ioval, io);
-}
-
-static void tr_setmute(int mute)
-{
- curmute = !!mute;
- ioval = (ioval & 0xf7) | (curmute << 3);
- outb(ioval, io);
-}
-
-static int tr_getsigstr(void)
-{
- int i, v;
-
- for(i = 0, v = 0; i < 100; i++) v |= inb(io);
- return (v & 1)? 0 : 0xffff;
-}
-
-static int tr_getstereo(void)
-{
- /* don't know how to determine it, just return the setting */
- return curstereo;
-}
-
-static void tr_setfreq(unsigned long f)
-{
- f /= 160; /* Convert to 10 kHz units */
- f += 1070; /* Add 10.7 MHz IF */
-
- write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
-}
-
-static int tr_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
-
- v.type=VID_TYPE_TUNER;
- v.channels=1;
- v.audios=1;
-
- /* No we don't do pictures */
- v.maxwidth=0;
- v.maxheight=0;
- v.minwidth=0;
- v.minheight=0;
-
- strcpy(v.name, "Trust FM Radio");
-
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
-
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
-
- if(copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
-
- if(v.tuner) /* Only 1 tuner */
- return -EINVAL;
-
- v.rangelow = 87500 * 16;
- v.rangehigh = 108000 * 16;
- v.flags = VIDEO_TUNER_LOW;
- v.mode = VIDEO_MODE_AUTO;
-
- v.signal = tr_getsigstr();
- if(tr_getstereo())
- v.flags |= VIDEO_TUNER_STEREO_ON;
-
- strcpy(v.name, "FM");
-
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
-
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
-
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner != 0)
- return -EINVAL;
-
- return 0;
- }
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &curfreq, sizeof(curfreq)))
- return -EFAULT;
- return 0;
-
- case VIDIOCSFREQ:
- {
- unsigned long f;
-
- if(copy_from_user(&f, arg, sizeof(curfreq)))
- return -EFAULT;
- tr_setfreq(f);
- return 0;
- }
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
-
- memset(&v,0, sizeof(v));
- v.flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
- v.mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- v.volume = curvol * 2048;
- v.step = 2048;
- v.bass = curbass * 4370;
- v.treble = curtreble * 4370;
-
- strcpy(v.name, "Trust FM Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
-
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
-
- tr_setvol(v.volume);
- tr_setbass(v.bass);
- tr_settreble(v.treble);
- tr_setstereo(v.mode & VIDEO_SOUND_STEREO);
- tr_setmute(v.flags & VIDEO_AUDIO_MUTE);
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int tr_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void tr_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct video_device trust_radio=
-{
- "Trust FM Radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_TRUST,
- tr_open,
- tr_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* No poll */
- tr_ioctl,
- NULL,
- NULL
-};
-
-static int __init trust_init(void)
-{
- if(io == -1) {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
- return -EINVAL;
- }
- if(check_region(io, 2)) {
- printk(KERN_ERR "trust: port 0x%x already in use\n", io);
- return -EBUSY;
- }
- if(video_register_device(&trust_radio, VFL_TYPE_RADIO)==-1)
- return -EINVAL;
-
- request_region(io, 2, "Trust FM Radio");
-
- printk(KERN_INFO "Trust FM Radio card driver v1.0.\n");
-
- write_i2c(2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
-
- tr_setvol(0x8000);
- tr_setbass(0x8000);
- tr_settreble(0x8000);
- tr_setstereo(1);
-
- /* mute card - prevents noisy bootups */
- tr_setmute(1);
-
- return 0;
-}
-
-MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit cleanup_trust_module(void)
-{
- video_unregister_device(&trust_radio);
- release_region(io, 2);
-}
-
-module_init(trust_init);
-module_exit(cleanup_trust_module);
diff --git a/drivers/char/radio-typhoon.c b/drivers/char/radio-typhoon.c
deleted file mode 100644
index a0bbf343f..000000000
--- a/drivers/char/radio-typhoon.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* Typhoon Radio Card driver for radio support
- * (c) 1999 Dr. Henrik Seidel <Henrik.Seidel@gmx.de>
- *
- * Card manufacturer:
- * http://194.18.155.92/idc/prod2.idc?nr=50753&lang=e
- *
- * Notes on the hardware
- *
- * This card has two output sockets, one for speakers and one for line.
- * The speaker output has volume control, but only in four discrete
- * steps. The line output has neither volume control nor mute.
- *
- * The card has auto-stereo according to its manual, although it all
- * sounds mono to me (even with the Win/DOS drivers). Maybe it's my
- * antenna - I really don't know for sure.
- *
- * Frequency control is done digitally.
- *
- * Volume control is done digitally, but there are only four different
- * possible values. So you should better always turn the volume up and
- * use line control. I got the best results by connecting line output
- * to the sound card microphone input. For such a configuration the
- * volume control has no effect, since volume control only influences
- * the speaker output.
- *
- * There is no explicit mute/unmute. So I set the radio frequency to a
- * value where I do expect just noise and turn the speaker volume down.
- * The frequency change is necessary since the card never seems to be
- * completely silent.
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/proc_fs.h> /* radio card status report */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */
-
-#define BANNER "Typhoon Radio Card driver v0.1\n"
-
-#ifndef CONFIG_RADIO_TYPHOON_PORT
-#define CONFIG_RADIO_TYPHOON_PORT -1
-#endif
-
-#ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ
-#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0
-#endif
-
-#ifndef CONFIG_PROC_FS
-#undef CONFIG_RADIO_TYPHOON_PROC_FS
-#endif
-
-struct typhoon_device {
- int users;
- int iobase;
- int curvol;
- int muted;
- unsigned long curfreq;
- unsigned long mutefreq;
-};
-
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol);
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
- unsigned long frequency);
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
-static void typhoon_mute(struct typhoon_device *dev);
-static void typhoon_unmute(struct typhoon_device *dev);
-static int typhoon_setvol(struct typhoon_device *dev, int vol);
-static int typhoon_ioctl(struct video_device *dev, unsigned int cmd, void *arg);
-static int typhoon_open(struct video_device *dev, int flags);
-static void typhoon_close(struct video_device *dev);
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
-static int typhoon_get_info(char *buf, char **start, off_t offset, int len);
-#endif
-
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol)
-{
- vol >>= 14; /* Map 16 bit to 2 bit */
- vol &= 3;
- outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */
- outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */
-}
-
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
- unsigned long frequency)
-{
- unsigned long outval;
- unsigned long x;
-
- /*
- * The frequency transfer curve is not linear. The best fit I could
- * get is
- *
- * outval = -155 + exp((f + 15.55) * 0.057))
- *
- * where frequency f is in MHz. Since we don't have exp in the kernel,
- * I approximate this function by a third order polynomial.
- *
- */
-
- x = frequency / 160;
- outval = (x * x + 2500) / 5000;
- outval = (outval * x + 5000) / 10000;
- outval -= (10 * x * x + 10433) / 20866;
- outval += 4 * x - 11505;
-
- outb_p((outval >> 8) & 0x01, dev->iobase + 4);
- outb_p(outval >> 9, dev->iobase + 6);
- outb_p(outval & 0xff, dev->iobase + 8);
-
- return 0;
-}
-
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency)
-{
- typhoon_setfreq_generic(dev, frequency);
- dev->curfreq = frequency;
- return 0;
-}
-
-static void typhoon_mute(struct typhoon_device *dev)
-{
- if (dev->muted == 1)
- return;
- typhoon_setvol_generic(dev, 0);
- typhoon_setfreq_generic(dev, dev->mutefreq);
- dev->muted = 1;
-}
-
-static void typhoon_unmute(struct typhoon_device *dev)
-{
- if (dev->muted == 0)
- return;
- typhoon_setfreq_generic(dev, dev->curfreq);
- typhoon_setvol_generic(dev, dev->curvol);
- dev->muted = 0;
-}
-
-static int typhoon_setvol(struct typhoon_device *dev, int vol)
-{
- if (dev->muted && vol != 0) { /* user is unmuting the card */
- dev->curvol = vol;
- typhoon_unmute(dev);
- return 0;
- }
- if (vol == dev->curvol) /* requested volume == current */
- return 0;
-
- if (vol == 0) { /* volume == 0 means mute the card */
- typhoon_mute(dev);
- dev->curvol = vol;
- return 0;
- }
- typhoon_setvol_generic(dev, vol);
- dev->curvol = vol;
- return 0;
-}
-
-
-static int typhoon_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct typhoon_device *typhoon = dev->priv;
-
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type = VID_TYPE_TUNER;
- v.channels = 1;
- v.audios = 1;
- /* No we don't do pictures */
- v.maxwidth = 0;
- v.maxheight = 0;
- v.minwidth = 0;
- v.minheight = 0;
- strcpy(v.name, "Typhoon Radio");
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg, sizeof(v)) != 0)
- return -EFAULT;
- if (v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow = 875 * 1600;
- v.rangehigh = 1080 * 1600;
- v.flags = VIDEO_TUNER_LOW;
- v.mode = VIDEO_MODE_AUTO;
- v.signal = 0xFFFF; /* We can't get the signal strength */
- strcpy(v.name, "FM");
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v.tuner != 0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if (copy_to_user(arg, &typhoon->curfreq,
- sizeof(typhoon->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if (copy_from_user(&typhoon->curfreq, arg,
- sizeof(typhoon->curfreq)))
- return -EFAULT;
- typhoon_setfreq(typhoon, typhoon->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v, 0, sizeof(v));
- v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
- v.mode |= VIDEO_SOUND_MONO;
- v.volume = typhoon->curvol;
- v.step = 1 << 14;
- strcpy(v.name, "Typhoon Radio");
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v.audio)
- return -EINVAL;
-
- if (v.flags & VIDEO_AUDIO_MUTE)
- typhoon_mute(typhoon);
- else
- typhoon_unmute(typhoon);
-
- if (v.flags & VIDEO_AUDIO_VOLUME)
- typhoon_setvol(typhoon, v.volume);
-
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int typhoon_open(struct video_device *dev, int flags)
-{
- struct typhoon_device *typhoon = dev->priv;
- if (typhoon->users)
- return -EBUSY;
- typhoon->users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void typhoon_close(struct video_device *dev)
-{
- struct typhoon_device *typhoon = dev->priv;
- typhoon->users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct typhoon_device typhoon_unit =
-{
- 0, /* users */
- CONFIG_RADIO_TYPHOON_PORT, /* iobase */
- 0, /* curvol */
- 0, /* muted */
- CONFIG_RADIO_TYPHOON_MUTEFREQ, /* curfreq */
- CONFIG_RADIO_TYPHOON_MUTEFREQ /* mutefreq */
-};
-
-static struct video_device typhoon_radio =
-{
- "Typhoon Radio",
- VID_TYPE_TUNER,
- VID_HARDWARE_TYPHOON,
- typhoon_open,
- typhoon_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL, /* Can't poll */
- typhoon_ioctl,
- NULL,
- NULL
-};
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
-
-static int typhoon_get_info(char *buf, char **start, off_t offset, int len)
-{
- char *out = buf;
-
- #ifdef MODULE
- #define MODULEPROCSTRING "Driver loaded as a module"
- #else
- #define MODULEPROCSTRING "Driver compiled into kernel"
- #endif
-
- /* output must be kept under PAGE_SIZE */
- out += sprintf(out, BANNER);
- out += sprintf(out, "Load type: " MODULEPROCSTRING "\n\n");
- out += sprintf(out, "frequency = %lu kHz\n",
- typhoon_unit.curfreq >> 4);
- out += sprintf(out, "volume = %d\n", typhoon_unit.curvol);
- out += sprintf(out, "mute = %s\n", typhoon_unit.muted ?
- "on" : "off");
- out += sprintf(out, "iobase = 0x%x\n", typhoon_unit.iobase);
- out += sprintf(out, "mute frequency = %lu kHz\n",
- typhoon_unit.mutefreq >> 4);
- return out - buf;
-}
-
-#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */
-
-MODULE_AUTHOR("Dr. Henrik Seidel");
-MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
-MODULE_PARM(mutefreq, "i");
-MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
-
-EXPORT_NO_SYMBOLS;
-
-static int io = -1;
-
-#ifdef MODULE
-static unsigned long mutefreq = 0;
-#endif
-
-static int __init typhoon_init(void)
-{
-#ifdef MODULE
- if (io == -1) {
- printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n");
- return -EINVAL;
- }
- typhoon_unit.iobase = io;
-
- if (mutefreq < 87000 || mutefreq > 108500) {
- printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n");
- printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
- return -EINVAL;
- }
- typhoon_unit.mutefreq = mutefreq;
-#endif /* MODULE */
-
- printk(KERN_INFO BANNER);
- io = typhoon_unit.iobase;
- if (check_region(io, 8)) {
- printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n",
- typhoon_unit.iobase);
- return -EBUSY;
- }
-
- typhoon_radio.priv = &typhoon_unit;
- if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO) == -1)
- return -EINVAL;
-
- request_region(typhoon_unit.iobase, 8, "typhoon");
- printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase);
- printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n",
- typhoon_unit.mutefreq);
- typhoon_unit.mutefreq <<= 4;
-
- /* mute card - prevents noisy bootups */
- typhoon_mute(&typhoon_unit);
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
- if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL,
- typhoon_get_info))
- printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n");
-#endif
-
- return 0;
-}
-
-static void __exit typhoon_cleanup_module(void)
-{
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
- remove_proc_entry("driver/radio-typhoon", NULL);
-#endif
-
- video_unregister_device(&typhoon_radio);
- release_region(io, 8);
-}
-
-module_init(typhoon_init);
-module_exit(typhoon_cleanup_module);
-
diff --git a/drivers/char/radio-zoltrix.c b/drivers/char/radio-zoltrix.c
deleted file mode 100644
index dd688935a..000000000
--- a/drivers/char/radio-zoltrix.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/* zoltrix radio plus driver for Linux radio support
- * (c) 1998 C. van Schaik <carl@leg.uct.ac.za>
- *
- * BUGS
- * Due to the inconsistancy in reading from the signal flags
- * it is difficult to get an accurate tuned signal.
- *
- * It seems that the card is not linear to 0 volume. It cuts off
- * at a low volume, and it is not possible (at least I have not found)
- * to get fine volume control over the low volume range.
- *
- * Some code derived from code by Romolo Manfredini
- * romolo@bicnet.it
- *
- * 1999-05-06 - (C. van Schaik)
- * - Make signal strength and stereo scans
- * kinder to cpu while in delay
- * 1999-01-05 - (C. van Schaik)
- * - Changed tuning to 1/160Mhz accuracy
- * - Added stereo support
- * (card defaults to stereo)
- * (can explicitly force mono on the card)
- * (can detect if station is in stereo)
- * - Added unmute function
- * - Reworked ioctl functions
- */
-
-#include <linux/module.h> /* Modules */
-#include <linux/init.h> /* Initdata */
-#include <linux/ioport.h> /* check_region, request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
-#include <linux/videodev.h> /* kernel radio structs */
-#include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */
-
-#ifndef CONFIG_RADIO_ZOLTRIX_PORT
-#define CONFIG_RADIO_ZOLTRIX_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_ZOLTRIX_PORT;
-static int users = 0;
-
-struct zol_device {
- int port;
- int curvol;
- unsigned long curfreq;
- int muted;
- unsigned int stereo;
- struct semaphore lock;
-};
-
-
-/* local things */
-
-static void sleep_delay(void)
-{
- /* Sleep nicely for +/- 10 mS */
- schedule();
-}
-
-static int zol_setvol(struct zol_device *dev, int vol)
-{
- dev->curvol = vol;
- if (dev->muted)
- return 0;
-
- down(&dev->lock);
- if (vol == 0) {
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
- up(&dev->lock);
- return 0;
- }
-
- outb(dev->curvol-1, io);
- sleep_delay();
- inb(io + 2);
- up(&dev->lock);
- return 0;
-}
-
-static void zol_mute(struct zol_device *dev)
-{
- dev->muted = 1;
- down(&dev->lock);
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
- up(&dev->lock);
-}
-
-static void zol_unmute(struct zol_device *dev)
-{
- dev->muted = 0;
- zol_setvol(dev, dev->curvol);
-}
-
-static int zol_setfreq(struct zol_device *dev, unsigned long freq)
-{
- /* tunes the radio to the desired frequency */
- unsigned long long bitmask, f, m;
- unsigned int stereo = dev->stereo;
- int i;
-
- if (freq == 0)
- return 1;
- m = (freq / 160 - 8800) * 2;
- f = (unsigned long long) m + 0x4d1c;
-
- bitmask = 0xc480402c10080000ull;
- i = 45;
-
- down(&dev->lock);
-
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
-
- outb(0x40, io);
- outb(0xc0, io);
-
- bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( stereo << 31));
- while (i--) {
- if ((bitmask & 0x8000000000000000ull) != 0) {
- outb(0x80, io);
- udelay(50);
- outb(0x00, io);
- udelay(50);
- outb(0x80, io);
- udelay(50);
- } else {
- outb(0xc0, io);
- udelay(50);
- outb(0x40, io);
- udelay(50);
- outb(0xc0, io);
- udelay(50);
- }
- bitmask *= 2;
- }
- /* termination sequence */
- outb(0x80, io);
- outb(0xc0, io);
- outb(0x40, io);
- udelay(1000);
- inb(io+2);
-
- udelay(1000);
-
- if (dev->muted)
- {
- outb(0, io);
- outb(0, io);
- inb(io + 3);
- udelay(1000);
- }
-
- up(&dev->lock);
-
- if(!dev->muted)
- {
- zol_setvol(dev, dev->curvol);
- }
- return 0;
-}
-
-/* Get signal strength */
-
-int zol_getsigstr(struct zol_device *dev)
-{
- int a, b;
-
- down(&dev->lock);
- outb(0x00, io); /* This stuff I found to do nothing */
- outb(dev->curvol, io);
- sleep_delay();
- sleep_delay();
-
- a = inb(io);
- sleep_delay();
- b = inb(io);
-
- up(&dev->lock);
-
- if (a != b)
- return (0);
-
- if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */
- || (a == 0xef)) /* with a binary scanner on the card io */
- return (1);
- return (0);
-}
-
-int zol_is_stereo (struct zol_device *dev)
-{
- int x1, x2;
-
- down(&dev->lock);
-
- outb(0x00, io);
- outb(dev->curvol, io);
- sleep_delay();
- sleep_delay();
-
- x1 = inb(io);
- sleep_delay();
- x2 = inb(io);
-
- up(&dev->lock);
-
- if ((x1 == x2) && (x1 == 0xcf))
- return 1;
- return 0;
-}
-
-static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct zol_device *zol = dev->priv;
-
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type = VID_TYPE_TUNER;
- v.channels = 1 + zol->stereo;
- v.audios = 1;
- /* No we don't do pictures */
- v.maxwidth = 0;
- v.maxheight = 0;
- v.minwidth = 0;
- v.minheight = 0;
- strcpy(v.name, "Zoltrix Radio");
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v.tuner)
- return -EINVAL;
- strcpy(v.name, "FM");
- v.rangelow = (int) (88.0 * 16000);
- v.rangehigh = (int) (108.0 * 16000);
- v.flags = zol_is_stereo(zol)
- ? VIDEO_TUNER_STEREO_ON : 0;
- v.flags |= VIDEO_TUNER_LOW;
- v.mode = VIDEO_MODE_AUTO;
- v.signal = 0xFFFF * zol_getsigstr(zol);
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v.tuner != 0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
- return 0;
- }
- case VIDIOCGFREQ:
- if (copy_to_user(arg, &zol->curfreq, sizeof(zol->curfreq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if (copy_from_user(&zol->curfreq, arg, sizeof(zol->curfreq)))
- return -EFAULT;
- zol_setfreq(zol, zol->curfreq);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v, 0, sizeof(v));
- v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
- v.mode != zol_is_stereo(zol)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- v.volume = zol->curvol * 4096;
- v.step = 4096;
- strcpy(v.name, "Zoltrix Radio");
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v.audio)
- return -EINVAL;
-
- if (v.flags & VIDEO_AUDIO_MUTE)
- zol_mute(zol);
- else
- {
- zol_unmute(zol);
- zol_setvol(zol, v.volume / 4096);
- }
-
- if (v.mode & VIDEO_SOUND_STEREO)
- {
- zol->stereo = 1;
- zol_setfreq(zol, zol->curfreq);
- }
- if (v.mode & VIDEO_SOUND_MONO)
- {
- zol->stereo = 0;
- zol_setfreq(zol, zol->curfreq);
- }
-
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static int zol_open(struct video_device *dev, int flags)
-{
- if (users)
- return -EBUSY;
- users++;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void zol_close(struct video_device *dev)
-{
- users--;
- MOD_DEC_USE_COUNT;
-}
-
-static struct zol_device zoltrix_unit;
-
-static struct video_device zoltrix_radio =
-{
- "Zoltrix Radio Plus",
- VID_TYPE_TUNER,
- VID_HARDWARE_ZOLTRIX,
- zol_open,
- zol_close,
- NULL, /* Can't read (no capture ability) */
- NULL, /* Can't write */
- NULL,
- zol_ioctl,
- NULL,
- NULL
-};
-
-static int __init zoltrix_init(void)
-{
- if (io == -1) {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
- return -EINVAL;
- }
- if (check_region(io, 2)) {
- printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
- return -EBUSY;
- }
- if ((io != 0x20c) && (io != 0x30c)) {
- printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
- return -ENXIO;
- }
- zoltrix_radio.priv = &zoltrix_unit;
-
- if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO) == -1)
- return -EINVAL;
-
- request_region(io, 2, "zoltrix");
- printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
-
- init_MUTEX(&zoltrix_unit.lock);
-
- /* mute card - prevents noisy bootups */
-
- /* this ensures that the volume is all the way down */
-
- outb(0, io);
- outb(0, io);
- sleep_delay();
- sleep_delay();
- inb(io + 3);
-
- zoltrix_unit.curvol = 0;
- zoltrix_unit.stereo = 1;
-
- return 0;
-}
-
-MODULE_AUTHOR("C.van Schaik");
-MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit zoltrix_cleanup_module(void)
-{
- video_unregister_device(&zoltrix_radio);
- release_region(io, 2);
-}
-
-module_init(zoltrix_init);
-module_exit(zoltrix_cleanup_module);
-
diff --git a/drivers/char/rio/linux_compat.h b/drivers/char/rio/linux_compat.h
index 3b6d2f3b1..ca1649f1e 100644
--- a/drivers/char/rio/linux_compat.h
+++ b/drivers/char/rio/linux_compat.h
@@ -72,8 +72,6 @@ struct ttystatics {
extern int rio_debug;
-#define rio_dprint(f, p) do {if (rio_debug & f) printk p;} while (0)
-
#define RIO_DEBUG_INIT 0x000001
#define RIO_DEBUG_BOOT 0x000002
#define RIO_DEBUG_CMD 0x000004
@@ -92,7 +90,7 @@ extern int rio_debug;
#define RIO_DEBUG_REC 0x008000
#define RIO_DEBUG_SPINLOCK 0x010000
#define RIO_DEBUG_DELAY 0x020000
-
+#define RIO_DEBUG_MOD_COUNT 0x040000
/* Copied over from riowinif.h . This is ugly. The winif file declares
also much other stuff which is incompatible with the headers from
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 01865a09d..93d1e1c46 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -249,6 +249,8 @@ long rio_irqmask = -1;
#ifndef TWO_ZERO
#ifdef MODULE
+MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
+MODULE_DESCRIPTION("RIO driver");
MODULE_PARM(rio_poll, "i");
MODULE_PARM(rio_debug, "i");
MODULE_PARM(rio_irqmask, "i");
@@ -394,26 +396,37 @@ void rio_udelay (int usecs)
void rio_inc_mod_count (void)
{
+#ifdef MODULE
func_enter ();
+ rio_dprintk (RIO_DEBUG_MOD_COUNT, "rio_inc_mod_count\n");
MOD_INC_USE_COUNT;
func_exit ();
+#endif
}
void rio_dec_mod_count (void)
{
+#ifdef MODULE
func_enter ();
+ rio_dprintk (RIO_DEBUG_MOD_COUNT, "rio_dec_mod_count\n");
MOD_DEC_USE_COUNT;
func_exit ();
+#endif
}
static int rio_set_real_termios (void *ptr)
{
- int rv;
+ int rv, modem;
+ struct tty_struct *tty;
func_enter();
- rv = RIOParam( (struct Port *) ptr, CONFIG, 0, 1);
+ tty = ((struct Port *)ptr)->gs.tty;
+
+ modem = (MAJOR(tty->device) == RIO_NORMAL_MAJOR0) || (MAJOR(tty->device) == RIO_NORMAL_MAJOR1);
+
+ rv = RIOParam( (struct Port *) ptr, CONFIG, modem, 1);
func_exit ();
@@ -631,6 +644,7 @@ static void rio_shutdown_port (void * ptr)
func_exit();
}
+
/* I haven't the foggiest why the decrement use count has to happen
here. The whole linux serial drivers stuff needs to be redesigned.
My guess is that this is a hack to minimize the impact of a bug
@@ -641,7 +655,7 @@ static void rio_shutdown_port (void * ptr)
static void rio_hungup (void *ptr)
{
func_enter ();
- /* rio_dec_mod_count (); */
+ rio_dec_mod_count ();
func_exit ();
}
@@ -652,9 +666,22 @@ static void rio_hungup (void *ptr)
*/
static void rio_close (void *ptr)
{
+ struct Port *PortP;
+
func_enter ();
+
+ PortP = (struct Port *)ptr;
+
riotclose (ptr);
+
+ if(PortP->gs.count) {
+ printk (KERN_ERR "WARNING port count:%d\n", PortP->gs.count);
+ PortP->gs.count = 0;
+ }
+
+
rio_dec_mod_count ();
+
func_exit ();
}
@@ -974,13 +1001,12 @@ static int rio_init_datastructures (void)
port->gs.close_delay = HZ/2;
port->gs.closing_wait = 30 * HZ;
port->gs.rd = &rio_real_driver;
-
+ port->portSem = SPIN_LOCK_UNLOCKED;
/*
* Initializing wait queue
*/
init_waitqueue_head(&port->gs.open_wait);
- init_waitqueue_head(&port->gs.close_wait);
-
+ init_waitqueue_head(&port->gs.close_wait);
}
#else
/* We could postpone initializing them to when they are configured. */
@@ -1010,7 +1036,7 @@ static int rio_init_datastructures (void)
return -ENOMEM;
}
-
+#ifdef MODULE
static void rio_release_drivers(void)
{
func_enter();
@@ -1020,6 +1046,7 @@ static void rio_release_drivers(void)
tty_unregister_driver (&rio_driver);
func_exit();
}
+#endif
#ifdef TWO_ZERO
#define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -1120,7 +1147,7 @@ int rio_init(void)
while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
pdev))) {
- if (pci_enable_device(pdev)) continue;
+ if (pci_enable_device(pdev)) continue;
#else
for (i=0;i< RIO_NBOARDS;i++) {
if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
@@ -1157,6 +1184,7 @@ int rio_init(void)
hp->Type = RIO_PCI;
hp->Copy = rio_pcicopy;
hp->Mode = RIO_PCI_BOOT_FROM_RAM;
+ hp->HostLock = SPIN_LOCK_UNLOCKED;
rio_reset_interrupt (hp);
rio_start_card_running (hp);
@@ -1206,7 +1234,7 @@ int rio_init(void)
while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_RIO,
pdev))) {
- if (pci_enable_device(pdev)) continue;
+ if (pci_enable_device(pdev)) continue;
#else
for (i=0;i< RIO_NBOARDS;i++) {
if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h
index c8b72bdce..4242197e5 100644
--- a/drivers/char/rio/rio_linux.h
+++ b/drivers/char/rio/rio_linux.h
@@ -29,6 +29,8 @@
#define RIO_PORTSPERBOARD 128
#define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD)
+#define MODEM_SUPPORT
+
#ifdef __KERNEL__
#define RIO_MAGIC 0x12345678
@@ -85,31 +87,34 @@ struct vpd_prom {
#endif
+void rio_dec_mod_count (void);
+void rio_inc_mod_count (void);
+
/* Allow us to debug "in the field" without requiring clients to
recompile.... */
#if 1
#define rio_spin_lock_irqsave(sem, flags) do { \
- rio_dprint(RIO_DEBUG_SPINLOCK, ("spinlockirqsave: %p %s:%d\n", \
- sem, __FILE__, __LINE__));\
+ rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \
+ sem, __FILE__, __LINE__);\
spin_lock_irqsave(sem, flags);\
} while (0)
#define rio_spin_unlock_irqrestore(sem, flags) do { \
- rio_dprint(RIO_DEBUG_SPINLOCK, ("spinunlockirqrestore: %p %s:%d\n",\
- sem, __FILE__, __LINE__));\
+ rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\
+ sem, __FILE__, __LINE__);\
spin_unlock_irqrestore(sem, flags);\
} while (0)
#define rio_spin_lock(sem) do { \
- rio_dprint(RIO_DEBUG_SPINLOCK, ("spinlock: %p %s:%d\n",\
- sem, __FILE__, __LINE__));\
+ rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\
+ sem, __FILE__, __LINE__);\
spin_lock(sem);\
} while (0)
#define rio_spin_unlock(sem) do { \
- rio_dprint(RIO_DEBUG_SPINLOCK, ("spinunlock: %p %s:%d\n",\
- sem, __FILE__, __LINE__));\
+ rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\
+ sem, __FILE__, __LINE__);\
spin_unlock(sem);\
} while (0)
#else
@@ -173,7 +178,7 @@ static inline void *rio_memcpy_fromio (void *dest, void *source, int n)
*/
#ifdef DEBUG
-#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
+#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0)
#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit " __FUNCTION__ "\n")
#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
index 8168f2133..d5ab5ba02 100644
--- a/drivers/char/rio/rioboot.c
+++ b/drivers/char/rio/rioboot.c
@@ -118,13 +118,13 @@ struct DownLoad * rbp;
"copyin". (Crash when a pagefault occurs). */
/* disable(oldspl); */
- rio_dprint(RIO_DEBUG_BOOT, ("Data at user address 0x%x\n",(int)rbp->DataP));
+ rio_dprintk (RIO_DEBUG_BOOT, "Data at user address 0x%x\n",(int)rbp->DataP);
/*
** Check that we have set asside enough memory for this
*/
if ( rbp->Count > SIXTY_FOUR_K ) {
- rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code Too Large!\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n");
p->RIOError.Error = HOST_FILE_TOO_LARGE;
/* restore(oldspl); */
func_exit ();
@@ -132,7 +132,7 @@ struct DownLoad * rbp;
}
if ( p->RIOBooting ) {
- rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code : BUSY BUSY BUSY!\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n");
p->RIOError.Error = BOOT_IN_PROGRESS;
/* restore(oldspl); */
func_exit ();
@@ -160,7 +160,7 @@ struct DownLoad * rbp;
if ( copyin((int)rbp->DataP,((caddr_t)(p->RIOBootPackets))+offset,
rbp->Count) ==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Bad data copy from user space\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Bad data copy from user space\n");
p->RIOError.Error = COPYIN_FAILED;
/* restore(oldspl); */
func_exit ();
@@ -185,7 +185,7 @@ void rio_start_card_running (struct Host * HostP)
switch ( HostP->Type ) {
case RIO_AT:
- rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Start ISA card running\n");
WBYTE(HostP->Control,
BOOT_FROM_RAM | EXTERNAL_BUS_ON
| HostP->Mode
@@ -198,7 +198,7 @@ void rio_start_card_running (struct Host * HostP)
** MCA handles IRQ vectors differently, so we don't write
** them to this register.
*/
- rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Start MCA card running\n");
WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
break;
@@ -206,7 +206,7 @@ void rio_start_card_running (struct Host * HostP)
/*
** EISA is totally different and expects OUTBZs to turn it on.
*/
- rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n");
+ rio_dprintk (RIO_DEBUG_BOOT, "Start EISA card running\n");
OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
break;
#endif
@@ -217,11 +217,11 @@ void rio_start_card_running (struct Host * HostP)
** mapped, so we are writing to memory registers instead of io
** ports.
*/
- rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Start PCI card running\n");
WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
break;
default:
- rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type));
+ rio_dprintk (RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type);
break;
}
/*
@@ -260,15 +260,15 @@ register struct DownLoad *rbp;
HostP = NULL; /* Assure the compiler we've initialized it */
for ( host=0; host<p->RIONumHosts; host++ ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Attempt to boot host %d\n",host));
+ rio_dprintk (RIO_DEBUG_BOOT, "Attempt to boot host %d\n",host);
HostP = &p->RIOHosts[host];
- rio_dprint(RIO_DEBUG_BOOT, ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
- HostP->Type, HostP->Mode, HostP->Ivec ) );
+ rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+ HostP->Type, HostP->Mode, HostP->Ivec);
if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) {
- rio_dprint(RIO_DEBUG_BOOT, ("%s %d already running\n","Host",host));
+ rio_dprintk (RIO_DEBUG_BOOT, "%s %d already running\n","Host",host);
continue;
}
@@ -285,13 +285,13 @@ register struct DownLoad *rbp;
*/
StartP = (caddr_t)&Cad[p->RIOConf.HostLoadBase-rbp->Count];
- rio_dprint(RIO_DEBUG_BOOT, ("kernel virtual address for host is 0x%x\n", (int)Cad ) );
- rio_dprint(RIO_DEBUG_BOOT, ("kernel virtual address for download is 0x%x\n", (int)StartP ) );
- rio_dprint(RIO_DEBUG_BOOT, ("host loadbase is 0x%x\n",p->RIOConf.HostLoadBase));
- rio_dprint(RIO_DEBUG_BOOT, ("size of download is 0x%x\n", rbp->Count ) );
+ rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for host is 0x%x\n", (int)Cad );
+ rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for download is 0x%x\n", (int)StartP);
+ rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
+ rio_dprintk (RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count);
if ( p->RIOConf.HostLoadBase < rbp->Count ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Bin too large\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Bin too large\n");
p->RIOError.Error = HOST_FILE_TOO_LARGE;
func_exit ();
return EFBIG;
@@ -307,7 +307,7 @@ register struct DownLoad *rbp;
** This ain't going to be none too clever if the download
** code is bigger than this segment.
*/
- rio_dprint(RIO_DEBUG_BOOT, ("Copy in code\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Copy in code\n");
/*
** PCI hostcard can't cope with 32 bit accesses and so need to copy
@@ -318,7 +318,7 @@ register struct DownLoad *rbp;
DownCode = sysbrk(rbp->Count);
if ( !DownCode ) {
- rio_dprint(RIO_DEBUG_BOOT, ("No system memory available\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "No system memory available\n");
p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY;
func_exit ();
return ENOMEM;
@@ -326,7 +326,7 @@ register struct DownLoad *rbp;
bzero(DownCode, rbp->Count);
if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
p->RIOError.Error = COPYIN_FAILED;
func_exit ();
return EFAULT;
@@ -337,13 +337,13 @@ register struct DownLoad *rbp;
sysfree( DownCode, rbp->Count );
}
else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
p->RIOError.Error = COPYIN_FAILED;
func_exit ();
return EFAULT;
}
- rio_dprint(RIO_DEBUG_BOOT, ("Copy completed\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Copy completed\n");
/*
** S T O P !
@@ -444,8 +444,8 @@ register struct DownLoad *rbp;
WBYTE( DestP[6] , NFIX(0) );
WBYTE( DestP[7] , JUMP(8) );
- rio_dprint(RIO_DEBUG_BOOT, ("host loadbase is 0x%x\n",p->RIOConf.HostLoadBase));
- rio_dprint(RIO_DEBUG_BOOT, ("startup offset is 0x%x\n",offset));
+ rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
+ rio_dprintk (RIO_DEBUG_BOOT, "startup offset is 0x%x\n",offset);
/*
** Flag what is going on
@@ -459,19 +459,19 @@ register struct DownLoad *rbp;
*/
OldParmMap = RWORD(HostP->__ParmMapR);
- rio_dprint(RIO_DEBUG_BOOT, ("Original parmmap is 0x%x\n",OldParmMap));
+ rio_dprintk (RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n",OldParmMap);
/*
** And start it running (I hope).
** As there is nothing dodgy or obscure about the
** above code, this is guaranteed to work every time.
*/
- rio_dprint(RIO_DEBUG_BOOT, ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
- HostP->Type, HostP->Mode, HostP->Ivec ) );
+ rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+ HostP->Type, HostP->Mode, HostP->Ivec);
rio_start_card_running(HostP);
- rio_dprint(RIO_DEBUG_BOOT, ("Set control port\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Set control port\n");
/*
** Now, wait for upto five seconds for the Tp to setup the parmmap
@@ -479,7 +479,7 @@ register struct DownLoad *rbp;
*/
for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&
(RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)));
+ rio_dprintk (RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR));
delay(HostP, HUNDRED_MS);
}
@@ -489,8 +489,8 @@ register struct DownLoad *rbp;
** has crashed & burned in a really spectacular way
*/
if ( RWORD(HostP->__ParmMapR) == OldParmMap ) {
- rio_dprint(RIO_DEBUG_BOOT, ("parmmap 0x%x\n", RWORD(HostP->__ParmMapR)));
- rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR));
+ rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n");
#define HOST_DISABLE \
HostP->Flags &= ~RUN_STATE; \
@@ -501,7 +501,7 @@ register struct DownLoad *rbp;
HOST_DISABLE;
}
- rio_dprint(RIO_DEBUG_BOOT, ("Running 0x%x\n",RWORD(HostP->__ParmMapR)));
+ rio_dprintk (RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR));
/*
** Well, the board thought it was OK, and setup its parmmap
@@ -513,10 +513,10 @@ register struct DownLoad *rbp;
** Grab a 32 bit pointer to the parmmap structure
*/
ParmMapP = (PARM_MAP *)RIO_PTR(Cad,RWORD(HostP->__ParmMapR));
- rio_dprint(RIO_DEBUG_BOOT, ("ParmMapP : %x\n", (int)ParmMapP));
+ rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
ParmMapP = (PARM_MAP *)((unsigned long)Cad +
(unsigned long)((RWORD((HostP->__ParmMapR))) & 0xFFFF));
- rio_dprint(RIO_DEBUG_BOOT, ("ParmMapP : %x\n", (int)ParmMapP));
+ rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
/*
** The links entry should be 0xFFFF; we set it up
@@ -524,8 +524,8 @@ register struct DownLoad *rbp;
** which links to use.
*/
if ( (RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF ) {
- rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail %s\n", HostP->Name));
- rio_dprint(RIO_DEBUG_BOOT, ("Links = 0x%x\n",RWORD(ParmMapP->links)));
+ rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
+ rio_dprintk (RIO_DEBUG_BOOT, "Links = 0x%x\n",RWORD(ParmMapP->links));
HOST_DISABLE;
}
@@ -535,28 +535,28 @@ register struct DownLoad *rbp;
** now wait for the card to set all the parmmap->XXX stuff
** this is a wait of upto two seconds....
*/
- rio_dprint(RIO_DEBUG_BOOT, ("Looking for init_done - %d ticks\n",p->RIOConf.StartupTime));
+ rio_dprintk (RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n",p->RIOConf.StartupTime);
HostP->timeout_id = 0;
for ( wait_count=0; (wait_count<p->RIOConf.StartupTime) &&
!RWORD(ParmMapP->init_done); wait_count++ ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Waiting for init_done\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Waiting for init_done\n");
delay(HostP, HUNDRED_MS);
}
- rio_dprint(RIO_DEBUG_BOOT, ("OK! init_done!\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "OK! init_done!\n");
if (RWORD(ParmMapP->error) != E_NO_ERROR ||
!RWORD(ParmMapP->init_done) ) {
- rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail %s\n", HostP->Name));
- rio_dprint(RIO_DEBUG_BOOT, ("Timedout waiting for init_done\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
+ rio_dprintk (RIO_DEBUG_BOOT, "Timedout waiting for init_done\n");
HOST_DISABLE;
}
- rio_dprint(RIO_DEBUG_BOOT, ("Got init_done\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Got init_done\n");
/*
** It runs! It runs!
*/
- rio_dprint(RIO_DEBUG_BOOT, ("Host ID %x Running\n",HostP->UniqueNum));
+ rio_dprintk (RIO_DEBUG_BOOT, "Host ID %x Running\n",HostP->UniqueNum);
/*
** set the time period between interrupts.
@@ -580,12 +580,14 @@ register struct DownLoad *rbp;
HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN];
HostP->UnixRups[RupN].Id = RupN+1;
HostP->UnixRups[RupN].BaseSysPort = NO_PORT;
+ HostP->UnixRups[RupN].RupLock = SPIN_LOCK_UNLOCKED;
}
for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) {
HostP->UnixRups[RupN+MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup;
HostP->UnixRups[RupN+MAX_RUP].Id = 0;
HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT;
+ HostP->UnixRups[RupN+MAX_RUP].RupLock = SPIN_LOCK_UNLOCKED;
}
/*
@@ -622,7 +624,7 @@ register struct DownLoad *rbp;
}
}
- rio_dprint(RIO_DEBUG_BOOT, ("Set the card running... \n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Set the card running... \n");
/*
** last thing - show the world that everything is in place
*/
@@ -638,7 +640,7 @@ register struct DownLoad *rbp;
p->RIOSystemUp++;
- rio_dprint(RIO_DEBUG_BOOT, ("Done everything %x\n", HostP->Ivec));
+ rio_dprintk (RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec);
func_exit ();
return 0;
}
@@ -672,7 +674,7 @@ struct PKT *PacketP;
** If we haven't been told what to boot, we can't boot it.
*/
if ( p->RIONumBootPkts == 0 ) {
- rio_dprint(RIO_DEBUG_BOOT, ("No RTA code to download yet\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n");
return 0;
}
@@ -693,7 +695,7 @@ struct PKT *PacketP;
** try to unhook a command block from the command free list.
*/
if ( !(CmdBlkP = RIOGetCmdBlk()) ) {
- rio_dprint(RIO_DEBUG_BOOT, ("No command blocks to boot RTA! come back later.\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n");
return 0;
}
@@ -716,8 +718,8 @@ struct PKT *PacketP;
** We only expect one type of command - a BOOT_REQUEST!
*/
if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Unexpected command %d on BOOT RUP %d of host %d\n",
- PktCmdP->Command,Rup,HostP-p->RIOHosts));
+ rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n",
+ PktCmdP->Command,Rup,HostP-p->RIOHosts);
ShowPacket( DBG_BOOT, PacketP );
RIOFreeCmdBlk( CmdBlkP );
return 1;
@@ -754,9 +756,9 @@ struct PKT *PacketP;
bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4);
- rio_dprint(RIO_DEBUG_BOOT, ("Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
+ rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts,
- p->RIOConf.RtaLoadBase));
+ p->RIOConf.RtaLoadBase);
/*
** If this host is in slave mode, send the RTA an invalid boot
@@ -775,11 +777,11 @@ struct PKT *PacketP;
*/
sequence = RWORD(PktCmdP->Sequence);
- rio_dprint(RIO_DEBUG_BOOT, ("Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup));
+ rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup);
if ( sequence >= p->RIONumBootPkts ) {
- rio_dprint(RIO_DEBUG_BOOT, ("Got a request for packet %d, max is %d\n", sequence,
- p->RIONumBootPkts));
+ rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence,
+ p->RIONumBootPkts);
ShowPacket( DBG_BOOT, PacketP );
}
@@ -821,26 +823,26 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
driver will never think that the RTA has booted... -- REW */
p->RIOBooting = 0;
- rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot completed - BootInProgress now %d\n", p->RIOBooting));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting);
/*
** Determine type of unit (16/8 port RTA).
*/
RtaType = GetUnitType(RtaUniq);
if ( Rup >= (ushort)MAX_RUP ) {
- rio_dprint(RIO_DEBUG_BOOT, ("RIO: Host %s has booted an RTA(%d) on link %c\n",
- HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A' ));
+ rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n",
+ HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A');
} else {
- rio_dprint(RIO_DEBUG_BOOT, ("RIO: RTA %s has booted an RTA(%d) on link %c\n",
+ rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n",
HostP->Mapping[Rup].Name, 8 * RtaType,
- RBYTE(PktCmdP->LinkNum)+'A'));
+ RBYTE(PktCmdP->LinkNum)+'A');
}
- rio_dprint(RIO_DEBUG_BOOT, ("UniqNum is 0x%x\n",RtaUniq));
+ rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq);
if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) )
{
- rio_dprint(RIO_DEBUG_BOOT, ( "Illegal RTA Uniq Number\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n");
return TRUE;
}
@@ -861,8 +863,8 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
*/
if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink))
{
- rio_dprint(RIO_DEBUG_BOOT, ("RTA failed to suspend booting on link %c\n",
- 'A' + MyLink));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n",
+ 'A' + MyLink);
}
}
else
@@ -874,8 +876,8 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
*/
WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30);
}
- rio_dprint(RIO_DEBUG_BOOT, ("RTA %x not owned - suspend booting down link %c on unit %x\n",
- RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n",
+ RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum);
return TRUE;
}
@@ -925,16 +927,16 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
}
}
if (RtaType == TYPE_RTA16) {
- rio_dprint(RIO_DEBUG_BOOT, ("RTA will be given IDs %d+%d\n",
- entry+1, entry2+1));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n",
+ entry+1, entry2+1);
} else {
- rio_dprint(RIO_DEBUG_BOOT, ("RTA will be given ID %d\n",entry+1));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given ID %d\n",entry+1);
}
return TRUE;
}
}
- rio_dprint(RIO_DEBUG_BOOT, ("RTA not configured for this host\n"));
+ rio_dprintk (RIO_DEBUG_BOOT, "RTA not configured for this host\n");
if ( Rup >= (ushort)MAX_RUP )
{
@@ -978,13 +980,13 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
entry2 = HostP->Mapping[entry].ID2 - 1;
if ( (HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) &&
(HostP->Mapping[entry2].RtaUniqueNum == RtaUniq) )
- rio_dprint(RIO_DEBUG_BOOT, ("Found previous tentative slots (%d+%d)\n",
- entry, entry2));
+ rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n",
+ entry, entry2);
else
continue;
}
else
- rio_dprint(RIO_DEBUG_BOOT, ("Found previous tentative slot (%d)\n",entry));
+ rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n",entry);
if (! p->RIONoMessage)
cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A');
return TRUE;
@@ -1013,7 +1015,7 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
** + Configure RTA on host A. We now have the same RTA configured
** with different ports on two different hosts.
*/
- rio_dprint(RIO_DEBUG_BOOT, ("Have we seen RTA %x before?\n", RtaUniq ));
+ rio_dprintk (RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq );
found = 0;
Flag = 0; /* Convince the compiler this variable is initialized */
for ( host = 0; !found && (host < p->RIONumHosts); host++ )
@@ -1029,12 +1031,12 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
if (RtaType == TYPE_RTA16)
{
MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1];
- rio_dprint(RIO_DEBUG_BOOT, ("This RTA is units %d+%d from host %s\n",
- rta+1, MapP->ID2, p->RIOHosts[host].Name ));
+ rio_dprintk (RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n",
+ rta+1, MapP->ID2, p->RIOHosts[host].Name);
}
else
- rio_dprint(RIO_DEBUG_BOOT, ("This RTA is unit %d from host %s\n",
- rta+1, p->RIOHosts[host].Name ));
+ rio_dprintk (RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n",
+ rta+1, p->RIOHosts[host].Name);
found = 1;
break;
}
@@ -1052,12 +1054,12 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
*/
if ( !MapP )
{
- rio_dprint(RIO_DEBUG_BOOT, ("Look for RTA %x in RIOSavedTable\n",RtaUniq));
+ rio_dprintk (RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n",RtaUniq);
for ( rta=0; rta < TOTAL_MAP_ENTRIES; rta++ )
{
- rio_dprint(RIO_DEBUG_BOOT, ("Check table entry %d (%x)",
+ rio_dprintk (RIO_DEBUG_BOOT, "Check table entry %d (%x)",
rta,
- p->RIOSavedTable[rta].RtaUniqueNum ));
+ p->RIOSavedTable[rta].RtaUniqueNum);
if ( (p->RIOSavedTable[rta].Flags & SLOT_IN_USE) &&
(p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq) )
@@ -1073,11 +1075,11 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
break;
}
MapP2 = &p->RIOSavedTable[entry2];
- rio_dprint(RIO_DEBUG_BOOT, ("This RTA is from table entries %d+%d\n",
- rta, entry2));
+ rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n",
+ rta, entry2);
}
else
- rio_dprint(RIO_DEBUG_BOOT, ("This RTA is from table entry %d\n", rta));
+ rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta);
break;
}
}
@@ -1133,8 +1135,8 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
{
if (Flag & SLOT_IN_USE)
{
- rio_dprint(RIO_DEBUG_BOOT, (
- "This RTA configured on another host - move entry to current host (1)\n"));
+ rio_dprintk (RIO_DEBUG_BOOT,
+ "This RTA configured on another host - move entry to current host (1)\n");
HostP->Mapping[entry].SysPort = MapP->SysPort;
CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN );
HostP->Mapping[entry].Flags =
@@ -1147,12 +1149,12 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort;
if ( HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted )
p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort;
- rio_dprint(RIO_DEBUG_BOOT, ("SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name));
+ rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name);
}
else
{
- rio_dprint(RIO_DEBUG_BOOT, (
- "This RTA has a tentative entry on another host - delete that entry (1)\n"));
+ rio_dprintk (RIO_DEBUG_BOOT,
+ "This RTA has a tentative entry on another host - delete that entry (1)\n");
HostP->Mapping[entry].Flags =
SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT;
#if NEED_TO_FIX
@@ -1177,9 +1179,9 @@ int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct Pk
p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort;
if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted)
p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort;
- rio_dprint(RIO_DEBUG_BOOT, ("SysPort %d, Name %s\n",
+ rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",
(int)HostP->Mapping[entry2].SysPort,
- HostP->Mapping[entry].Name));
+ HostP->Mapping[entry].Name);
}
else
HostP->Mapping[entry2].Flags = SLOT_TENTATIVE |
@@ -1272,7 +1274,7 @@ struct Host *HostP;
{
int link;
- rio_dprint(RIO_DEBUG_BOOT, ("FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq));
+ rio_dprintk (RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq);
HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE);
HostP->Mapping[entry].SysPort = NO_PORT;
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 835d815d3..3a330a07c 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -91,12 +91,12 @@ struct Map * MapP;
{
struct CmdBlk *CmdBlkP;
- rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n");
CmdBlkP = RIOGetCmdBlk();
if ( !CmdBlkP ) {
- rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA: GetCmdBlk failed\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
return ENXIO;
}
@@ -111,7 +111,7 @@ struct Map * MapP;
CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF;
if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA: Failed to queue foad command\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
return EIO;
}
return 0;
@@ -124,12 +124,12 @@ struct Map * MapP;
{
struct CmdBlk *CmdBlkP;
- rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n");
CmdBlkP = RIOGetCmdBlk();
if ( !CmdBlkP ) {
- rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA: GetCmdBlk failed\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
return ENXIO;
}
@@ -144,7 +144,7 @@ struct Map * MapP;
CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF;
if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA: Failed to queue zombie command\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
return EIO;
}
return 0;
@@ -158,7 +158,7 @@ int (* func)( struct Host *HostP, struct Map *MapP );
{
uint Host;
- rio_dprint(RIO_DEBUG_CMD, ("Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func ));
+ rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func);
if ( !RtaUnique )
return(0);
@@ -203,7 +203,7 @@ caddr_t arg;
uint Host;
if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("RIO_IDENTIFY_RTA copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
@@ -231,12 +231,12 @@ caddr_t arg;
*/
struct CmdBlk *CmdBlkP;
- rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n");
CmdBlkP = RIOGetCmdBlk();
if ( !CmdBlkP ) {
- rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA: GetCmdBlk failed\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
return ENXIO;
}
@@ -249,9 +249,8 @@ caddr_t arg;
CmdBlkP->Packet.data[1] = 0;
CmdBlkP->Packet.data[2] = IdRta.ID;
- if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP)
- == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA: Failed to queue command\n"));
+ if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
+ rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
return EIO;
}
return 0;
@@ -274,11 +273,10 @@ caddr_t arg;
struct Host *HostP;
struct CmdBlk *CmdBlkP;
- rio_dprint(RIO_DEBUG_CMD, ("KILL HOST NEIGHBOUR\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");
- if ( copyin( (int)arg, (caddr_t)&KillUnit,
- sizeof(KillUnit) ) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("RIO_KILL_NEIGHBOUR copy failed\n"));
+ if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
+ rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
@@ -289,7 +287,7 @@ caddr_t arg;
CmdBlkP = RIOGetCmdBlk();
if ( !CmdBlkP ) {
- rio_dprint(RIO_DEBUG_CMD, ("UFOAD: GetCmdBlk failed\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
return ENXIO;
}
@@ -310,7 +308,7 @@ caddr_t arg;
if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
CmdBlkP) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("UFOAD: Failed queue command\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
return EIO;
}
return 0;
@@ -320,7 +318,7 @@ caddr_t arg;
if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
CmdBlkP->Packet.dest_unit = ID+1;
if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("UFOAD: Failed queue command\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
return EIO;
}
return 0;
@@ -339,12 +337,12 @@ int Link;
{
struct CmdBlk *CmdBlkP;
- rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link));
+ rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);
CmdBlkP = RIOGetCmdBlk();
if ( !CmdBlkP ) {
- rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA: GetCmdBlk failed\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
return ENXIO;
}
@@ -359,7 +357,7 @@ int Link;
CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF;
if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA: Failed to queue iwait command\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
return EIO;
}
return 0;
@@ -416,6 +414,7 @@ PKT *PacketP;
ushort subCommand;
unsigned long flags;
+ func_enter ();
#ifdef CHECK
CheckHost( Host );
@@ -435,34 +434,35 @@ PKT *PacketP;
UnixRupP = &HostP->UnixRups[rup];
SysPort = UnixRupP->BaseSysPort +
(RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
- rio_dprint(RIO_DEBUG_CMD, ("Command on rup %d, port %d\n", rup, SysPort));
+ rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);
#ifdef CHECK
CheckRup( rup );
CheckUnixRupP( UnixRupP );
#endif
if ( UnixRupP->BaseSysPort == NO_PORT ) {
- rio_dprint(RIO_DEBUG_CMD, ("OBSCURE ERROR!\n"));
- rio_dprint(RIO_DEBUG_CMD, ("Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"));
- rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: Host number %d, name ``%s''\n",
- HostP-p->RIOHosts, HostP->Name ));
- rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: Rup number 0x%x\n", rup));
-
- if ( Rup >= (ushort)MAX_RUP )
- rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: This is the RUP for RTA ``%s''\n",
- HostP->Mapping[Rup].Name ));
- else
- rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 'A' + Rup - MAX_RUP, HostP->Name ));
-
- rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Destination 0x%x:0x%x\n",
- PacketP->dest_unit, PacketP->dest_port ));
- rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Source 0x%x:0x%x\n",
- PacketP->src_unit, PacketP->src_port ));
- rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Length 0x%x (%d)\n", PacketP->len,PacketP->len ));
- rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Control 0x%x (%d)\n", PacketP->control, PacketP->control));
- rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Check 0x%x (%d)\n", PacketP->csum, PacketP->csum ));
- rio_dprint(RIO_DEBUG_CMD, ("COMMAND information: Host Port Number 0x%x,
- Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command ));
+ rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
+ rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
+ rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n",
+ HostP-p->RIOHosts, HostP->Name );
+ rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup);
+
+ if ( Rup >= (ushort)MAX_RUP ) {
+ rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",
+ HostP->Mapping[Rup].Name);
+ } else
+ rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n",
+ ('A' + Rup - MAX_RUP), HostP->Name);
+
+ rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",
+ PacketP->dest_unit, PacketP->dest_port );
+ rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n",
+ PacketP->src_unit, PacketP->src_port );
+ rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", PacketP->len,PacketP->len );
+ rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", PacketP->control, PacketP->control);
+ rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", PacketP->csum, PacketP->csum );
+ rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x,
+ Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );
return TRUE;
}
@@ -470,13 +470,10 @@ PKT *PacketP;
CheckSysPort( SysPort );
#endif
PortP = p->RIOPortp[ SysPort ];
-#if 0
- ttyP = PortP->TtyP;
-#endif
rio_spin_lock_irqsave(&PortP->portSem, flags);
switch( RBYTE(PktCmdP->Command) ) {
case BREAK_RECEIVED:
- rio_dprint(RIO_DEBUG_CMD, ("Received a break!\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");
/* If the current line disc. is not multi-threading and
the current processor is not the default, reset rup_intr
and return FALSE to ensure that the command packet is
@@ -486,16 +483,16 @@ PKT *PacketP;
break;
case COMPLETE:
- rio_dprint(RIO_DEBUG_CMD, ("Command complete on phb %d host %d\n",
- RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts));
+ rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",
+ RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
subCommand = 1;
switch (RBYTE(PktCmdP->SubCommand)) {
case MEMDUMP :
- rio_dprint(RIO_DEBUG_CMD, ("Memory dump cmd (0x%x) from addr 0x%x\n",
- RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr)));
+ rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",
+ RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
break;
case READ_REGISTER :
- rio_dprint(RIO_DEBUG_CMD, ("Read register (0x%x)\n", RWORD(PktCmdP->SubAddr)));
+ rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));
p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
break;
default :
@@ -504,18 +501,16 @@ PKT *PacketP;
}
if (subCommand)
break;
- rio_dprint(RIO_DEBUG_CMD, ("New status is 0x%x was 0x%x\n",
- RBYTE(PktCmdP->PortStatus),PortP->PortState));
+ rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",
+ RBYTE(PktCmdP->PortStatus),PortP->PortState);
if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
- rio_dprint(RIO_DEBUG_CMD, ("Mark status & wakeup\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");
PortP->PortState = RBYTE(PktCmdP->PortStatus);
/* What should we do here ...
wakeup( &PortP->PortState );
*/
- }
- else {
- rio_dprint(RIO_DEBUG_CMD, ("No change\n"));
- }
+ } else
+ rio_dprintk (RIO_DEBUG_CMD, "No change\n");
/* FALLTHROUGH */
case MODEM_STATUS:
@@ -527,7 +522,7 @@ PKT *PacketP;
ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
if ((PortP->ModemState & MSVR1_HOST) ==
(ReportedModemStatus & MSVR1_HOST)) {
- rio_dprint(RIO_DEBUG_CMD, ("Modem status unchanged 0x%x\n", PortP->ModemState));
+ rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
/*
** Update ModemState just in case tbusy or tstop states have
** changed.
@@ -535,8 +530,8 @@ PKT *PacketP;
PortP->ModemState = ReportedModemStatus;
}
else {
- rio_dprint(RIO_DEBUG_CMD, ("Modem status change from 0x%x to 0x%x\n",
- PortP->ModemState, ReportedModemStatus));
+ rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",
+ PortP->ModemState, ReportedModemStatus);
PortP->ModemState = ReportedModemStatus;
#ifdef MODEM_SUPPORT
if ( PortP->Mapped ) {
@@ -551,50 +546,41 @@ PKT *PacketP;
** If the device is a modem, then check the modem
** carrier.
*/
- if(!(ttyP->t_cflag & CLOCAL) &&
- ((PortP->State & (RIO_MOPEN|RIO_WOPEN))))
- {
+ if (PortP->gs.tty == NULL)
+ break;
+
+ if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
+ ((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
+
+ rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");
/*
** Is there a carrier?
*/
- if ( PortP->ModemState & MSVR1_CD )
- {
+ if ( PortP->ModemState & MSVR1_CD ) {
/*
** Has carrier just appeared?
*/
- if (!(ttyP->t_state & CARR_ON))
- {
- rio_dprint(RIO_DEBUG_CMD, PortP,DBG_MODEM,"Carrier just came up.\n");
- ttyP->t_state |=CARR_ON;
+ if (!(PortP->State & RIO_CARR_ON)) {
+ rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");
+ PortP->State |= RIO_CARR_ON;
/*
** wakeup anyone in WOPEN
*/
- if ( ttyP->t_state & (ISOPEN|WOPEN) )
- wakeup((caddr_t)&ttyP->t_canq);
+ if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
+ wake_up_interruptible (&PortP->gs.open_wait);
#ifdef STATS
PortP->Stat.ModemOnCnt++;
#endif
}
- }
- else
- {
+ } else {
/*
** Has carrier just dropped?
*/
- if (ttyP->t_state & CARR_ON)
- {
- /*
- ** send SIGHUP to the process group
- */
- if ( ttyP->t_state & (ISOPEN|WOPEN) )
- {
- signal(ttyP->t_pgrp,SIGHUP);
- ttyflush(ttyP,(FREAD|FWRITE));
- }
- ttyP->t_state &= ~CARR_ON;
- wakeup( (caddr_t)&PortP->TxBufferOut );
- wakeup( (caddr_t)&PortP->TxBufferIn );
- rio_dprint(RIO_DEBUG_CMD, PortP,DBG_MODEM,"Carrier just went down.\n");
+ if (PortP->State & RIO_CARR_ON) {
+ if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
+ tty_hangup (PortP->gs.tty);
+ PortP->State &= ~RIO_CARR_ON;
+ rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");
#ifdef STATS
PortP->Stat.ModemOffCnt++;
#endif
@@ -607,11 +593,14 @@ PKT *PacketP;
break;
default:
- rio_dprint(RIO_DEBUG_CMD, ("Unknown command %d on CMD_RUP of host %d\n",
- RBYTE(PktCmdP->Command),HostP-p->RIOHosts));
+ rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",
+ RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
break;
}
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+
+ func_exit ();
+
return TRUE;
}
/*
@@ -667,11 +656,8 @@ struct CmdBlk *CmdBlkP;
CheckRup( Rup );
CheckCmdBlkP( CmdBlkP );
#endif
-
- rio_dprint(RIO_DEBUG_CMD, ("RIOQueueCmdBlk(Host, Rup %d, 0x%x)\n", Rup, (int)CmdBlkP ));
-
if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
- rio_dprint(RIO_DEBUG_CMD, ("Illegal rup number %d in RIOQueueCmdBlk\n",Rup));
+ rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);
RIOFreeCmdBlk( CmdBlkP );
return RIO_FAIL;
}
@@ -685,11 +671,12 @@ struct CmdBlk *CmdBlkP;
** straight on the RUP....
*/
if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) &&
- (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) &&
+ (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
:TRUE)) {
- rio_dprint(RIO_DEBUG_CMD, ("RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
- CmdBlkP->Packet.data[0]));
+ rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
+ CmdBlkP->Packet.data[0]);
+
/*
** Whammy! blat that pack!
@@ -711,28 +698,27 @@ struct CmdBlk *CmdBlkP;
return RIO_SUCCESS;
}
-
- rio_dprint(RIO_DEBUG_CMD, ("RUP active - en-queing\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");
if ( UnixRupP->CmdsWaitingP != NULL)
- rio_dprint(RIO_DEBUG_CMD, ("Rup active - command waiting\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");
if ( UnixRupP->CmdPendingP != NULL )
- rio_dprint(RIO_DEBUG_CMD, ("Rup active - command pending\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");
if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
- rio_dprint(RIO_DEBUG_CMD, ("Rup active - command rup not ready\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");
Base = &UnixRupP->CmdsWaitingP;
- rio_dprint(RIO_DEBUG_CMD, ("First try to queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base));
+ rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);
while ( *Base ) {
- rio_dprint(RIO_DEBUG_CMD, ("Command cmdblk 0x%x here\n",(int)(*Base)));
+ rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));
Base = &((*Base)->NextP);
- rio_dprint(RIO_DEBUG_CMD, ("Now try to queue cmd cmdblk 0x%x at 0x%x\n",
- (int)CmdBlkP,(int)Base));
+ rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n",
+ (int)CmdBlkP,(int)Base);
}
- rio_dprint(RIO_DEBUG_CMD, ("Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base));
+ rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base);
*Base = CmdBlkP;
@@ -775,17 +761,15 @@ struct Host * HostP;
if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
int FreeMe;
- /* rio_dprint(RIO_DEBUG_CMD, ("RIORupCmd( %d, %d )\n", HostP-p->RIOHosts, Rup )); */
-
PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));
ShowPacket( DBG_CMD, PacketP );
switch ( RBYTE(PacketP->dest_port) ) {
case BOOT_RUP:
- rio_dprint(RIO_DEBUG_CMD, ("Incoming Boot %s packet '%x'\n",
+ rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n",
RBYTE(PacketP->len) & 0x80 ? "Command":"Data",
- RBYTE(PacketP->data[0]) ));
+ RBYTE(PacketP->data[0]));
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
@@ -800,8 +784,8 @@ struct Host * HostP;
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
if (PacketP->data[5] == MEMDUMP) {
- rio_dprint(RIO_DEBUG_CMD, ("Memdump from 0x%x complete\n",
- *(ushort *) &(PacketP->data[6])));
+ rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
+ *(ushort *) &(PacketP->data[6]));
HostP->Copy( (caddr_t)&(PacketP->data[8]),
(caddr_t)p->RIOMemDump, 32 );
}
@@ -815,19 +799,19 @@ struct Host * HostP;
break;
default:
- rio_dprint(RIO_DEBUG_CMD, ("Unknown RUP %d\n", RBYTE(PacketP->dest_port)));
+ rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port));
FreeMe = 1;
break;
}
if ( FreeMe ) {
- rio_dprint(RIO_DEBUG_CMD, ("Free processed incoming command packet\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n");
put_free_end(HostP,PacketP);
WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);
if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
- rio_dprint(RIO_DEBUG_CMD, ("Handshake rup %d\n",Rup));
+ rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup);
WWORD(UnixRupP->RupP->handshake,
PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
}
@@ -839,7 +823,7 @@ struct Host * HostP;
** and it has completed, then tidy it up.
*/
if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
- (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) ) {
+ (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
/*
** we are idle.
** there is a command in pending.
@@ -848,11 +832,11 @@ struct Host * HostP;
** what happened).
*/
if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
- rio_dprint(RIO_DEBUG_CMD, ("Free Boot %s Command Block '%x'\n",
+ rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n",
CmdBlkP->Packet.len & 0x80 ? "Command":"Data",
- CmdBlkP->Packet.data[0] ));
+ CmdBlkP->Packet.data[0]);
- rio_dprint(RIO_DEBUG_CMD, ("Command 0x%x completed\n",(int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP);
/*
** Clear the Rup lock to prevent mutual exclusion.
@@ -880,27 +864,27 @@ struct Host * HostP;
*/
if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
(UnixRupP->CmdPendingP == NULL) &&
- (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) ) {
+ (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
/*
** if the pre-function is non-zero, call it.
** If it returns RIO_FAIL then don't
** send this command yet!
*/
#ifdef CHECK
-CheckCmdBlkP( CmdBlkP );
+ CheckCmdBlkP (CmdBlkP);
#endif
if ( !(CmdBlkP->PreFuncP ?
(*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
- rio_dprint(RIO_DEBUG_CMD, ("Not ready to start command 0x%x\n",(int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP);
}
else {
- rio_dprint(RIO_DEBUG_CMD, ("Start new command 0x%x Cmd byte is 0x%x\n",
- (int)CmdBlkP, CmdBlkP->Packet.data[0]));
+ rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n",
+ (int)CmdBlkP, CmdBlkP->Packet.data[0]);
/*
** Whammy! blat that pack!
*/
#ifdef CHECK
-CheckPacketP( (PKT *)RIO_PTR(HostP->Caddr,UnixRupP->RupP->txpkt) );
+ CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
#endif
HostP->Copy( (caddr_t)&CmdBlkP->Packet,
RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));
@@ -1026,7 +1010,7 @@ struct CmdBlk *CmdBlkP;
** MAGIC! (Basically, handshake the RX buffer, so that
** the RTAs upstream can be re-enabled.)
*/
- rio_dprint(RIO_DEBUG_CMD, ("Util: Set RX handshake bit\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
}
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -1046,7 +1030,7 @@ struct CmdBlk *CmdBlkP;
#ifdef CHECK
CheckPortP( PortP );
#endif
- rio_dprint(RIO_DEBUG_CMD, ("Decrement in use count for port\n"));
+ rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n");
if (PortP->InUse) {
if ( --PortP->InUse != NOT_INUSE ) {
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index fa68646d5..af61dc997 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -137,7 +137,7 @@ int copyin (int arg, caddr_t dp, int siz)
{
int rv;
- rio_dprint (RIO_DEBUG_CTRL, ("Copying %d bytes from user %p to %p.\n", siz, (void *) arg, dp));
+ rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes from user %p to %p.\n", siz, (void *)arg, dp);
rv = copy_from_user (dp, (void *)arg, siz);
if (rv < 0) return COPYFAIL;
else return rv;
@@ -148,7 +148,7 @@ int copyout (caddr_t dp, int arg, int siz)
{
int rv;
- rio_dprint (RIO_DEBUG_CTRL, ("Copying %d bytes to user %p from %p.\n", siz, (void *) arg, dp));
+ rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes to user %p from %p.\n", siz, (void *)arg, dp);
rv = copy_to_user ((void *)arg, dp, siz);
if (rv < 0) return COPYFAIL;
else return rv;
@@ -207,7 +207,7 @@ int su;
Host=0;
PortP = NULL;
- rio_dprint(RIO_DEBUG_CTRL, ("control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg));
+ rio_dprintk (RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg);
switch (cmd) {
/*
@@ -218,7 +218,7 @@ int su;
** otherwise just the specified host card will be changed.
*/
case RIO_SET_TIMER:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_TIMER to %dms\n", (uint)arg));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_TIMER to %dms\n", (uint)arg);
{
int host, value;
host = (uint)arg >> 16;
@@ -296,42 +296,42 @@ int su;
*/
case RIO_FOAD_RTA:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_FOAD_RTA\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n");
return RIOCommandRta(p, (uint)arg, RIOFoadRta);
case RIO_ZOMBIE_RTA:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_ZOMBIE_RTA\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n");
return RIOCommandRta(p, (uint)arg, RIOZombieRta);
case RIO_IDENTIFY_RTA:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_IDENTIFY_RTA\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n");
return RIOIdentifyRta(p, arg);
case RIO_KILL_NEIGHBOUR:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_KILL_NEIGHBOUR\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n");
return RIOKillNeighbour(p, arg);
case SPECIAL_RUP_CMD:
{
struct CmdBlk *CmdBlkP;
- rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n");
if (copyin((int)arg, (caddr_t)&SpecialRupCmd,
sizeof(SpecialRupCmd)) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
CmdBlkP = RIOGetCmdBlk();
if ( !CmdBlkP ) {
- rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD GetCmdBlk failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n");
return ENXIO;
}
CmdBlkP->Packet = SpecialRupCmd.Packet;
if ( SpecialRupCmd.Host >= p->RIONumHosts )
SpecialRupCmd.Host = 0;
- rio_dprint(RIO_DEBUG_CTRL, ("Queue special rup command for host %d rup %d\n",
- SpecialRupCmd.Host, SpecialRupCmd.RupNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n",
+ SpecialRupCmd.Host, SpecialRupCmd.RupNum);
if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host],
SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) {
cprintf("FAILED TO QUEUE SPECIAL RUP COMMAND\n");
@@ -348,7 +348,7 @@ RIO_DEBUG_CTRL, if (su)
return EPERM;
case RIO_ALL_MODEM:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_ALL_MODEM\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n");
p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
return EINVAL;
@@ -356,44 +356,44 @@ RIO_DEBUG_CTRL, if (su)
/*
** Read the routing table from the device driver to user space
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_TABLE\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE\n");
if ((retval = RIOApel(p)) != 0)
return retval;
if (copyout((caddr_t)p->RIOConnectTable, (int)arg,
TOTAL_MAP_ENTRIES*sizeof(struct Map)) == COPYFAIL) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_TABLE copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
{
int entry;
- rio_dprint(RIO_DEBUG_CTRL, ("*****\nMAP ENTRIES\n") );
+ rio_dprintk (RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n");
for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
{
if ((p->RIOConnectTable[entry].ID == 0) &&
(p->RIOConnectTable[entry].HostUniqueNum == 0) &&
(p->RIOConnectTable[entry].RtaUniqueNum == 0)) continue;
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) );
- rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link );
+ rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name );
}
- rio_dprint(RIO_DEBUG_CTRL, ("*****\nEND MAP ENTRIES\n") );
+ rio_dprintk (RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n");
}
p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */
return 0;
@@ -402,16 +402,16 @@ RIO_DEBUG_CTRL, if (su)
/*
** Write the routing table to the device driver from user space
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n");
if ( !su ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE !Root\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
if ( copyin((int)arg, (caddr_t)&p->RIOConnectTable[0],
TOTAL_MAP_ENTRIES*sizeof(struct Map) ) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
@@ -449,17 +449,17 @@ RIO_DEBUG_CTRL, if (su)
** Send bindings table, containing unique numbers of RTAs owned
** by this system to user space
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n");
if ( !su )
{
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS !Root\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
if (copyout((caddr_t) p->RIOBindTab, (int)arg,
(sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -470,17 +470,17 @@ RIO_DEBUG_CTRL, if (su)
** Receive a bindings table, containing unique numbers of RTAs owned
** by this system
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n");
if ( !su )
{
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS !Root\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
if (copyin((int)arg, (caddr_t)&p->RIOBindTab[0],
(sizeof(ulong) * MAX_RTA_BINDINGS))==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
@@ -493,10 +493,10 @@ RIO_DEBUG_CTRL, if (su)
** Bind this RTA to host, so that it will be booted by
** host in 'boot owned RTAs' mode.
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_BIND_RTA\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA\n");
if ( !su ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_BIND_RTA !Root\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
@@ -508,8 +508,8 @@ RIO_DEBUG_CTRL, if (su)
** Already exists - delete
*/
p->RIOBindTab[Entry] = 0L;
- rio_dprint(RIO_DEBUG_CTRL, ("Removing Rta %x from p->RIOBindTab\n",
- (int) arg));
+ rio_dprintk (RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n",
+ (int) arg);
return 0;
}
}
@@ -518,90 +518,90 @@ RIO_DEBUG_CTRL, if (su)
*/
if (EmptySlot != -1) {
p->RIOBindTab[EmptySlot] = (int) arg;
- rio_dprint(RIO_DEBUG_CTRL, ("Adding Rta %x to p->RIOBindTab\n",
- (int) arg));
+ rio_dprintk (RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n",
+ (int) arg);
}
else {
- rio_dprint(RIO_DEBUG_CTRL, ("p->RIOBindTab full! - Rta %x not added\n",
- (int) arg));
+ rio_dprintk (RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n",
+ (int) arg);
return 1;
}
return 0;
}
case RIO_RESUME :
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME\n");
port = (uint) arg;
if ((port < 0) || (port > 511)) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Bad port number %d\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
PortP = p->RIOPortp[port];
if (!PortP->Mapped) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d not mapped\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port);
p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
return EINVAL;
}
if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d not open\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port);
return EINVAL;
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) ==
RIO_FAIL) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME failed\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return EBUSY;
}
else {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d resumed\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port);
PortP->State |= RIO_BUSY;
}
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return retval;
case RIO_ASSIGN_RTA:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_ASSIGN_RTA\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n");
if ( !su ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_ASSIGN_RTA !Root\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
== COPYFAIL) {
- rio_dprint(RIO_DEBUG_CTRL, ("Copy from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
return RIOAssignRta(p, &MapEnt);
case RIO_CHANGE_NAME:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_CHANGE_NAME\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n");
if ( !su ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_CHANGE_NAME !Root\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
== COPYFAIL) {
- rio_dprint(RIO_DEBUG_CTRL, ("Copy from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
return RIOChangeName(p, &MapEnt);
case RIO_DELETE_RTA:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_DELETE_RTA\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n");
if ( !su ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_DELETE_RTA !Root\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
== COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("Copy from data space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Copy from data space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
@@ -638,7 +638,7 @@ RIO_DEBUG_CTRL, if (su)
return 0;
case RIO_GET_LOG:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_LOG\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_LOG\n");
#ifdef LOGGING
RIOGetLog(arg);
return 0;
@@ -653,17 +653,17 @@ RIO_DEBUG_CTRL, if (su)
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Get module type for port %d\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "Get module type for port %d\n", port);
if ( port < 0 || port > 511 )
{
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_MODTYPE: Bad port number %d\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
PortP = (p->RIOPortp[port]);
if (!PortP->Mapped)
{
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_MODTYPE: Port %d not mapped\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port);
p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
return EINVAL;
}
@@ -703,7 +703,7 @@ RIO_DEBUG_CTRL, if (su)
*/
case RIO_BLOCK_OPENS:
- rio_dprint(RIO_DEBUG_CTRL, ("Opens block until booted\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Opens block until booted\n");
for ( Entry=0; Entry < RIO_PORTS; Entry++ ) {
rio_spin_lock_irqsave(&PortP->portSem, flags);
p->RIOPortp[Entry]->WaitUntilBooted = 1;
@@ -712,33 +712,33 @@ RIO_DEBUG_CTRL, if (su)
return 0;
case RIO_SETUP_PORTS:
- rio_dprint(RIO_DEBUG_CTRL, ("Setup ports\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Setup ports\n");
if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup))
== COPYFAIL ) {
p->RIOError.Error = COPYIN_FAILED;
- rio_dprint(RIO_DEBUG_CTRL, ("EFAULT"));
+ rio_dprintk (RIO_DEBUG_CTRL, "EFAULT");
return EFAULT;
}
if ( PortSetup.From > PortSetup.To ||
PortSetup.To >= RIO_PORTS ) {
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
- rio_dprint(RIO_DEBUG_CTRL, ("ENXIO"));
+ rio_dprintk (RIO_DEBUG_CTRL, "ENXIO");
return ENXIO;
}
if ( PortSetup.XpCps > p->RIOConf.MaxXpCps ||
PortSetup.XpCps < p->RIOConf.MinXpCps ) {
p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;
- rio_dprint(RIO_DEBUG_CTRL, ("EINVAL"));
+ rio_dprintk (RIO_DEBUG_CTRL, "EINVAL");
return EINVAL;
}
if ( !p->RIOPortp ) {
cprintf("No p->RIOPortp array!\n");
- rio_dprint(RIO_DEBUG_CTRL, ("No p->RIOPortp array!\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "No p->RIOPortp array!\n");
return EIO;
}
- rio_dprint(RIO_DEBUG_CTRL, ("entering loop (%d %d)!\n", PortSetup.From, PortSetup.To));
+ rio_dprintk (RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To);
for (loop=PortSetup.From; loop<=PortSetup.To; loop++) {
- rio_dprint(RIO_DEBUG_CTRL, ("in loop (%d)!\n", loop));
+ rio_dprintk (RIO_DEBUG_CTRL, "in loop (%d)!\n", loop);
#if 0
PortP = p->RIOPortp[loop];
if ( !PortP->TtyP )
@@ -791,12 +791,12 @@ RIO_DEBUG_CTRL, if (su)
rio_spin_unlock_irqrestore( &PortP->portSem , flags);
#endif
}
- rio_dprint(RIO_DEBUG_CTRL, ("after loop (%d)!\n", loop));
- rio_dprint(RIO_DEBUG_CTRL, ("Retval:%x\n", retval ) );
+ rio_dprintk (RIO_DEBUG_CTRL, "after loop (%d)!\n", loop);
+ rio_dprintk (RIO_DEBUG_CTRL, "Retval:%x\n", retval);
return retval;
case RIO_GET_PORT_SETUP :
- rio_dprint(RIO_DEBUG_CTRL, ("Get port setup\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Get port setup\n");
if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup))
== COPYFAIL ) {
p->RIOError.Error = COPYIN_FAILED;
@@ -832,7 +832,7 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_GET_PORT_PARAMS :
- rio_dprint(RIO_DEBUG_CTRL, ("Get port params\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Get port params\n");
if (copyin( (int)arg, (caddr_t)&PortParams,
sizeof(struct PortParams)) == COPYFAIL) {
p->RIOError.Error = COPYIN_FAILED;
@@ -845,7 +845,7 @@ RIO_DEBUG_CTRL, if (su)
PortP = (p->RIOPortp[PortParams.Port]);
PortParams.Config = PortP->Config;
PortParams.State = PortP->State;
- rio_dprint(RIO_DEBUG_CTRL, ("Port %d\n", PortParams.Port));
+ rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
if (copyout((caddr_t)&PortParams, (int)arg,
sizeof(struct PortParams)) == COPYFAIL ) {
@@ -855,7 +855,7 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_GET_PORT_TTY :
- rio_dprint(RIO_DEBUG_CTRL, ("Get port tty\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Get port tty\n");
if (copyin((int)arg, (caddr_t)&PortTty, sizeof(struct PortTty))
== COPYFAIL) {
p->RIOError.Error = COPYIN_FAILED;
@@ -866,7 +866,7 @@ RIO_DEBUG_CTRL, if (su)
return ENXIO;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Port %d\n", PortTty.port));
+ rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
PortP = (p->RIOPortp[PortTty.port]);
#if 0
PortTty.Tty.tm.c_iflag = PortP->TtyP->tm.c_iflag;
@@ -887,7 +887,7 @@ RIO_DEBUG_CTRL, if (su)
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Set port %d tty\n", PortTty.port));
+ rio_dprintk (RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port);
if (PortTty.port >= (ushort) RIO_PORTS) {
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return ENXIO;
@@ -906,7 +906,7 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_SET_PORT_PARAMS :
- rio_dprint(RIO_DEBUG_CTRL, ("Set port params\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Set port params\n");
if ( copyin((int)arg, (caddr_t)&PortParams, sizeof(PortParams))
== COPYFAIL ) {
p->RIOError.Error = COPYIN_FAILED;
@@ -923,7 +923,7 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_GET_PORT_STATS :
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_PORT_STATS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
if ( copyin((int)arg, (caddr_t)&portStats,
sizeof(struct portStats)) == COPYFAIL ) {
p->RIOError.Error = COPYIN_FAILED;
@@ -949,7 +949,7 @@ RIO_DEBUG_CTRL, if (su)
case RIO_RESET_PORT_STATS :
port = (uint) arg;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESET_PORT_STATS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
if ( port >= RIO_PORTS ) {
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return ENXIO;
@@ -965,7 +965,7 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_GATHER_PORT_STATS :
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GATHER_PORT_STATS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
if ( copyin( (int)arg, (caddr_t)&portStats,
sizeof(struct portStats)) == COPYFAIL ) {
p->RIOError.Error = COPYIN_FAILED;
@@ -985,22 +985,22 @@ RIO_DEBUG_CTRL, if (su)
case RIO_READ_LEVELS:
{
int num;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_LEVELS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_LEVELS\n");
for ( num=0; RIODbInf[num].Flag; num++ ) ;
- rio_dprint(RIO_DEBUG_CTRL, ("%d levels to copy\n",num));
+ rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copy\n",num);
if (copyout((caddr_t)RIODbInf,(int)arg,
sizeof(struct DbInf)*(num+1))==COPYFAIL) {
- rio_dprint(RIO_DEBUG_CTRL, ("ReadLevels Copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "ReadLevels Copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
- rio_dprint(RIO_DEBUG_CTRL, ("%d levels to copied\n",num));
+ rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copied\n",num);
return retval;
}
#endif
case RIO_READ_CONFIG:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_CONFIG\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
if (copyout((caddr_t)&p->RIOConf, (int)arg,
sizeof(struct Conf)) ==COPYFAIL ) {
p->RIOError.Error = COPYOUT_FAILED;
@@ -1009,7 +1009,7 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_SET_CONFIG:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_CONFIG\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n");
if ( !su ) {
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
@@ -1029,11 +1029,11 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_START_POLLER:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_START_POLLER\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_START_POLLER\n");
return EINVAL;
case RIO_STOP_POLLER:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_STOP_POLLER\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n");
if ( !su ) {
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
@@ -1043,7 +1043,7 @@ RIO_DEBUG_CTRL, if (su)
case RIO_SETDEBUG:
case RIO_GETDEBUG:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SETDEBUG/RIO_GETDEBUG\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
if ( copyin( (int)arg, (caddr_t)&DebugCtrl, sizeof(DebugCtrl) )
==COPYFAIL ) {
p->RIOError.Error = COPYIN_FAILED;
@@ -1057,18 +1057,18 @@ RIO_DEBUG_CTRL, if (su)
}
p->rio_debug = DebugCtrl.Debug;
p->RIODebugWait = DebugCtrl.Wait;
- rio_dprint(RIO_DEBUG_CTRL, ("Set global debug to 0x%x set wait to 0x%x\n",
- p->rio_debug,p->RIODebugWait));
+ rio_dprintk (RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n",
+ p->rio_debug,p->RIODebugWait);
}
else {
- rio_dprint(RIO_DEBUG_CTRL, ("Get global debug 0x%x wait 0x%x\n",
- p->rio_debug,p->RIODebugWait));
+ rio_dprintk (RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n",
+ p->rio_debug,p->RIODebugWait);
DebugCtrl.Debug = p->rio_debug;
DebugCtrl.Wait = p->RIODebugWait;
if ( copyout((caddr_t)&DebugCtrl,(int)arg,
sizeof(DebugCtrl)) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET/GET DEBUG: bad port number %d\n",
- DebugCtrl.SysPort));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
+ DebugCtrl.SysPort);
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1076,8 +1076,8 @@ RIO_DEBUG_CTRL, if (su)
}
else if ( DebugCtrl.SysPort >= RIO_PORTS &&
DebugCtrl.SysPort != NO_PORT ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET/GET DEBUG: bad port number %d\n",
- DebugCtrl.SysPort));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
+ DebugCtrl.SysPort);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return ENXIO;
}
@@ -1089,16 +1089,16 @@ RIO_DEBUG_CTRL, if (su)
rio_spin_lock_irqsave(&PortP->portSem, flags);
p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug;
rio_spin_unlock_irqrestore( &PortP->portSem , flags);
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SETDEBUG 0x%x\n",
- p->RIOPortp[DebugCtrl.SysPort]->Debug));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n",
+ p->RIOPortp[DebugCtrl.SysPort]->Debug);
}
else {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GETDEBUG 0x%x\n",
- p->RIOPortp[DebugCtrl.SysPort]->Debug));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n",
+ p->RIOPortp[DebugCtrl.SysPort]->Debug);
DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
if ( copyout((caddr_t)&DebugCtrl,(int)arg,
sizeof(DebugCtrl))==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_GETDEBUG: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1111,12 +1111,12 @@ RIO_DEBUG_CTRL, if (su)
** We return MAX_VERSION_LEN bytes, being a
** textual null terminated string.
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID\n") );
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID\n");
if ( copyout( (caddr_t)RIOVersid(),
(int)arg,
sizeof(struct rioVersion) ) == COPYFAIL )
{
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID: Bad copy to user space (host=%d)\n",Host) );
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1150,10 +1150,10 @@ RIO_DEBUG_CTRL, if (su)
** Enquire as to the number of hosts located
** at init time.
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_NUM_HOSTS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
if (copyout((caddr_t)&p->RIONumHosts, (int)arg,
sizeof(p->RIONumHosts) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_NUM_HOSTS: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1163,9 +1163,9 @@ RIO_DEBUG_CTRL, if (su)
/*
** Kill host. This may not be in the final version...
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_FOAD %d\n", (int)arg));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD %d\n", (int)arg);
if ( !su ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_FOAD: Not super user\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
@@ -1213,27 +1213,27 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_DOWNLOAD:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n");
if ( !su ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Not super user\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n");
p->RIOError.Error = NOT_SUPER_USER;
return EPERM;
}
if ( copyin((int)arg, (caddr_t)&DownLoad,
sizeof(DownLoad) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Copy in from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Copied in download code for product code 0x%x\n",
- DownLoad.ProductCode ) );
+ rio_dprintk (RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n",
+ DownLoad.ProductCode);
/*
** It is important that the product code is an unsigned object!
*/
if ( DownLoad.ProductCode > MAX_PRODUCT ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Bad product code %d passed\n",
- DownLoad.ProductCode));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n",
+ DownLoad.ProductCode);
p->RIOError.Error = NO_SUCH_PRODUCT;
return ENXIO;
}
@@ -1254,63 +1254,63 @@ RIO_DEBUG_CTRL, if (su)
if (copyin((int)arg, (caddr_t)&host,
sizeof(host) ) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, (
- "RIO_HOST_REQ: Copy in from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL,
+ "RIO_HOST_REQ: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
/*
** Fetch the parmmap
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PARMS\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS\n");
if ( copyout( (caddr_t)p->RIOHosts[host].ParmMapP,
(int)arg, sizeof(PARM_MAP) )==COPYFAIL ) {
p->RIOError.Error = COPYOUT_FAILED;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_PARMS: Copy out to user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
return EFAULT;
}
}
return retval;
case RIO_HOST_REQ:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
if (copyin((int)arg, (caddr_t)&HostReq,
sizeof(HostReq) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Copy in from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
if ( HostReq.HostNum >= p->RIONumHosts ) {
p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Illegal host number %d\n",
- HostReq.HostNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n",
+ HostReq.HostNum);
return ENXIO;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Request for host %d\n", HostReq.HostNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum);
if (copyout((caddr_t)&p->RIOHosts[HostReq.HostNum],
(int)HostReq.HostP,sizeof(struct Host) ) == COPYFAIL) {
p->RIOError.Error = COPYOUT_FAILED;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n");
return EFAULT;
}
return retval;
case RIO_HOST_DPRAM:
- rio_dprint(RIO_DEBUG_CTRL, ("Request for DPRAM\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Request for DPRAM\n");
if ( copyin( (int)arg, (caddr_t)&HostDpRam,
sizeof(HostDpRam) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Copy in from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
if ( HostDpRam.HostNum >= p->RIONumHosts ) {
p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Illegal host number %d\n",
- HostDpRam.HostNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n",
+ HostDpRam.HostNum);
return ENXIO;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Request for host %d\n", HostDpRam.HostNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum);
if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) {
int off;
@@ -1321,7 +1321,7 @@ RIO_DEBUG_CTRL, if (su)
if ( copyout( (caddr_t)copy, (int)HostDpRam.DpRamP,
sizeof(struct DpRam) ) == COPYFAIL ) {
p->RIOError.Error = COPYOUT_FAILED;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
return EFAULT;
}
}
@@ -1329,15 +1329,15 @@ RIO_DEBUG_CTRL, if (su)
(int)HostDpRam.DpRamP,
sizeof(struct DpRam) ) == COPYFAIL ) {
p->RIOError.Error = COPYOUT_FAILED;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
return EFAULT;
}
return retval;
case RIO_SET_BUSY:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_BUSY\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
if ( (int)arg < 0 || (int)arg > 511 ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_BUSY: Bad port number %d\n",(int)arg));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %d\n",(int)arg);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
@@ -1351,26 +1351,26 @@ RIO_DEBUG_CTRL, if (su)
** The daemon want port information
** (probably for debug reasons)
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
if ( copyin((int)arg, (caddr_t)&PortReq,
sizeof(PortReq) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Copy in from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Illegal port number %d\n",
- PortReq.SysPort));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n",
+ PortReq.SysPort);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return ENXIO;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Request for port %d\n", PortReq.SysPort));
+ rio_dprintk (RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort);
if (copyout((caddr_t)p->RIOPortp[PortReq.SysPort],
(int)PortReq.PortP,
sizeof(struct Port) ) == COPYFAIL) {
p->RIOError.Error = COPYOUT_FAILED;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n");
return EFAULT;
}
return retval;
@@ -1380,40 +1380,40 @@ RIO_DEBUG_CTRL, if (su)
** The daemon want rup information
** (probably for debug reasons)
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
if (copyin((int)arg, (caddr_t)&RupReq,
sizeof(RupReq) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Copy in from user space failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Illegal host number %d\n",
- RupReq.HostNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n",
+ RupReq.HostNum);
p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
return ENXIO;
}
if ( RupReq.RupNum >= MAX_RUP+LINKS_PER_UNIT ) { /* eek! */
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Illegal rup number %d\n",
- RupReq.RupNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n",
+ RupReq.RupNum);
p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
HostP = &p->RIOHosts[RupReq.HostNum];
if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Host %d not running\n",
- RupReq.HostNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n",
+ RupReq.HostNum);
p->RIOError.Error = HOST_NOT_RUNNING;
return EIO;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Request for rup %d from host %d\n",
- RupReq.RupNum,RupReq.HostNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "Request for rup %d from host %d\n",
+ RupReq.RupNum,RupReq.HostNum);
if (copyout((caddr_t)HostP->UnixRups[RupReq.RupNum].RupP,
(int)RupReq.RupP,sizeof(struct RUP) ) == COPYFAIL) {
p->RIOError.Error = COPYOUT_FAILED;
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
return EFAULT;
}
return retval;
@@ -1423,39 +1423,39 @@ RIO_DEBUG_CTRL, if (su)
** The daemon want lpb information
** (probably for debug reasons)
*/
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
if (copyin((int)arg, (caddr_t)&LpbReq,
sizeof(LpbReq) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Bad copy from user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Illegal host number %d\n",
- LpbReq.Host));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n",
+ LpbReq.Host);
p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
return ENXIO;
}
if ( LpbReq.Link >= LINKS_PER_UNIT ) { /* eek! */
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Illegal link number %d\n",
- LpbReq.Link));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n",
+ LpbReq.Link);
p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
HostP = &p->RIOHosts[LpbReq.Host];
if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Host %d not running\n",
- LpbReq.Host));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n",
+ LpbReq.Host );
p->RIOError.Error = HOST_NOT_RUNNING;
return EIO;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Request for lpb %d from host %d\n",
- LpbReq.Link, LpbReq.Host));
+ rio_dprintk (RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n",
+ LpbReq.Link, LpbReq.Host);
if (copyout((caddr_t)&HostP->LinkStrP[LpbReq.Link],
(int)LpbReq.LpbP,sizeof(struct LPB) ) == COPYFAIL) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1494,7 +1494,7 @@ RIO_DEBUG_CTRL, if (su)
p->RIOError.Error = NOT_RECEIVING_PROCESS;
return EPERM;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Clear signal process to zero\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Clear signal process to zero\n");
p->RIOSignalProcess = 0;
return retval;
@@ -1526,10 +1526,10 @@ RIO_DEBUG_CTRL, if (su)
case RIO_MAP_B50_TO_57600:
case RIO_MAP_B110_TO_110:
case RIO_MAP_B110_TO_115200:
- rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping\n");
port = (uint) arg;
if ( port < 0 || port > 511 ) {
- rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping: Bad port number %d\n", port));
+ rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
@@ -1553,14 +1553,14 @@ RIO_DEBUG_CTRL, if (su)
return retval;
case RIO_STREAM_INFO:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_STREAM_INFO\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n");
return EINVAL;
case RIO_SEND_PACKET:
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SEND_PACKET\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
if ( copyin( (int)arg, (caddr_t)&SendPack,
sizeof(SendPack) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_SEND_PACKET: Bad copy from user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
@@ -1605,7 +1605,7 @@ RIO_DEBUG_CTRL, if (su)
case RIO_WHAT_MESG:
if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg,
sizeof(p->RIONoMessage) )==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_WHAT_MESG: Bad copy to user space\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1617,8 +1617,8 @@ RIO_DEBUG_CTRL, if (su)
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP host %d rup %d addr %x\n",
- SubCmd.Host, SubCmd.Rup, SubCmd.Addr));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n",
+ SubCmd.Host, SubCmd.Rup, SubCmd.Addr);
if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) {
p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
@@ -1638,7 +1638,7 @@ RIO_DEBUG_CTRL, if (su)
rio_spin_lock_irqsave(&PortP->portSem, flags);
if ( RIOPreemptiveCmd(p, PortP, MEMDUMP ) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n");
rio_spin_unlock_irqrestore( &PortP->portSem , flags);
return EBUSY;
}
@@ -1648,7 +1648,7 @@ RIO_DEBUG_CTRL, if (su)
rio_spin_unlock_irqrestore( &PortP->portSem , flags);
if ( copyout( (caddr_t)p->RIOMemDump, (int)arg,
MEMDUMP_SIZE) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1657,14 +1657,14 @@ RIO_DEBUG_CTRL, if (su)
case RIO_TICK:
if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
return EINVAL;
- rio_dprint(RIO_DEBUG_CTRL, ("Set interrupt for host %d\n", (int)arg ));
+ rio_dprintk (RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int)arg);
WBYTE(p->RIOHosts[(int)arg].SetInt , 0xff);
return 0;
case RIO_TOCK:
if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
return EINVAL;
- rio_dprint(RIO_DEBUG_CTRL, ("Clear interrupt for host %d\n", (int)arg ));
+ rio_dprintk (RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int)arg);
WBYTE((p->RIOHosts[(int)arg].ResetInt) , 0xff);
return 0;
@@ -1684,12 +1684,12 @@ RIO_DEBUG_CTRL, if (su)
p->RIOError.Error = COPYIN_FAILED;
return EFAULT;
}
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER host %d rup %d port %d reg %x\n",
- SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n",
+ SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr);
if (SubCmd.Port > 511) {
- rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping: Bad port number %d\n",
- SubCmd.Port));
+ rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n",
+ SubCmd.Port);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
@@ -1711,7 +1711,7 @@ RIO_DEBUG_CTRL, if (su)
rio_spin_lock_irqsave(&PortP->portSem, flags);
if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n");
rio_spin_unlock_irqrestore( &PortP->portSem , flags);
return EBUSY;
}
@@ -1721,7 +1721,7 @@ RIO_DEBUG_CTRL, if (su)
rio_spin_unlock_irqrestore( &PortP->portSem , flags);
if (copyout((caddr_t)&p->CdRegister, (int)arg,
sizeof(uint)) == COPYFAIL ) {
- rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER copy failed\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return EFAULT;
}
@@ -1738,18 +1738,18 @@ RIO_DEBUG_CTRL, if (su)
switch ( (uint)arg & RIO_DEV_MASK ) {
case RIO_DEV_DIRECT:
arg = (caddr_t)drv_makedev(major(dev), port);
- rio_dprint(RIO_DEBUG_CTRL, ("Makedev direct 0x%x is 0x%x\n",port, (int)arg ));
+ rio_dprintk (RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n",port, (int)arg);
return (int)arg;
case RIO_DEV_MODEM:
arg = (caddr_t)drv_makedev(major(dev), (port|RIO_MODEM_BIT) );
- rio_dprint(RIO_DEBUG_CTRL, ("Makedev modem 0x%x is 0x%x\n",port, (int)arg ));
+ rio_dprintk (RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n",port, (int)arg);
return (int)arg;
case RIO_DEV_XPRINT:
arg = (caddr_t)drv_makedev(major(dev), port);
- rio_dprint(RIO_DEBUG_CTRL, ("Makedev printer 0x%x is 0x%x\n",port, (int)arg ));
+ rio_dprintk (RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n",port, (int)arg);
return (int)arg;
}
- rio_dprint(RIO_DEBUG_CTRL, ("MAKE Device is called\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "MAKE Device is called\n");
return EINVAL;
}
/*
@@ -1766,17 +1766,17 @@ RIO_DEBUG_CTRL, if (su)
mino = RIO_UNMODEM(dv);
if ( RIO_ISMODEM(dv) ) {
- rio_dprint(RIO_DEBUG_CTRL, ("Minor for device 0x%x: modem %d\n", dv, mino));
+ rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino);
arg = (caddr_t)(mino | RIO_DEV_MODEM);
}
else {
- rio_dprint(RIO_DEBUG_CTRL, ("Minor for device 0x%x: direct %d\n", dv, mino));
+ rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino);
arg = (caddr_t)(mino | RIO_DEV_DIRECT);
}
return (int)arg;
}
}
- rio_dprint(RIO_DEBUG_CTRL, ("INVALID DAEMON IOCTL 0x%x\n",cmd));
+ rio_dprintk (RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n",cmd);
p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
func_exit ();
@@ -1803,18 +1803,18 @@ uchar Cmd;
#endif
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_CTRL, ("Preemptive command to deleted RTA ignored\n"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n");
return RIO_FAIL;
}
if (((int)((char)PortP->InUse) == -1) || ! (CmdBlkP = RIOGetCmdBlk()) ) {
- rio_dprint(RIO_DEBUG_CTRL, ("Cannot allocate command block for command %d on port %d\n",
- Cmd, PortP->PortNum));
+ rio_dprintk (RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n",
+ Cmd, PortP->PortNum);
return RIO_FAIL;
}
- rio_dprint(RIO_DEBUG_CTRL, ("Command blk 0x%x - InUse now %d\n",
- (int)CmdBlkP,PortP->InUse));
+ rio_dprintk (RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n",
+ (int)CmdBlkP,PortP->InUse);
PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0];
@@ -1840,40 +1840,40 @@ uchar Cmd;
switch ( Cmd ) {
case MEMDUMP:
- rio_dprint(RIO_DEBUG_CTRL, ("Queue MEMDUMP command blk 0x%x (addr 0x%x)\n",
- (int)CmdBlkP, (int)SubCmd.Addr));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n",
+ (int)CmdBlkP, (int)SubCmd.Addr);
PktCmdP->SubCommand = MEMDUMP;
PktCmdP->SubAddr = SubCmd.Addr;
break;
case FCLOSE:
- rio_dprint(RIO_DEBUG_CTRL, ("Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP);
break;
case READ_REGISTER:
- rio_dprint(RIO_DEBUG_CTRL, ("Queue READ_REGISTER (0x%x) command blk 0x%x\n",
- (int)SubCmd.Addr, (int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n",
+ (int)SubCmd.Addr, (int)CmdBlkP);
PktCmdP->SubCommand = READ_REGISTER;
PktCmdP->SubAddr = SubCmd.Addr;
break;
case RESUME:
- rio_dprint(RIO_DEBUG_CTRL, ("Queue RESUME command blk 0x%x\n",(int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n",(int)CmdBlkP);
break;
case RFLUSH:
- rio_dprint(RIO_DEBUG_CTRL, ("Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP);
CmdBlkP->PostFuncP = RIORFlushEnable;
break;
case SUSPEND:
- rio_dprint(RIO_DEBUG_CTRL, ("Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP);
break;
case MGET :
- rio_dprint(RIO_DEBUG_CTRL, ("Queue MGET command blk 0x%x\n", (int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int)CmdBlkP);
break;
case MSET :
case MBIC :
case MBIS :
CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
- rio_dprint(RIO_DEBUG_CTRL, ("Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP);
break;
case WFLUSH:
@@ -1883,12 +1883,12 @@ uchar Cmd;
** RTA.
*/
if ((int)((char)PortP->WflushFlag) == (int)-1) {
- rio_dprint(RIO_DEBUG_CTRL, ("Trashed WFLUSH, WflushFlag about to wrap!"));
+ rio_dprintk (RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!");
RIOFreeCmdBlk(CmdBlkP);
return(RIO_FAIL);
} else {
- rio_dprint(RIO_DEBUG_CTRL, ("Queue WFLUSH command blk 0x%x\n",
- (int)CmdBlkP));
+ rio_dprintk (RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n",
+ (int)CmdBlkP);
CmdBlkP->PostFuncP = RIOWFlushMark;
}
break;
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index 59cfdedd5..cbefdac2d 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -81,7 +81,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
#include "control.h"
#include "cirrus.h"
#include "rioioctl.h"
-
+#include "rio_linux.h"
#undef bcopy
#define bcopy rio_pcicopy
@@ -109,7 +109,7 @@ struct RioHostInfo * info;
*/
if ( !p->RIOPortp )
{
- rio_dprint(RIO_DEBUG_INIT, ("Allocating and setting up driver data structures\n") );
+ rio_dprintk (RIO_DEBUG_INIT, "Allocating and setting up driver data structures\n");
RIOAllocDataStructs(p); /* allocate host/port structs */
RIOSetupDataStructs(p); /* setup topology structs */
@@ -155,16 +155,16 @@ struct RioHostInfo * info;
if ( info->bus & ISA_BUS )
{
- rio_dprint(RIO_DEBUG_INIT, ("initialising card %d (ISA)\n", p->RIONumHosts) );
+ rio_dprintk (RIO_DEBUG_INIT, "initialising card %d (ISA)\n", p->RIONumHosts);
RIOISAinit(p, p->mode);
}
else
{
- rio_dprint(RIO_DEBUG_INIT, ("initialising card %d (PCI)\n", p->RIONumHosts) );
+ rio_dprintk (RIO_DEBUG_INIT, "initialising card %d (PCI)\n", p->RIONumHosts);
RIOPCIinit(p, RIO_PCI_DEFAULT_MODE);
}
- rio_dprint(RIO_DEBUG_INIT, ("Total hosts initialised so far : %d\n", p->RIONumHosts) );
+ rio_dprintk (RIO_DEBUG_INIT, "Total hosts initialised so far : %d\n", p->RIONumHosts);
#ifdef FUTURE_RELEASE
@@ -193,13 +193,13 @@ int mode;
p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
(int (*)())rio_intr, (char*)p->RIONumHosts);
- rio_dprint(RIO_DEBUG_INIT, ("Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid ) );
+ rio_dprintk (RIO_DEBUG_INIT, "Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid );
if (RIODoAT(p, p->RIOHosts[p->RIONumHosts].PaddrP, mode)) {
return;
}
else {
- rio_dprint(RIO_DEBUG_INIT, ("RIODoAT failed\n"));
+ rio_dprintk (RIO_DEBUG_INIT, "RIODoAT failed\n");
p->RIOFailed++;
}
#endif
@@ -268,7 +268,7 @@ int Base;
** map it in in one 64K block.
*/
if (RIOMapin(Base, RIO_AT_MEM_SIZE, &virtAddr) == -1) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Couldn't map the board in!\n"));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't map the board in!\n");
return((caddr_t)0);
}
@@ -285,8 +285,8 @@ int Base;
** Signature mismatch - card not at this address
*/
RIOMapout(Base, RIO_AT_MEM_SIZE, virtAddr);
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Couldn't match the signature 0x%x 0x%x!\n",
- (int)cardp, off));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't match the signature 0x%x 0x%x!\n",
+ (int)cardp, off);
return((caddr_t)0);
}
}
@@ -356,10 +356,10 @@ int mode;
((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)|
((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum);
p->RIONumHosts++;
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Tests Passed at 0x%x\n", Base));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base);
return(1);
}
#if 0
@@ -378,7 +378,7 @@ int RIOMCAinit(int Mode)
** is only FAST LINKS
*/
Mode = (Mode & FAST_LINKS) ? McaTpFastLinks : McaTpSlowLinks;
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOMCAinit(%d)\n",Mode);
+ rio_dprintk (RIO_DEBUG_INIT, "RIOMCAinit(%d)\n",Mode);
/*
@@ -395,7 +395,7 @@ int RIOMCAinit(int Mode)
*/
if (((inb(McaIdHigh)<< 8)|inb(McaIdLow)) == McaRIOId)
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Potential MCA card in slot %d\n",SlotNumber);
+ rio_dprintk (RIO_DEBUG_INIT, "Potential MCA card in slot %d\n", SlotNumber);
/*
** Card appears to be a RIO MCA card!
@@ -417,48 +417,44 @@ int RIOMCAinit(int Mode)
*/
Ivec = inb(McaIrqEnable);
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Ivec is %x\n",Ivec);
+ rio_dprintk (RIO_DEBUG_INIT, "Ivec is %x\n", Ivec);
switch ( Ivec & McaIrqMask )
{
case McaIrq9:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ9\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ9\n");
break;
case McaIrq3:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ3\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ3\n");
break;
case McaIrq4:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ4\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ4\n");
break;
case McaIrq7:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ7\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ7\n");
break;
case McaIrq10:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ10\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ10\n");
break;
case McaIrq11:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ11\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ11\n");
break;
case McaIrq12:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ12\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ12\n");
break;
case McaIrq15:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ15\n");
+ rio_dprintk (RIO_DEBUG_INIT, "IRQ15\n");
break;
}
/*
** If the card enable bit isn't set, then set it!
*/
- if ((Ivec & McaCardEnable) != McaCardEnable )
- {
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"McaCardEnable not set - setting!\n");
- outb(McaIrqEnable,Ivec|McaCardEnable);
- }
- else
- {
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"McaCardEnable already set\n");
- }
+ if ((Ivec & McaCardEnable) != McaCardEnable) {
+ rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable not set - setting!\n");
+ outb(McaIrqEnable,Ivec|McaCardEnable);
+ } else
+ rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable already set\n");
/*
** Convert the IRQ enable mask into something useful
@@ -468,10 +464,10 @@ int RIOMCAinit(int Mode)
/*
** Find the physical address
*/
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"inb(McaMemory) is %x\n",inb(McaMemory));
+ rio_dprintk (RIO_DEBUG_INIT, "inb(McaMemory) is %x\n", inb(McaMemory));
Paddr = McaAddress(inb(McaMemory));
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"MCA card has Ivec %d Addr %x\n",Ivec,Paddr);
+ rio_dprintk (RIO_DEBUG_INIT, "MCA card has Ivec %d Addr %x\n", Ivec, Paddr);
if ( Paddr != 0 )
{
@@ -482,21 +478,20 @@ int RIOMCAinit(int Mode)
Handle = RIOMapin( Paddr, RIO_MCA_MEM_SIZE, &Caddr );
if ( Handle == -1 ) {
- rio_dprint(RIO_DEBUG_INIT, ("Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE,Paddr);
+ rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE, Paddr;
continue;
}
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Board mapped to vaddr 0x%x\n",Caddr);
+ rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
/*
** And check that it is actually there!
*/
if ( RIOBoardTest( Paddr,Caddr,RIO_MCA,SlotNumber ) == RIO_SUCCESS )
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Board has passed test\n");
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,
- "Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
- SlotNumber,RIO_MCA,Paddr,Caddr,Mode);
+ rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
+ rio_dprintk (RIO_DEBUG_INIT, "Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
+ SlotNumber, RIO_MCA, Paddr, Caddr, Mode);
/*
** Board has passed its scrub test. Fill in all the
@@ -524,25 +519,25 @@ int RIOMCAinit(int Mode)
/*
** It failed the test, so ignore it.
*/
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"TEST FAILED\n");
+ rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
RIOMapout(Paddr, RIO_MCA_MEM_SIZE, Caddr );
}
}
else
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d - Paddr zero!\n",SlotNumber);
+ rio_dprintk (RIO_DEBUG_INIT, "Slot %d - Paddr zero!\n", SlotNumber);
}
}
else
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d NOT RIO\n",SlotNumber);
+ rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
}
}
/*
** Now we have checked all the slots, turn off the MCA slot selector
*/
outb(McaSlotSelect,0);
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d NOT RIO\n",SlotNumber);
+ rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
return ret;
}
@@ -565,13 +560,13 @@ int RIOEISAinit( int Mode )
if ( EISADone )
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOEISAinit() - already done, return.\n");
+ rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit() - already done, return.\n");
return(0);
}
EISADone++;
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOEISAinit()\n");
+ rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit()\n");
/*
@@ -584,23 +579,21 @@ int RIOEISAinit( int Mode )
Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) |
INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO);
- /* rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT, "Check EISA slot %d, ID=%x\n",EisaSlot,Ident); */
-
if ( Ident == RIO_EISA_IDENT )
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Found Specialix product\n");
+ rio_dprintk (RIO_DEBUG_INIT, "Found Specialix product\n");
if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE )
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Not Specialix RIO - Product number %x\n",
- INBZ(EisaSlot,EISA_PRODUCT_NUMBER));
+ rio_dprintk (RIO_DEBUG_INIT, "Not Specialix RIO - Product number %x\n",
+ INBZ(EisaSlot, EISA_PRODUCT_NUMBER));
continue; /* next slot */
}
/*
** Its a Specialix RIO!
*/
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIO Revision %d\n",
- INBZ(EisaSlot,EISA_REVISION_NUMBER));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO Revision %d\n",
+ INBZ(EisaSlot, EISA_REVISION_NUMBER));
RIOMachineType |= (1<<RIO_EISA);
@@ -627,43 +620,43 @@ int RIOEISAinit( int Mode )
switch ( Ivec & EISA_INTERRUPT_MASK )
{
case EISA_IRQ_3:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 3\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 3\n");
break;
case EISA_IRQ_4:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 4\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 4\n");
break;
case EISA_IRQ_5:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 5\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 5\n");
break;
case EISA_IRQ_6:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 6\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 6\n");
break;
case EISA_IRQ_7:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 7\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 7\n");
break;
case EISA_IRQ_9:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 9\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 9\n");
break;
case EISA_IRQ_10:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 10\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 10\n");
break;
case EISA_IRQ_11:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 11\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 11\n");
break;
case EISA_IRQ_12:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 12\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 12\n");
break;
case EISA_IRQ_14:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 14\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 14\n");
break;
case EISA_IRQ_15:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 15\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 15\n");
break;
case EISA_POLLED:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA POLLED\n");
+ rio_dprintk (RIO_DEBUG_INIT, "EISA POLLED\n");
break;
default:
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
+ rio_dprintk (RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
Ivec &= EISA_CONTROL_MASK;
}
#endif
@@ -741,7 +734,7 @@ int RIOEISAinit( int Mode )
*/
Ivec = RIOEisaToIvec(Ivec);
- rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
+ rio_dprintk (RIO_DEBUG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
EisaSlot, Ivec);
/*
@@ -750,11 +743,11 @@ int RIOEISAinit( int Mode )
Paddr = (INBZ(EisaSlot,EISA_MEMORY_BASE_HI)<<24) |
(INBZ(EisaSlot,EISA_MEMORY_BASE_LO)<<16);
- rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"EISA card has Ivec %d Addr %x\n",Ivec,Paddr);
+ rio_dprintk (RIO_DEBUG_INIT, "EISA card has Ivec %d Addr %x\n", Ivec, Paddr);
if ( Paddr == 0 )
{
- rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT | DBG_FAIL,
+ rio_dprintk (RIO_DEBUG_INIT,
"Board in slot %d configured for address zero!\n", EisaSlot);
continue;
}
@@ -762,23 +755,23 @@ int RIOEISAinit( int Mode )
/*
** Tell the memory mapper that we want to talk to it
*/
- rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"About to map EISA card \n");
+ rio_dprintk (RIO_DEBUG_INIT, "About to map EISA card \n");
if (RIOMapin( Paddr, RIO_EISA_MEM_SIZE, &Caddr) == -1) {
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"Couldn't map %d bytes at %x\n",
+ rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n",
RIO_EISA_MEM_SIZE,Paddr);
continue;
}
- rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"Board mapped to vaddr 0x%x\n",Caddr);
+ rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
/*
** And check that it is actually there!
*/
if ( RIOBoardTest( Paddr,Caddr,RIO_EISA,EisaSlot) == RIO_SUCCESS )
{
- rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"Board has passed test\n");
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,
+ rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
+ rio_dprintk (RIO_DEBUG_INIT,
"Slot %d. Ivec %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
EisaSlot,Ivec,RIO_EISA,Paddr,Caddr,Mode);
@@ -818,7 +811,7 @@ int RIOEISAinit( int Mode )
/*
** It failed the test, so ignore it.
*/
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"TEST FAILED\n");
+ rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
RIOMapout(Paddr, RIO_EISA_MEM_SIZE, Caddr );
}
@@ -917,7 +910,7 @@ int Mode;
int Handle; /* Handle to Virtual memory allocated for current PCI host */
- rio_dprint(RIO_DEBUG_INIT, ("Search for a RIO PCI card - start at slot %d\n", slot ) );
+ rio_dprintk (RIO_DEBUG_INIT, "Search for a RIO PCI card - start at slot %d\n", slot);
/*
** Initialise the search status
@@ -926,7 +919,7 @@ int Mode;
while ( (slot < MAX_PCI_SLOT) & (p->RIOLastPCISearch != RIO_SUCCESS) )
{
- rio_dprint(RIO_DEBUG_INIT, ("Currently testing slot %d\n", slot ) );
+ rio_dprintk (RIO_DEBUG_INIT, "Currently testing slot %d\n", slot);
if (read_config(0,slot,0) == RIO_PCI_JET_CARD) {
p->RIOHosts[p->RIONumHosts].Ivec = 0;
@@ -934,7 +927,7 @@ int Mode;
Paddr = Paddr - (Paddr & 0x1); /* Mask off the io bit */
if ( (Paddr == 0) || ((Paddr & 0xffff0000) == 0xffff0000) ) {
- rio_dprint(RIO_DEBUG_INIT, ("Goofed up slot\n") ); /* what! */
+ rio_dprintk (RIO_DEBUG_INIT, "Goofed up slot\n"); /* what! */
slot++;
continue;
}
@@ -942,11 +935,11 @@ int Mode;
p->RIOHosts[p->RIONumHosts].PaddrP = Paddr;
Ivec = (read_config(0,slot,0x3c) & 0xff);
- rio_dprint(RIO_DEBUG_INIT, ("PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec ) );
+ rio_dprintk (RIO_DEBUG_INIT, "PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec);
Handle = RIOMapin( Paddr, RIO_PCI_MEM_SIZE, &Caddr );
if (Handle == -1) {
- rio_dprint(RIO_DEBUG_INIT, ("Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr ) );
+ rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr);
slot++;
continue;
}
@@ -954,9 +947,8 @@ int Mode;
p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
(int (*)())rio_intr, (char *)p->RIONumHosts);
if (RIOBoardTest( Paddr, Caddr, RIO_PCI, 0 ) == RIO_SUCCESS) {
- rio_dprint(RIO_DEBUG_INIT, ("Board has passed test\n"));
- rio_dprint(RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr,
- Mode));
+ rio_dprintk (RIO_DEBUG_INIT, ("Board has passed test\n");
+ rio_dprintk (RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, Mode);
/*
** Board has passed its scrub test. Fill in all the
@@ -991,8 +983,8 @@ int Mode;
((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
- rio_dprint(RIO_DEBUG_INIT, ("Unique no 0x%x.\n",
- p->RIOHosts[p->RIONumHosts].UniqueNum ) );
+ rio_dprintk (RIO_DEBUG_INIT, "Unique no 0x%x.\n",
+ p->RIOHosts[p->RIONumHosts].UniqueNum);
p->RIOLastPCISearch = RIO_SUCCESS;
p->RIONumHosts++;
@@ -1002,8 +994,8 @@ int Mode;
}
if ( slot >= MAX_PCI_SLOT ) {
- rio_dprint(RIO_DEBUG_INIT, ("All %d PCI slots have tested for RIO cards !!!\n",
- MAX_PCI_SLOT ) );
+ rio_dprintk (RIO_DEBUG_INIT, "All %d PCI slots have tested for RIO cards !!!\n",
+ MAX_PCI_SLOT);
}
@@ -1025,7 +1017,7 @@ void riohalt( void )
int host;
for ( host=0; host<p->RIONumHosts; host++ )
{
- rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Stop host %d\n",host);
+ rio_dprintk (RIO_DEBUG_INIT, "Stop host %d\n", host);
(void)RIOBoardTest( p->RIOHosts[host].PaddrP, p->RIOHosts[host].Caddr, p->RIOHosts[host].Type,p->RIOHosts[host].Slot );
}
}
@@ -1058,8 +1050,8 @@ int slot;
int op, bank;
int nbanks;
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
- type,(int)DpRam,slot));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
+ type,(int)DpRam, slot);
RIOHostReset(type, DpRam, slot);
@@ -1071,7 +1063,7 @@ int slot;
** scratch - 1000h bytes
*/
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Setup ram/size arrays\n"));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n");
size[0] = DP_SRAM1_SIZE;
size[1] = DP_SRAM2_SIZE;
@@ -1087,12 +1079,12 @@ int slot;
if (nbanks == 3) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
- (int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
+ (int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]);
} else {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
(int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2], (int)ram[3],
- size[3]));
+ size[3]);
}
/*
@@ -1103,14 +1095,14 @@ int slot;
for (op=0; op<TEST_END; op++) {
for (bank=0; bank<nbanks; bank++) {
if (RIOScrub(op, (BYTE *)ram[bank], size[bank]) == RIO_FAIL) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: RIOScrub band %d, op %d failed\n",
- bank, op));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n",
+ bank, op);
return RIO_FAIL;
}
}
}
- rio_dprint(RIO_DEBUG_INIT, ("Test completed\n"));
+ rio_dprintk (RIO_DEBUG_INIT, "Test completed\n");
return RIO_SUCCESS;
}
@@ -1158,14 +1150,14 @@ int size;
if (op) {
for (off=0; off<size; off++) {
if (RBYTE(ram[off]) != oldbyte) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
return RIO_FAIL;
}
}
for (off=0; off<size; off+=2) {
if (*(ushort *)&ram[off] != oldword) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]));
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]);
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
return RIO_FAIL;
}
}
@@ -1180,12 +1172,12 @@ int size;
*/
for (off=0; off<size; off++) {
if (op && (RBYTE(ram[off]) != oldbyte)) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off,oldbyte,RBYTE(ram[off])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
return RIO_FAIL;
}
WBYTE(ram[off],invbyte);
if (RBYTE(ram[off]) != invbyte) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n",off,invbyte,RBYTE(ram[off])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, RBYTE(ram[off]));
return RIO_FAIL;
}
}
@@ -1199,15 +1191,15 @@ int size;
*/
for (off=0; off<size; off+=2) {
if (*(ushort *)&ram[off] != invword) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,invword,*(ushort *)&ram[off]));
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, *(ushort *)&ram[off]);
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
return RIO_FAIL;
}
*(ushort *)&ram[off] = newword;
if ( *(ushort *)&ram[off] != newword ) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n",off,newword,*(ushort *)&ram[off]));
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
return RIO_FAIL;
}
}
@@ -1219,15 +1211,15 @@ int size;
*/
for (off=0; off<size; off++) {
if (RBYTE(ram[off]) != newbyte) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n",off,newbyte,RBYTE(ram[off])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
return RIO_FAIL;
}
}
for (off=0; off<size; off+=2) {
if ( *(ushort *)&ram[off] != newword ) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n",off,newword,*(ushort *)&ram[off]));
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
return RIO_FAIL;
}
}
@@ -1244,8 +1236,8 @@ int size;
for ( off=0; off<size; off+=2 ) {
if (*(ushort *)&ram[off] != swapword) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n",off,swapword,*((ushort *)&ram[off])));
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, *((ushort *)&ram[off]));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
return RIO_FAIL;
}
*((ushort *)&ram[off]) = ~swapword;
@@ -1253,11 +1245,11 @@ int size;
for (off=0; off<size; off+=2) {
if (RBYTE(ram[off]) != newbyte) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off,newbyte,RBYTE(ram[off])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
return RIO_FAIL;
}
if (RBYTE(ram[off+1]) != invbyte) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off+1,invbyte,RBYTE(ram[off+1])));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, RBYTE(ram[off+1]));
return RIO_FAIL;
}
*((ushort *)&ram[off]) = newword;
@@ -1384,14 +1376,14 @@ struct rio_info * p;
p->RIOPortp = (struct Port *)sysbrk(RIO_PORTS * sizeof(struct Port));
if (!p->RIOPortp) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: No memory for port structures\n"));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for port structures\n");
p->RIOFailed++;
return;
}
bzero( p->RIOPortp, sizeof(struct Port) * RIO_PORTS );
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: allocated and cleared memory for port structs\n") );
- rio_dprint(RIO_DEBUG_INIT, ("First RIO port struct @0x%x, size=0x%x bytes\n",
- (int)p->RIOPortp, sizeof(struct Port) ) );
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: allocated and cleared memory for port structs\n");
+ rio_dprintk (RIO_DEBUG_INIT, "First RIO port struct @0x%x, size=0x%x bytes\n",
+ (int)p->RIOPortp, sizeof(struct Port));
for( port=0; port<RIO_PORTS; port++ ) {
p->RIOPortp[port].PortNum = port;
@@ -1404,14 +1396,14 @@ struct rio_info * p;
p->RIOHosts = (struct Host *)sysbrk(RIO_HOSTS * sizeof(struct Host));
if (!p->RIOHosts) {
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: No memory for host structures\n"));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for host structures\n");
p->RIOFailed++;
return;
}
bzero(p->RIOHosts, sizeof(struct Host)*RIO_HOSTS);
- rio_dprint(RIO_DEBUG_INIT, ("RIO-init: allocated and cleared memory for host structs\n"));
- rio_dprint(RIO_DEBUG_INIT, ("First RIO host struct @0x%x, size=0x%x bytes\n",
- (int)p->RIOHosts, sizeof(struct Host) ) );
+ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: allocated and cleared memory for host structs\n");
+ rio_dprintk (RIO_DEBUG_INIT, "First RIO host struct @0x%x, size=0x%x bytes\n",
+ (int)p->RIOHosts, sizeof(struct Host));
for( host=0; host<RIO_HOSTS; host++ ) {
spin_lock_init (&p->RIOHosts[host].HostLock);
@@ -1494,10 +1486,10 @@ struct rio_info * p;
char * RIORelID = RELEASE_ID;
int host;
- rio_dprint(RIO_DEBUG_INIT, ("RIO : Release: %s ID: %s\n", RIORelease, RIORelID));
+ rio_dprintk (RIO_DEBUG_INIT, "RIO : Release: %s ID: %s\n", RIORelease, RIORelID);
if ( p->RIONumHosts==0 ) {
- rio_dprint(RIO_DEBUG_INIT, ("\nNo Hosts configured\n"));
+ rio_dprintk (RIO_DEBUG_INIT, "\nNo Hosts configured\n");
return(0);
}
@@ -1505,7 +1497,7 @@ struct rio_info * p;
struct Host *HostP = &p->RIOHosts[host];
switch ( HostP->Type ) {
case RIO_AT:
- rio_dprint(RIO_DEBUG_INIT, ("AT BUS : found the card at 0x%x\n", HostP->PaddrP));
+ rio_dprintk (RIO_DEBUG_INIT, "AT BUS : found the card at 0x%x\n", HostP->PaddrP);
}
}
return 0;
@@ -1587,17 +1579,17 @@ uint Slot;
/*
** Reset the Tpu
*/
- rio_dprint(RIO_DEBUG_INIT, ("RIOHostReset: type 0x%x", Type ) );
+ rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type);
switch ( Type ) {
case RIO_AT:
- rio_dprint(RIO_DEBUG_INIT, (" (RIO_AT)\n"));
+ rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n");
WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
INTERRUPT_DISABLE | BYTE_OPERATION |
SLOW_LINKS | SLOW_AT_BUS);
WBYTE(DpRamP->DpResetTpu, 0xFF);
rio_udelay (3);
- rio_dprint(RIO_DEBUG_INIT, ("RIOHostReset: Don't know if it worked. Try reset again\n") );
+ rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n");
WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
INTERRUPT_DISABLE | BYTE_OPERATION |
SLOW_LINKS | SLOW_AT_BUS);
@@ -1630,7 +1622,7 @@ uint Slot;
break;
#endif
case RIO_PCI:
- rio_dprint(RIO_DEBUG_INIT, (" (RIO_PCI)\n") );
+ rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n");
DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM;
DpRamP->DpResetInt = 0xFF;
DpRamP->DpResetTpu = 0xFF;
@@ -1645,7 +1637,7 @@ uint Slot;
#endif
default:
- rio_dprint(RIO_DEBUG_INIT, (" (UNKNOWN)\n") );
+ rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n");
break;
}
return;
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index e92609839..f52124b78 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -190,8 +190,8 @@ char * en;
tty = PortP->gs.tty;
- rio_dprint (RIO_DEBUG_INTR, ("tx port %d: %d chars queued.\n",
- PortP->PortNum, PortP->gs.xmit_cnt));
+ rio_dprintk (RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n",
+ PortP->PortNum, PortP->gs.xmit_cnt);
if (!PortP->gs.xmit_cnt) return;
@@ -215,10 +215,10 @@ char * en;
{ int t;
t = (c > 10)?10:c;
- rio_dprint (RIO_DEBUG_INTR, ("tx port %d: copying %d chars: %s - %s\n",
- PortP->PortNum, c,
- firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail , t),
- firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t)));
+ rio_dprintk (RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n",
+ PortP->PortNum, c,
+ firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail , t),
+ firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t));
}
/* If for one reason or another, we can't copy more data,
we're done! */
@@ -244,14 +244,14 @@ char * en;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2*PKT_MAX_DATA_LEN)) {
- rio_dprint (RIO_DEBUG_INTR, ("Waking up.... ldisc:%d (%d/%d)....",
+ rio_dprintk (RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....",
(int)(PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)),
- PortP->gs.wakeup_chars, PortP->gs.xmit_cnt));
+ PortP->gs.wakeup_chars, PortP->gs.xmit_cnt);
if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
PortP->gs.tty->ldisc.write_wakeup)
(PortP->gs.tty->ldisc.write_wakeup)(PortP->gs.tty);
- rio_dprint (RIO_DEBUG_INTR, ("(%d/%d)\n",
- PortP->gs.wakeup_chars, PortP->gs.xmit_cnt));
+ rio_dprintk (RIO_DEBUG_INTR, "(%d/%d)\n",
+ PortP->gs.wakeup_chars, PortP->gs.xmit_cnt);
wake_up_interruptible(&PortP->gs.tty->write_wait);
}
@@ -273,7 +273,7 @@ struct rio_info * p;
for ( host=0; host<p->RIONumHosts; host++ ) {
struct Host *HostP = &p->RIOHosts[host];
- rio_dprint(RIO_DEBUG_INTR, ("riointr() doing host %d type %d\n", host, HostP->Type ) );
+ rio_dprintk (RIO_DEBUG_INTR, "riointr() doing host %d type %d\n", host, HostP->Type);
switch( HostP->Type ) {
case RIO_AT:
@@ -363,7 +363,7 @@ int From;
static int t =0;
rio_spin_unlock (&HostP->HostLock);
if ((t++ % 200) == 0)
- rio_dprint(RIO_DEBUG_INTR, ("Interrupt but host not running. flags=%x.\n", (int)HostP->Flags));
+ rio_dprintk (RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int)HostP->Flags);
return;
}
rio_spin_unlock (&HostP->HostLock);
@@ -372,7 +372,7 @@ int From;
WWORD( HostP->ParmMapP->rup_intr , 0 );
p->RIORupCount++;
RupIntr++;
- rio_dprint(RIO_DEBUG_INTR, ("RUP interrupt on host %d\n", HostP-p->RIOHosts ));
+ rio_dprintk (RIO_DEBUG_INTR, "rio: RUP interrupt on host %d\n", HostP-p->RIOHosts);
RIOPollHostCommands(p, HostP );
}
@@ -383,7 +383,7 @@ int From;
p->RIORxCount++;
RxIntr++;
- rio_dprint(RIO_DEBUG_INTR, ("RX interrupt on host %d\n", HostP-p->RIOHosts));
+ rio_dprintk (RIO_DEBUG_INTR, "rio: RX interrupt on host %d\n", HostP-p->RIOHosts);
/*
** Loop through every port. If the port is mapped into
** the system ( i.e. has /dev/ttyXXXX associated ) then it is
@@ -451,7 +451,7 @@ int From;
** MAGIC! ( Basically, handshake the RX buffer, so that
** the RTAs upstream can be re-enabled. )
*/
- rio_dprint(RIO_DEBUG_INTR, ("Set RX handshake bit\n" ));
+ rio_dprintk (RIO_DEBUG_INTR, "Set RX handshake bit\n");
WWORD( PortP->PhbP->handshake,
PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET );
}
@@ -466,7 +466,7 @@ int From;
p->RIOTxCount++;
TxIntr++;
- rio_dprint(RIO_DEBUG_INTR, ("TX interrupt on host %d\n", HostP-p->RIOHosts));
+ rio_dprintk (RIO_DEBUG_INTR, "rio: TX interrupt on host %d\n", HostP-p->RIOHosts);
/*
** Loop through every port.
@@ -504,7 +504,7 @@ int From;
continue;
}
- rio_dprint (RIO_DEBUG_INTR, ("Looking into port %d.\n", port));
+ rio_dprintk (RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
/*
** Lock the port before we begin working on it.
*/
@@ -515,7 +515,7 @@ int From;
** we need do none of this processing.
*/
if ( !can_add_transmit( &PacketP, PortP ) ) {
- rio_dprint (RIO_DEBUG_INTR, ("Can't add to port, so skipping.\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
rio_spin_unlock(&PortP->portSem);
continue;
}
@@ -527,7 +527,7 @@ int From;
ttyP = PortP->gs.tty;
/* If ttyP is NULL, the port is getting closed. Forget about it. */
if (!ttyP) {
- rio_dprint (RIO_DEBUG_INTR, ("no tty, so skipping.\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "no tty, so skipping.\n");
rio_spin_unlock(&PortP->portSem);
continue;
}
@@ -603,10 +603,10 @@ int From;
** with WFLUSH
*/
if ( PortP->WflushFlag ) {
- rio_dprint(RIO_DEBUG_INTR, ("Want to WFLUSH mark this port\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
if ( PortP->InUse )
- rio_dprint(RIO_DEBUG_INTR, ("FAILS - PORT IS IN USE\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
}
while ( PortP->WflushFlag &&
@@ -615,7 +615,7 @@ int From;
int p;
struct PktCmd *PktCmdP;
- rio_dprint(RIO_DEBUG_INTR, ("Add WFLUSH marker to data queue\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
/*
** make it look just like a WFLUSH command
*/
@@ -670,8 +670,8 @@ int From;
PortP->MagicFlags &= ~MAGIC_FLUSH;
}
- rio_dprint(RIO_DEBUG_INTR, ("Wflush count now stands at %d\n",
- PortP->WflushFlag));
+ rio_dprintk (RIO_DEBUG_INTR, "Wflush count now stands at %d\n",
+ PortP->WflushFlag);
}
if ( PortP->MagicFlags & MORE_OUTPUT_EYGOR ) {
if ( PortP->MagicFlags & MAGIC_FLUSH ) {
@@ -747,12 +747,12 @@ struct Port * PortP;
TtyP = PortP->gs.tty;
if (!TtyP) {
- rio_dprint (RIO_DEBUG_INTR, ("RIOReceive: tty is null. \n"));
+ rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
return;
}
if (PortP->State & RIO_THROTTLE_RX) {
- rio_dprint (RIO_DEBUG_INTR, ("RIOReceive: Throttled. Can't handle more input.\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
return;
}
@@ -786,18 +786,18 @@ struct Port * PortP;
** check that it is not a command!
*/
if ( PacketP->len & PKT_CMD_BIT ) {
- rio_dprint(RIO_DEBUG_INTR, ("RIO: unexpected command packet received on PHB\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
/* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
- rio_dprint(RIO_DEBUG_INTR, (" dest_unit = %d\n", PacketP->dest_unit));
- rio_dprint(RIO_DEBUG_INTR, (" dest_port = %d\n", PacketP->dest_port));
- rio_dprint(RIO_DEBUG_INTR, (" src_unit = %d\n", PacketP->src_unit));
- rio_dprint(RIO_DEBUG_INTR, (" src_port = %d\n", PacketP->src_port));
- rio_dprint(RIO_DEBUG_INTR, (" len = %d\n", PacketP->len));
- rio_dprint(RIO_DEBUG_INTR, (" control = %d\n", PacketP->control));
- rio_dprint(RIO_DEBUG_INTR, (" csum = %d\n", PacketP->csum));
- rio_dprint(RIO_DEBUG_INTR, (" data bytes: "));
+ rio_dprintk (RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit);
+ rio_dprintk (RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port);
+ rio_dprintk (RIO_DEBUG_INTR, " src_unit = %d\n", PacketP->src_unit);
+ rio_dprintk (RIO_DEBUG_INTR, " src_port = %d\n", PacketP->src_port);
+ rio_dprintk (RIO_DEBUG_INTR, " len = %d\n", PacketP->len);
+ rio_dprintk (RIO_DEBUG_INTR, " control = %d\n", PacketP->control);
+ rio_dprintk (RIO_DEBUG_INTR, " csum = %d\n", PacketP->csum);
+ rio_dprintk (RIO_DEBUG_INTR, " data bytes: ");
for ( DataCnt=0; DataCnt<PKT_MAX_DATA_LEN; DataCnt++ )
- rio_dprint(RIO_DEBUG_INTR, ("%d\n", PacketP->data[DataCnt]));
+ rio_dprintk (RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]);
remove_receive( PortP );
put_free_end( PortP->HostP, PacketP );
continue; /* with next packet */
@@ -820,8 +820,8 @@ struct Port * PortP;
transCount = min(PacketP->len & PKT_LEN_MASK,
TTY_FLIPBUF_SIZE - TtyP->flip.count);
- rio_dprint(RIO_DEBUG_REC, ("port %d: Copy %d bytes\n",
- PortP->PortNum, transCount ) );
+ rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n",
+ PortP->PortNum, transCount);
/*
** To use the following 'kkprintfs' for debugging - change the '#undef'
** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
@@ -880,7 +880,7 @@ struct Port * PortP;
}
}
if (copied) {
- rio_dprint ( RIO_DEBUG_REC, ("port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied));
+ rio_dprintk (RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
tty_flip_buffer_push (TtyP);
}
@@ -906,25 +906,25 @@ int port;
SysPort = port; /* Believe me, it works. */
if ( SysPort < 0 || SysPort >= RIO_PORTS ) {
- rio_dprint(RIO_DEBUG_INTR, ("Illegal port %d derived from TTY in riotproc()\n",SysPort));
+ rio_dprintk (RIO_DEBUG_INTR, "Illegal port %d derived from TTY in riotproc()\n",SysPort);
return 0;
}
PortP = p->RIOPortp[SysPort];
if ((uint)PortP->PhbP < (uint)PortP->Caddr ||
(uint)PortP->PhbP >= (uint)PortP->Caddr+SIXTY_FOUR_K ) {
- rio_dprint(RIO_DEBUG_INTR, ("RIO: NULL or BAD PhbP on sys port %d in proc routine\n",
- SysPort));
- rio_dprint(RIO_DEBUG_INTR, (" PortP = 0x%x\n",PortP));
- rio_dprint(RIO_DEBUG_INTR, (" PortP->PhbP = 0x%x\n",PortP->PhbP));
- rio_dprint(RIO_DEBUG_INTR, (" PortP->Caddr = 0x%x\n",PortP->PhbP));
- rio_dprint(RIO_DEBUG_INTR, (" PortP->HostPort = 0x%x\n",PortP->HostPort));
+ rio_dprintk (RIO_DEBUG_INTR, "RIO: NULL or BAD PhbP on sys port %d in proc routine\n",
+ SysPort);
+ rio_dprintk (RIO_DEBUG_INTR, " PortP = 0x%x\n",PortP);
+ rio_dprintk (RIO_DEBUG_INTR, " PortP->PhbP = 0x%x\n",PortP->PhbP);
+ rio_dprintk (RIO_DEBUG_INTR, " PortP->Caddr = 0x%x\n",PortP->PhbP);
+ rio_dprintk (RIO_DEBUG_INTR, " PortP->HostPort = 0x%x\n",PortP->HostPort);
return 0;
}
switch(cmd) {
case T_WFLUSH:
- rio_dprint(RIO_DEBUG_INTR, "T_WFLUSH\n");
+ rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH\n");
/*
** Because of the spooky way the RIO works, we don't need
** to issue a flush command on any of the SET*F commands,
@@ -941,14 +941,14 @@ int port;
** form a wflush packet - 1 byte long, no data
*/
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_INTR, ("WFLUSH on deleted RTA\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "WFLUSH on deleted RTA\n");
}
else {
if ( RIOPreemptiveCmd(p, PortP, WFLUSH ) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command failed\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command failed\n");
}
else
- rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command\n");
}
/*
** WFLUSH operation - flush the data!
@@ -956,7 +956,7 @@ int port;
PortP->TxBufferIn = PortP->TxBufferOut = 0;
}
else {
- rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command ignored\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command ignored\n");
}
/*
** sort out the line discipline
@@ -966,16 +966,16 @@ int port;
break;
case T_RESUME:
- rio_dprint(RIO_DEBUG_INTR, ("T_RESUME\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_RESUME\n");
/*
** send pre-emptive resume packet
*/
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_INTR, ("RESUME on deleted RTA\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "RESUME on deleted RTA\n");
}
else {
if ( RIOPreemptiveCmd(p, PortP, RESUME ) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_INTR, ("T_RESUME Command failed\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_RESUME Command failed\n");
}
}
/*
@@ -986,7 +986,7 @@ int port;
break;
case T_TIME:
- rio_dprint(RIO_DEBUG_INTR, ("T_TIME\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_TIME\n");
/*
** T_TIME is called when xDLY is set in oflags and
** the line discipline timeout has expired. It's
@@ -1008,16 +1008,16 @@ start:
break;
case T_SUSPEND:
- rio_dprint(RIO_DEBUG_INTR, ("T_SUSPEND\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND\n");
/*
** send a suspend pre-emptive packet.
*/
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_INTR, ("SUSPEND deleted RTA\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "SUSPEND deleted RTA\n");
}
else {
if ( RIOPreemptiveCmd(p, PortP, SUSPEND ) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_INTR, ("T_SUSPEND Command failed\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND Command failed\n");
}
}
/*
@@ -1026,18 +1026,18 @@ start:
break;
case T_BLOCK:
- rio_dprint(RIO_DEBUG_INTR, ("T_BLOCK\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_BLOCK\n");
break;
case T_RFLUSH:
- rio_dprint(RIO_DEBUG_INTR, ("T_RFLUSH\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH\n");
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_INTR, ("RFLUSH on deleted RTA\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "RFLUSH on deleted RTA\n");
PortP->RxDataStart = 0;
}
else {
if ( RIOPreemptiveCmd( p, PortP, RFLUSH ) == RIO_FAIL ) {
- rio_dprint(RIO_DEBUG_INTR, ("T_RFLUSH Command failed\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH Command failed\n");
return 0;
}
PortP->RxDataStart = 0;
@@ -1050,14 +1050,14 @@ start:
/*
** MAGIC!
*/
- rio_dprint(RIO_DEBUG_INTR, ("Set receive handshake bit\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "Set receive handshake bit\n");
PortP->PhbP->handshake |= PHB_HANDSHAKE_RESET;
}
}
break;
/* FALLTHROUGH */
case T_UNBLOCK:
- rio_dprint(RIO_DEBUG_INTR, ("T_UNBLOCK\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_UNBLOCK\n");
/*
** If there is any data to receive set a timeout to service it.
*/
@@ -1065,7 +1065,7 @@ start:
break;
case T_BREAK:
- rio_dprint(RIO_DEBUG_INTR, ("T_BREAK\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "T_BREAK\n");
/*
** Send a break command. For Sys V
** this is a timed break, so we
@@ -1075,12 +1075,12 @@ start:
** Build a BREAK command
*/
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_INTR, ("BREAK on deleted RTA\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "BREAK on deleted RTA\n");
}
else {
if (RIOShortCommand(PortP,SBREAK,2,
p->RIOConf.BreakInterval)==RIO_FAIL) {
- rio_dprint(RIO_DEBUG_INTR, ("SBREAK RIOShortCommand failed\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
}
}
@@ -1090,18 +1090,18 @@ start:
break;
case T_INPUT:
- rio_dprint(RIO_DEBUG_INTR, ("Proc T_INPUT called - I don't know what to do!\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "Proc T_INPUT called - I don't know what to do!\n");
break;
case T_PARM:
- rio_dprint(RIO_DEBUG_INTR, ("Proc T_PARM called - I don't know what to do!\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "Proc T_PARM called - I don't know what to do!\n");
break;
case T_SWTCH:
- rio_dprint(RIO_DEBUG_INTR, ("Proc T_SWTCH called - I don't know what to do!\n"));
+ rio_dprintk (RIO_DEBUG_INTR, "Proc T_SWTCH called - I don't know what to do!\n");
break;
default:
- rio_dprint(RIO_DEBUG_INTR, ("Proc UNKNOWN command %d\n",cmd));
+ rio_dprintk (RIO_DEBUG_INTR, "Proc UNKNOWN command %d\n",cmd);
}
/*
** T_OUTPUT returns without passing through this point!
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
index 550e2c17d..4ce8443c3 100644
--- a/drivers/char/rio/rioparam.c
+++ b/drivers/char/rio/rioparam.c
@@ -176,13 +176,18 @@ int SleepFlag;
int retries = 0xff;
unsigned long flags;
+ func_enter ();
+
TtyP = PortP->gs.tty;
- rio_dprint(RIO_DEBUG_PARAM, ("RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",
- PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP) );
+ rio_dprintk (RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",
+ PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);
if (!TtyP) {
- rio_dprint (RIO_DEBUG_PARAM, ("Can't call rioparam with null tty.\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n");
+
+ func_exit ();
+
return RIO_FAIL;
}
rio_spin_lock_irqsave(&PortP->portSem, flags );
@@ -205,7 +210,7 @@ int SleepFlag;
PortP->FirstOpen = 0;
}
else if (PortP->Store || PortP->Lock) {
- rio_dprint(RIO_DEBUG_PARAM, ("OPEN: Restoring stored/locked params\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "OPEN: Restoring stored/locked params\n");
TtyP->tm.c_iflag = PortP->StoredTty.iflag;
TtyP->tm.c_oflag = PortP->StoredTty.oflag;
TtyP->tm.c_cflag = PortP->StoredTty.cflag;
@@ -226,41 +231,49 @@ int SleepFlag;
break;
}
if ( PortP->InUse != NOT_INUSE ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Port IN_USE for pre-emptive command\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n");
}
if ( !res ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Port has no space on transmit queue\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Port has no space on transmit queue\n");
}
if ( SleepFlag != OK_TO_SLEEP ) {
rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+ func_exit();
+
return RIO_FAIL;
}
- rio_dprint(RIO_DEBUG_PARAM, ("wait for can_add_transmit\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit\n");
rio_spin_unlock_irqrestore( &PortP->portSem, flags);
retval = RIODelay(PortP, HUNDRED_MS);
rio_spin_lock_irqsave( &PortP->portSem, flags);
if (retval == RIO_FAIL) {
- rio_dprint(RIO_DEBUG_PARAM, ("wait for can_add_transmit broken by signal\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n");
rio_spin_unlock_irqrestore( &PortP->portSem, flags);
pseterr(EINTR);
+ func_exit();
+
return RIO_FAIL;
}
if ( PortP->State & RIO_DELETED ) {
rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+ func_exit ();
+
return RIO_SUCCESS;
}
}
if (!res) {
rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+ func_exit ();
+
return RIO_FAIL;
}
- rio_dprint(RIO_DEBUG_PARAM, ("can_add_transmit() returns %x\n",res));
- rio_dprint(RIO_DEBUG_PARAM, ("Packet is 0x%x\n",(int) PacketP));
+ rio_dprintk (RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n",res);
+ rio_dprintk (RIO_DEBUG_PARAM, "Packet is 0x%x\n",(int) PacketP);
phb_param_ptr = (struct phb_param *)PacketP->data;
@@ -270,7 +283,7 @@ int SleepFlag;
** COR 1
*/
if ( TtyP->tm.c_iflag & INPCK ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Parity checking on input enabled\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Parity checking on input enabled\n");
Cor1 |= COR1_INPCK;
}
#endif
@@ -278,53 +291,53 @@ int SleepFlag;
switch ( TtyP->termios->c_cflag & CSIZE ) {
case CS5:
{
- rio_dprint(RIO_DEBUG_PARAM, ("5 bit data\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "5 bit data\n");
Cor1 |= COR1_5BITS;
break;
}
case CS6:
{
- rio_dprint(RIO_DEBUG_PARAM, ("6 bit data\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "6 bit data\n");
Cor1 |= COR1_6BITS;
break;
}
case CS7:
{
- rio_dprint(RIO_DEBUG_PARAM, ("7 bit data\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "7 bit data\n");
Cor1 |= COR1_7BITS;
break;
}
case CS8:
{
- rio_dprint(RIO_DEBUG_PARAM, ("8 bit data\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "8 bit data\n");
Cor1 |= COR1_8BITS;
break;
}
}
if ( TtyP->termios->c_cflag & CSTOPB ) {
- rio_dprint(RIO_DEBUG_PARAM, ("2 stop bits\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "2 stop bits\n");
Cor1 |= COR1_2STOP;
}
else {
- rio_dprint(RIO_DEBUG_PARAM, ("1 stop bit\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "1 stop bit\n");
Cor1 |= COR1_1STOP;
}
if ( TtyP->termios->c_cflag & PARENB ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Enable parity\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable parity\n");
Cor1 |= COR1_NORMAL;
}
else {
- rio_dprint(RIO_DEBUG_PARAM, ("Disable parity\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Disable parity\n");
Cor1 |= COR1_NOP;
}
if ( TtyP->termios->c_cflag & PARODD ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Odd parity\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Odd parity\n");
Cor1 |= COR1_ODD;
}
else {
- rio_dprint(RIO_DEBUG_PARAM, ("Even parity\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Even parity\n");
Cor1 |= COR1_EVEN;
}
@@ -332,89 +345,89 @@ int SleepFlag;
** COR 2
*/
if ( TtyP->termios->c_iflag & IXON ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Enable start/stop output control\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop output control\n");
Cor2 |= COR2_IXON;
}
else {
if ( PortP->Config & RIO_IXON ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Force enable start/stop output control\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Force enable start/stop output control\n");
Cor2 |= COR2_IXON;
}
else
- rio_dprint(RIO_DEBUG_PARAM, ("IXON has been disabled.\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "IXON has been disabled.\n");
}
if (TtyP->termios->c_iflag & IXANY) {
if ( PortP->Config & RIO_IXANY ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Enable any key to restart output\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable any key to restart output\n");
Cor2 |= COR2_IXANY;
}
else
- rio_dprint(RIO_DEBUG_PARAM, ("IXANY has been disabled due to sanity reasons.\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");
}
if ( TtyP->termios->c_iflag & IXOFF ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Enable start/stop input control 2\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");
Cor2 |= COR2_IXOFF;
}
if ( TtyP->termios->c_cflag & HUPCL ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Hangup on last close\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Hangup on last close\n");
Cor2 |= COR2_HUPCL;
}
if ( C_CRTSCTS (TtyP)) {
- rio_dprint(RIO_DEBUG_PARAM, ("Rx hardware flow control enabled\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n");
Cor2 |= COR2_CTSFLOW;
Cor2 |= COR2_RTSFLOW;
} else {
- rio_dprint(RIO_DEBUG_PARAM, ("Rx hardware flow control disabled\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n");
Cor2 &= ~COR2_CTSFLOW;
Cor2 &= ~COR2_RTSFLOW;
}
if ( TtyP->termios->c_cflag & CLOCAL ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Local line\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Local line\n");
}
else {
- rio_dprint(RIO_DEBUG_PARAM, ("Possible Modem line\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Possible Modem line\n");
}
/*
** COR 4 (there is no COR 3)
*/
if ( TtyP->termios->c_iflag & IGNBRK ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Ignore break condition\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Ignore break condition\n");
Cor4 |= COR4_IGNBRK;
}
if ( !(TtyP->termios->c_iflag & BRKINT) ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Break generates NULL condition\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Break generates NULL condition\n");
Cor4 |= COR4_NBRKINT;
} else {
- rio_dprint(RIO_DEBUG_PARAM, ("Interrupt on break condition\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Interrupt on break condition\n");
}
if ( TtyP->termios->c_iflag & INLCR ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Map newline to carriage return on input\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage return on input\n");
Cor4 |= COR4_INLCR;
}
if ( TtyP->termios->c_iflag & IGNCR ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Ignore carriage return on input\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Ignore carriage return on input\n");
Cor4 |= COR4_IGNCR;
}
if ( TtyP->termios->c_iflag & ICRNL ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Map carriage return to newline on input\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on input\n");
Cor4 |= COR4_ICRNL;
}
if ( TtyP->termios->c_iflag & IGNPAR ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Ignore characters with parity errors\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Ignore characters with parity errors\n");
Cor4 |= COR4_IGNPAR;
}
if ( TtyP->termios->c_iflag & PARMRK ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Mark parity errors\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Mark parity errors\n");
Cor4 |= COR4_PARMRK;
}
@@ -444,24 +457,24 @@ int SleepFlag;
** Could set LNE here if you wanted LNext processing. SVR4 will use it.
*/
if ( TtyP->termios->c_iflag & ISTRIP ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Strip input characters\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Strip input characters\n");
if (! (PortP->State & RIO_TRIAD_MODE)) {
Cor5 |= COR5_ISTRIP;
}
}
if ( TtyP->termios->c_oflag & ONLCR ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Map newline to carriage-return, newline on output\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n");
if ( PortP->CookMode == COOK_MEDIUM )
Cor5 |= COR5_ONLCR;
}
if ( TtyP->termios->c_oflag & OCRNL ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Map carriage return to newline on output\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on output\n");
if ( PortP->CookMode == COOK_MEDIUM )
Cor5 |= COR5_OCRNL;
}
if ( ( TtyP->termios->c_oflag & TABDLY) == TAB3 ) {
- rio_dprint(RIO_DEBUG_PARAM, ("Tab delay 3 set\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Tab delay 3 set\n");
if ( PortP->CookMode == COOK_MEDIUM )
Cor5 |= COR5_TAB3;
}
@@ -481,8 +494,8 @@ int SleepFlag;
/*
** Baud rate bytes
*/
- rio_dprint(RIO_DEBUG_PARAM, ("Mapping of rx/tx baud %x (%x)\n",
- TtyP->termios->c_cflag, CBAUD));
+ rio_dprintk (RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n",
+ TtyP->termios->c_cflag, CBAUD);
switch (TtyP->termios->c_cflag & CBAUD) {
#define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break
@@ -494,77 +507,77 @@ int SleepFlag;
/* XXX MIssing conversion table. XXX */
/* (TtyP->termios->c_cflag & V_CBAUD); */
- rio_dprint(RIO_DEBUG_PARAM, ("tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud));
+ rio_dprintk (RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud);
/*
** Leftovers
*/
if ( TtyP->termios->c_cflag & CREAD )
- rio_dprint(RIO_DEBUG_PARAM, ("Enable receiver\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable receiver\n");
#ifdef RCV1EN
if ( TtyP->termios->c_cflag & RCV1EN )
- rio_dprint(RIO_DEBUG_PARAM, ("RCV1EN (?)\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "RCV1EN (?)\n");
#endif
#ifdef XMT1EN
if ( TtyP->termios->c_cflag & XMT1EN )
- rio_dprint(RIO_DEBUG_PARAM, ("XMT1EN (?)\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "XMT1EN (?)\n");
#endif
#if 0
if ( TtyP->termios->c_cflag & LOBLK )
- rio_dprint(RIO_DEBUG_PARAM, ("LOBLK - JCL output blocks when not current\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "LOBLK - JCL output blocks when not current\n");
#endif
if ( TtyP->termios->c_lflag & ISIG )
- rio_dprint(RIO_DEBUG_PARAM, ("Input character signal generating enabled\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Input character signal generating enabled\n");
if ( TtyP->termios->c_lflag & ICANON )
- rio_dprint(RIO_DEBUG_PARAM, ("Canonical input: erase and kill enabled\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n");
if ( TtyP->termios->c_lflag & XCASE )
- rio_dprint(RIO_DEBUG_PARAM, ("Canonical upper/lower presentation\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n");
if ( TtyP->termios->c_lflag & ECHO )
- rio_dprint(RIO_DEBUG_PARAM, ("Enable input echo\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable input echo\n");
if ( TtyP->termios->c_lflag & ECHOE )
- rio_dprint(RIO_DEBUG_PARAM, ("Enable echo erase\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable echo erase\n");
if ( TtyP->termios->c_lflag & ECHOK )
- rio_dprint(RIO_DEBUG_PARAM, ("Enable echo kill\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable echo kill\n");
if ( TtyP->termios->c_lflag & ECHONL )
- rio_dprint(RIO_DEBUG_PARAM, ("Enable echo newline\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable echo newline\n");
if ( TtyP->termios->c_lflag & NOFLSH )
- rio_dprint(RIO_DEBUG_PARAM, ("Disable flush after interrupt or quit\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n");
#ifdef TOSTOP
if ( TtyP->termios->c_lflag & TOSTOP )
- rio_dprint(RIO_DEBUG_PARAM, ("Send SIGTTOU for background output\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n");
#endif
#ifdef XCLUDE
if ( TtyP->termios->c_lflag & XCLUDE )
- rio_dprint(RIO_DEBUG_PARAM, ("Exclusive use of this line\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Exclusive use of this line\n");
#endif
if ( TtyP->termios->c_iflag & IUCLC )
- rio_dprint(RIO_DEBUG_PARAM, ("Map uppercase to lowercase on input\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n");
if ( TtyP->termios->c_oflag & OPOST )
- rio_dprint(RIO_DEBUG_PARAM, ("Enable output post-processing\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Enable output post-processing\n");
if ( TtyP->termios->c_oflag & OLCUC )
- rio_dprint(RIO_DEBUG_PARAM, ("Map lowercase to uppercase on output\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n");
if ( TtyP->termios->c_oflag & ONOCR )
- rio_dprint(RIO_DEBUG_PARAM, ("No carriage return output at column 0\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "No carriage return output at column 0\n");
if ( TtyP->termios->c_oflag & ONLRET )
- rio_dprint(RIO_DEBUG_PARAM, ("Newline performs carriage return function\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Newline performs carriage return function\n");
if ( TtyP->termios->c_oflag & OFILL )
- rio_dprint(RIO_DEBUG_PARAM, ("Use fill characters for delay\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Use fill characters for delay\n");
if ( TtyP->termios->c_oflag & OFDEL )
- rio_dprint(RIO_DEBUG_PARAM, ("Fill character is DEL\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Fill character is DEL\n");
if ( TtyP->termios->c_oflag & NLDLY )
- rio_dprint(RIO_DEBUG_PARAM, ("Newline delay set\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Newline delay set\n");
if ( TtyP->termios->c_oflag & CRDLY )
- rio_dprint(RIO_DEBUG_PARAM, ("Carriage return delay set\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Carriage return delay set\n");
if ( TtyP->termios->c_oflag & TABDLY )
- rio_dprint(RIO_DEBUG_PARAM, ("Tab delay set\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Tab delay set\n");
#if 0
if ( TtyP->termios->c_oflag & BSDLY )
- rio_dprint(RIO_DEBUG_PARAM, ("Back-space delay set\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Back-space delay set\n");
if ( TtyP->termios->c_oflag & VTDLY )
- rio_dprint(RIO_DEBUG_PARAM, ("Vertical tab delay set\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Vertical tab delay set\n");
if ( TtyP->termios->c_oflag & FFDLY )
- rio_dprint(RIO_DEBUG_PARAM, ("Form-feed delay set\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "Form-feed delay set\n");
#endif
/*
** These things are kind of useful in a later life!
@@ -573,6 +586,8 @@ int SleepFlag;
if ( PortP->State & RIO_DELETED ) {
rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+ func_exit ();
+
return RIO_FAIL;
}
@@ -610,10 +625,12 @@ int SleepFlag;
rio_spin_unlock_irqrestore( &PortP->portSem, flags);
- rio_dprint(RIO_DEBUG_PARAM, ("add_transmit returned.\n"));
+ rio_dprintk (RIO_DEBUG_PARAM, "add_transmit returned.\n");
/*
** job done.
*/
+ func_exit ();
+
return RIO_SUCCESS;
}
@@ -644,7 +661,7 @@ add_transmit(PortP)
struct Port *PortP;
{
if (RWORD(*PortP->TxAdd) & PKT_IN_USE) {
- rio_dprint (RIO_DEBUG_PARAM, ("add_transmit: Packet has been stolen!"));
+ rio_dprintk (RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!");
}
WWORD( *(ushort *)PortP->TxAdd, RWORD(*PortP->TxAdd) | PKT_IN_USE);
PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart :
@@ -672,7 +689,7 @@ PKT *PktP;
*
************************************************/
- rio_dprint(RIO_DEBUG_PFE, ("put_free_end(PktP=%x)\n",(int)PktP));
+ rio_dprintk (RIO_DEBUG_PFE, "put_free_end(PktP=%x)\n",(int)PktP);
if ((old_end=RWORD(HostP->ParmMapP->free_list_end)) != TPNULL) {
new_end = RIO_OFF(HostP->Caddr,PktP);
@@ -683,12 +700,13 @@ PKT *PktP;
WWORD(HostP->ParmMapP->free_list_end, new_end);
}
else { /* First packet on the free list this should never happen! */
- rio_dprint(RIO_DEBUG_PFE, ("put_free_end(): This should never happen\n"));
+ rio_dprintk (RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
WWORD(HostP->ParmMapP->free_list_end , RIO_OFF(HostP->Caddr,PktP));
tmp_pointer = (FREE_LIST *)PktP;
WWORD(tmp_pointer->prev , TPNULL);
WWORD(tmp_pointer->next , TPNULL);
}
+ rio_dprintk (RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock);
rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
}
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
index 2f13eb273..ab78ddf5d 100644
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -178,8 +178,8 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
if ( Lies )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("LIES! DAMN LIES! %d LIES!\n",Lies));
- rio_dprint(RIO_DEBUG_ROUTE, ("%d:%c %d:%c %d:%c %d:%c\n",
+ rio_dprintk (RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n",Lies);
+ rio_dprintk (RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n",
RBYTE(PktCmdP->RouteTopology[0].Unit),
'A'+RBYTE(PktCmdP->RouteTopology[0].Link),
RBYTE(PktCmdP->RouteTopology[1].Unit),
@@ -187,7 +187,7 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
RBYTE(PktCmdP->RouteTopology[2].Unit),
'A'+RBYTE(PktCmdP->RouteTopology[2].Link),
RBYTE(PktCmdP->RouteTopology[3].Unit),
- 'A'+RBYTE(PktCmdP->RouteTopology[3].Link)));
+ 'A'+RBYTE(PktCmdP->RouteTopology[3].Link));
return TRUE;
}
@@ -219,11 +219,11 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
NewUnit != ROUTE_NO_ID &&
NewUnit != ROUTE_INTERCONNECT )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("I have a link from %s %s to unit %d:%d - I don't like it.\n",
+ rio_dprintk (RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n",
MyType,
MyName,
NewUnit,
- NewLink));
+ NewLink);
}
else
{
@@ -248,8 +248,8 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
RIOConCon(p,HostP,ThisUnit,ThisLink,NewUnit,NewLink,CONNECT);
if ( NewUnit == ROUTE_NO_ID )
- rio_dprint(RIO_DEBUG_ROUTE, ("%s %s (%c) is connected to an unconfigured unit.\n",
- MyType,MyName,'A'+ThisLink));
+ rio_dprintk (RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n",
+ MyType,MyName,'A'+ThisLink);
if ( NewUnit == ROUTE_INTERCONNECT )
{
@@ -267,14 +267,14 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
if ( HostP->Topology[OldLink].Unit == ThisUnit &&
HostP->Topology[OldLink].Link == ThisLink )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A'));
+ rio_dprintk (RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A');
HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT;
HostP->Topology[OldLink].Link = NO_LINK;
}
else
{
- rio_dprint(RIO_DEBUG_ROUTE, ("HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n",
- OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'));
+ rio_dprintk (RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n",
+ OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
}
}
else if ( OldUnit <= MAX_RUP )
@@ -282,29 +282,29 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
if ( HostP->Mapping[OldUnit-1].Topology[OldLink].Unit == ThisUnit &&
HostP->Mapping[OldUnit-1].Topology[OldLink].Link == ThisLink )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("SETTING RTA %s (%c) TO DISCONNECTED!\n",
- HostP->Mapping[OldUnit-1].Name,OldLink+'A'));
+ rio_dprintk (RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n",
+ HostP->Mapping[OldUnit-1].Name,OldLink+'A');
HostP->Mapping[OldUnit-1].Topology[OldLink].Unit=ROUTE_DISCONNECT;
HostP->Mapping[OldUnit-1].Topology[OldLink].Link=NO_LINK;
}
else
{
- rio_dprint(RIO_DEBUG_ROUTE, ("RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n",
+ rio_dprintk (RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n",
HostP->Mapping[OldUnit-1].Name,OldLink+'A',
- HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'));
+ HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
}
}
if ( NewUnit == HOST_ID )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("MARKING HOST (%c) CONNECTED TO %s (%c)\n",
- NewLink+'A',MyName,ThisLink+'A'));
+ rio_dprintk (RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n",
+ NewLink+'A',MyName,ThisLink+'A');
HostP->Topology[NewLink].Unit = ThisUnit;
HostP->Topology[NewLink].Link = ThisLink;
}
else if ( NewUnit <= MAX_RUP )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("MARKING RTA %s (%c) CONNECTED TO %s (%c)\n",
- HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A'));
+ rio_dprintk (RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n",
+ HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A');
HostP->Mapping[NewUnit-1].Topology[NewLink].Unit=ThisUnit;
HostP->Mapping[NewUnit-1].Topology[NewLink].Link=ThisLink;
}
@@ -321,8 +321,8 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
*/
if ( RBYTE(PktCmdP->Command) != ROUTE_REQUEST )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Unknown command %d received on rup %d host %d ROUTE_RUP\n",
- RBYTE(PktCmdP->Command),Rup,(int)HostP));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %d ROUTE_RUP\n",
+ RBYTE(PktCmdP->Command),Rup,(int)HostP);
return TRUE;
}
@@ -336,7 +336,7 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
*/
RtaType = GetUnitType(RtaUniq);
- rio_dprint(RIO_DEBUG_ROUTE, ("Received a request for an ID for serial number %x\n", RtaUniq));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq);
Mod = RBYTE(PktCmdP->ModuleTypes);
Mod1 = LONYBLE(Mod);
@@ -347,14 +347,14 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
** with 8 port, set 2nd ident in Mod2 to the same as Mod1.
*/
Mod2 = Mod1;
- rio_dprint(RIO_DEBUG_ROUTE, ("Backplane type is %s (all ports)\n",
- p->RIOModuleTypes[Mod1].Name ));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n",
+ p->RIOModuleTypes[Mod1].Name);
}
else
{
Mod2 = HINYBLE(Mod);
- rio_dprint(RIO_DEBUG_ROUTE, ("Module types are %s (ports 0-3) and %s (ports 4-7)\n",
- p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name ));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n",
+ p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name);
}
if ( RtaUniq == 0xffffffff )
@@ -367,7 +367,7 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
*/
if ( !(CmdBlkP = RIOGetCmdBlk()) )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("No command blocks to route RTA! come back later.\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n");
return 0;
}
@@ -384,8 +384,8 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
if (! RIOBootOk(p, HostP, RtaUniq))
{
- rio_dprint(RIO_DEBUG_ROUTE, ("RTA %x tried to get an ID, but does not belong - FOAD it!\n",
- RtaUniq));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n",
+ RtaUniq);
PktReplyP->Command = ROUTE_FOAD;
HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
@@ -397,13 +397,13 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
*/
for ( ThisUnit=0; ThisUnit<MAX_RUP; ThisUnit++ )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Entry %d Flags=%s %s UniqueNum=0x%x\n",
+ rio_dprintk (RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n",
ThisUnit,
HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ?
"Slot-In-Use":"Not In Use",
HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ?
"Slot-Tentative":"Not Tentative",
- HostP->Mapping[ThisUnit].RtaUniqueNum ));
+ HostP->Mapping[ThisUnit].RtaUniqueNum);
/*
** We have an entry for it.
@@ -414,12 +414,12 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
if (RtaType == TYPE_RTA16)
{
ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1;
- rio_dprint(RIO_DEBUG_ROUTE, ("Found unit 0x%x at slots %d+%d\n",
- RtaUniq,ThisUnit,ThisUnit2));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n",
+ RtaUniq,ThisUnit,ThisUnit2);
}
else
- rio_dprint(RIO_DEBUG_ROUTE, ("Found unit 0x%x at slot %d\n",
- RtaUniq,ThisUnit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n",
+ RtaUniq,ThisUnit);
/*
** If we have no knowledge of booting it, then the host has
** been re-booted, and so we must kill the RTA, so that it
@@ -458,14 +458,14 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
*/
RIOFixPhbs(p, HostP, ThisUnit2);
PktReplyP->IDNum2 = ThisUnit2+1;
- rio_dprint(RIO_DEBUG_ROUTE, ("RTA '%s' has been allocated IDs %d+%d\n",
- HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n",
+ HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2);
}
else
{
PktReplyP->IDNum2 = ROUTE_NO_ID;
- rio_dprint(RIO_DEBUG_ROUTE, ("RTA '%s' has been allocated ID %d\n",
- HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n",
+ HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum);
}
HostP->Copy("RT_ALLOCAT",PktReplyP->CommandText,10);
@@ -489,7 +489,7 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort];
if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Re-opened this port\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
rio_spin_lock_irqsave(&PortP->portSem, flags);
PortP->MagicFlags |= MAGIC_REBOOT;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -502,7 +502,7 @@ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP
PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort];
if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Re-opened this port\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
rio_spin_lock_irqsave(&PortP->portSem, flags);
PortP->MagicFlags |= MAGIC_REBOOT;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -628,7 +628,7 @@ uint unit;
unsigned long flags;
int PortN = HostP->Mapping[unit].SysPort;
- rio_dprint(RIO_DEBUG_ROUTE, ("RIOFixPhbs unit %d sysport %d\n", unit, PortN));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN);
if (PortN != -1) {
ushort dest_unit = HostP->Mapping[unit].ID2;
@@ -656,7 +656,7 @@ uint unit;
** unset, so go no further.
*/
if (PortP->TxStart == 0) {
- rio_dprint(RIO_DEBUG_ROUTE, ("Tx pkts not set up yet\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");
break;
}
@@ -691,10 +691,10 @@ uint unit;
WBYTE(Pkt->dest_unit, dest_unit);
WBYTE(Pkt->dest_port, dest_port);
}
- rio_dprint(RIO_DEBUG_ROUTE, ("phb dest: Old %x:%x New %x:%x\n",
+ rio_dprintk (RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n",
RWORD(PortP->PhbP->destination) & 0xff,
(RWORD(PortP->PhbP->destination) >> 8) & 0xff,
- dest_unit, dest_port));
+ dest_unit, dest_port);
WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8));
WWORD(PortP->PhbP->link, link);
@@ -706,7 +706,7 @@ uint unit;
*/
if (link > 3) return;
if (((unit * 8) + 7) > RWORD(HostP->LinkStrP[link].last_port)) {
- rio_dprint(RIO_DEBUG_ROUTE, ("last port on host link %d: %d\n", link, (unit * 8) + 7));
+ rio_dprintk (RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7);
WWORD(HostP->LinkStrP[link].last_port, (unit * 8) + 7);
}
}
@@ -732,7 +732,7 @@ uint UnitId;
CheckUnitId( UnitId );
#endif
if ( RIOCheck( HostP, UnitId ) ) {
- rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated\n",UnitId));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId);
rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
return(0);
}
@@ -771,7 +771,7 @@ uint UnitId;
HostP->Mapping[UnitId].Flags |= BEEN_HERE;
if ( p->RIOPrintDisabled == DO_PRINT )
- rio_dprint(RIO_DEBUG_ROUTE, ("RIOMesgIsolated %s",HostP->Mapping[UnitId].Name));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name);
for ( link=0; link<LINKS_PER_UNIT; link++) {
unit = HostP->Mapping[UnitId].Topology[link].Unit;
@@ -795,7 +795,7 @@ uint UnitId;
CheckUnitId( UnitId );
#endif
/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */
- rio_dprint(RIO_DEBUG_ROUTE, ("RIOCheck : UnitID = %d\n",UnitId));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId);
if ( UnitId == HOST_ID ) {
/* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */
@@ -854,16 +854,16 @@ uint Uniq;
case RIO_MCA:
case RIO_EISA:
case RIO_PCI:
- rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: Host\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Host\n");
return(TYPE_HOST);
case RIO_RTA_16:
- rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: 16 port RTA\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n");
return(TYPE_RTA16);
case RIO_RTA:
- rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: 8 port RTA\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n");
return(TYPE_RTA8);
default :
- rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: Unrecognised\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n");
return(99);
}
}
@@ -876,7 +876,7 @@ struct rio_info * p;
return(0);
p->RIOQuickCheck = CHANGED;
if ( p->RIOSignalProcess ) {
- rio_dprint(RIO_DEBUG_ROUTE, ("Send SIG-HUP"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Send SIG-HUP");
/*
psignal( RIOSignalProcess, SIGHUP );
*/
@@ -951,10 +951,10 @@ int Change;
ToName = ToId ? HostP->Mapping[ToId-1].Name : HostP->Name;
ToType = ToId ? "RTA" : "HOST";
- rio_dprint(RIO_DEBUG_ROUTE, ("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
+ rio_dprintk (RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
FromType, FromName, 'A'+FromLink,
ToType, ToName, 'A'+ToLink,
- (Change==CONNECT) ? "established" : "disconnected"));
+ (Change==CONNECT) ? "established" : "disconnected");
cprintf("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
FromType, FromName, 'A'+FromLink,
ToType, ToName, 'A'+ToLink,
@@ -1000,7 +1000,7 @@ RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
int link;
- rio_dprint(RIO_DEBUG_ROUTE, ("RIOFreeDisconnect unit %d\n",unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit);
/*
** If the slot is tentative and does not belong to the
** second half of a 16 port RTA then scan to see if
@@ -1023,17 +1023,17 @@ RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
** made this slot tentative and not yet received a topology update.
** Lets check how long ago we made it tentative.
*/
- rio_dprint(RIO_DEBUG_ROUTE, ("Just about to check LBOLT on entry %d\n",unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit);
if (drv_getparm(LBOLT, (ulong_t *) &current_time))
- rio_dprint(RIO_DEBUG_ROUTE, ("drv_getparm(LBOLT,....) Failed.\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n");
elapse_time = current_time - TentTime[unit];
- rio_dprint(RIO_DEBUG_ROUTE, ("elapse %d = current %d - tent %d (%d usec)\n",
- elapse_time, current_time, TentTime[unit],drv_hztousec(elapse_time)));
+ rio_dprintk (RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n",
+ elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time));
if (drv_hztousec(elapse_time) < WAIT_TO_FINISH)
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Skipping slot %d, not timed out yet %d\n"
- ,unit,drv_hztousec(elapse_time)));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n",
+ unit, drv_hztousec(elapse_time));
return 1;
}
#endif
@@ -1046,7 +1046,7 @@ RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
{
int nOther = (HostP->Mapping[unit].ID2) -1;
- rio_dprint(RIO_DEBUG_ROUTE, ("RioFreedis second slot %d.\n",nOther));
+ rio_dprintk (RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther);
bzero((caddr_t)&HostP->Mapping[nOther], sizeof(struct Map));
}
RIORemoveFromSavedTable(p, &HostP->Mapping[unit]);
@@ -1082,19 +1082,19 @@ RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
*/
for (unit = 0; unit < MAX_RUP; unit++)
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Scanning unit %d\n",unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Scanning unit %d\n",unit);
/*
** If the flags are zero then the slot is empty.
*/
if (HostP->Mapping[unit].Flags == 0)
{
- rio_dprint(RIO_DEBUG_ROUTE, (" This slot is empty.\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, " This slot is empty.\n");
/*
** If we haven't allocated the first ID then do it now.
*/
if (*pID1 == MAX_RUP)
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Make tentative entry for first unit %d\n", unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit);
*pID1 = unit;
/*
@@ -1109,7 +1109,7 @@ RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
/*
** Allocate the second slot and return.
*/
- rio_dprint(RIO_DEBUG_ROUTE, ("Make tentative entry for second unit %d\n", unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit);
*pID2 = unit;
return 0;
}
@@ -1121,18 +1121,18 @@ RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
** need to start all over again looking for tentative slots
** that we can re-use.
*/
- rio_dprint(RIO_DEBUG_ROUTE, ("Starting to scan for tentative slots\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n");
for (unit = 0; unit < MAX_RUP; unit++)
{
if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) ||
(HostP->Mapping[unit].Flags == 0)) && !
(HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT ))
{
- rio_dprint(RIO_DEBUG_ROUTE, (" Slot %d looks promising.\n",unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, " Slot %d looks promising.\n",unit);
if(unit == *pID1)
{
- rio_dprint(RIO_DEBUG_ROUTE, (" No it isn't, its the 1st half\n"));
+ rio_dprintk (RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n");
continue;
}
@@ -1152,7 +1152,7 @@ RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
*/
if (*pID1 == MAX_RUP)
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Grab tentative entry for first unit %d\n", unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit);
*pID1 = unit;
/*
@@ -1172,8 +1172,8 @@ RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
/*
** Allocate the second slot and return.
*/
- rio_dprint(RIO_DEBUG_ROUTE, ("Grab tentative/empty entry for second unit %d\n",
- unit));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n",
+ unit);
*pID2 = unit;
/*
@@ -1190,7 +1190,7 @@ RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
if (*pID1 > *pID2)
{
- rio_dprint(RIO_DEBUG_ROUTE, ("Swapping IDS %d %d\n",*pID1,*pID2));
+ rio_dprintk (RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2);
tempID = *pID1;
*pID1 = *pID2;
*pID2 = tempID;
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
index 6329a6e18..2b82c25ad 100644
--- a/drivers/char/rio/riotable.c
+++ b/drivers/char/rio/riotable.c
@@ -120,7 +120,7 @@ struct rio_info * p;
** (9) That names aren't duplicated
** xx (10) That hosts that actually exist are mentioned in the table. xx
*/
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(1)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n");
if ( p->RIOSystemUp ) { /* (1) */
p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED;
return EBUSY;
@@ -133,7 +133,7 @@ struct rio_info * p;
for ( Entry=0; Entry<TOTAL_MAP_ENTRIES; Entry++ ) {
MapP = &p->RIOConnectTable[Entry];
if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) {
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(2)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n");
cptr = MapP->Name; /* (2) */
cptr[MAX_NAME_LEN-1]='\0';
if ( cptr[0]=='\0' ) {
@@ -161,19 +161,19 @@ struct rio_info * p;
continue;
}
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(3)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n");
if ( !MapP->RtaUniqueNum && !MapP->HostUniqueNum ) { /* (3) */
if ( MapP->ID || MapP->SysPort || MapP->Flags ) {
- rio_dprint(RIO_DEBUG_TABLE, ("%s pretending to be empty but isn't\n",MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n",MapP->Name);
p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL;
p->RIOError.Entry = Entry;
return ENXIO;
}
- rio_dprint(RIO_DEBUG_TABLE, ("!RIO: Daemon: test (3) passes\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n");
continue;
}
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(4)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n");
for ( Host=0; Host<p->RIONumHosts; Host++ ) { /* (4) */
if ( p->RIOHosts[Host].UniqueNum==MapP->HostUniqueNum ) {
HostP = &p->RIOHosts[Host];
@@ -187,8 +187,8 @@ struct rio_info * p;
}
if ( Host >= p->RIONumHosts ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has unknown host unique number 0x%x\n",
- MapP->Name,MapP->HostUniqueNum));
+ rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n",
+ MapP->Name, MapP->HostUniqueNum);
MapP->HostUniqueNum = 0;
/* MapP->RtaUniqueNum = 0; */
/* MapP->ID = 0; */
@@ -198,18 +198,18 @@ struct rio_info * p;
continue;
}
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(5)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n");
if ( MapP->RtaUniqueNum ) { /* (5) */
if ( !MapP->ID ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RIO: RTA %s has been allocated an ID of zero!\n",
- MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n",
+ MapP->Name);
p->RIOError.Error = ZERO_RTA_ID;
p->RIOError.Entry = Entry;
return ENXIO;
}
if ( MapP->ID > MAX_RUP ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RIO: RTA %s has been allocated an illegal ID %d\n",
- MapP->Name, MapP->ID));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an illegal ID %d\n",
+ MapP->Name, MapP->ID);
p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
p->RIOError.Entry = Entry;
return ENXIO;
@@ -218,8 +218,8 @@ struct rio_info * p;
if ( MapP->HostUniqueNum ==
p->RIOConnectTable[SubEnt].HostUniqueNum &&
MapP->ID == p->RIOConnectTable[SubEnt].ID ) {
- rio_dprint(RIO_DEBUG_TABLE, ("Dupl. ID number allocated to RTA %s and RTA %s\n",
- MapP->Name,p->RIOConnectTable[SubEnt].Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n",
+ MapP->Name, p->RIOConnectTable[SubEnt].Name);
p->RIOError.Error = DUPLICATED_RTA_ID;
p->RIOError.Entry = Entry;
p->RIOError.Other = SubEnt;
@@ -232,29 +232,29 @@ struct rio_info * p;
if ((MapP->RtaUniqueNum ==
p->RIOConnectTable[SubEnt].RtaUniqueNum)
&& (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) {
- rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has duplicate unique number\n",MapP->Name));
- rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has duplicate unique number\n",
- p->RIOConnectTable[SubEnt].Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",MapP->Name);
+ rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",
+ p->RIOConnectTable[SubEnt].Name);
p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER;
p->RIOError.Entry = Entry;
p->RIOError.Other = SubEnt;
return ENXIO;
}
}
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(7a)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n");
/* (7a) */
if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort % PORTS_PER_RTA)) {
- rio_dprint(RIO_DEBUG_TABLE, ("TTY Port number %d-RTA %s is not a multiple of %d!\n",
- (int)MapP->SysPort,MapP->Name,PORTS_PER_RTA));
+ rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n",
+ (int)MapP->SysPort,MapP->Name, PORTS_PER_RTA);
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
p->RIOError.Entry = Entry;
return ENXIO;
}
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(7b)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n");
/* (7b) */
if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort >= RIO_PORTS)) {
- rio_dprint(RIO_DEBUG_TABLE, ("TTY Port number %d for RTA %s is too big\n",
- (int)MapP->SysPort,MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n",
+ (int)MapP->SysPort, MapP->Name);
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
p->RIOError.Entry = Entry;
return ENXIO;
@@ -263,22 +263,22 @@ struct rio_info * p;
if ( p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT )
continue;
if ( p->RIOConnectTable[SubEnt].RtaUniqueNum ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(8)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n");
/* (8) */
if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort ==
p->RIOConnectTable[SubEnt].SysPort) ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RTA %s:same TTY port # as RTA %s (%d)\n",
+ rio_dprintk (RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n",
MapP->Name, p->RIOConnectTable[SubEnt].Name,
- (int)MapP->SysPort));
+ (int)MapP->SysPort);
p->RIOError.Error = TTY_NUMBER_IN_USE;
p->RIOError.Entry = Entry;
p->RIOError.Other = SubEnt;
return ENXIO;
}
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(9)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n");
if (RIOStrCmp(MapP->Name,
p->RIOConnectTable[SubEnt].Name)==0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */
- rio_dprint(RIO_DEBUG_TABLE, ("RTA name %s used twice\n",MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
p->RIOError.Error = NAME_USED_TWICE;
p->RIOError.Entry = Entry;
p->RIOError.Other = SubEnt;
@@ -288,17 +288,17 @@ struct rio_info * p;
}
}
else { /* (6) */
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(6)\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n");
if ( MapP->ID ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RIO:HOST %s has been allocated ID that isn't zero!\n",
- MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n",
+ MapP->Name);
p->RIOError.Error = HOST_ID_NOT_ZERO;
p->RIOError.Entry = Entry;
return ENXIO;
}
if ( MapP->SysPort != NO_PORT ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RIO: HOST %s has been allocated port numbers!\n",
- MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n",
+ MapP->Name);
p->RIOError.Error = HOST_SYSPORT_BAD;
p->RIOError.Entry = Entry;
return ENXIO;
@@ -326,7 +326,7 @@ struct rio_info * p;
** Copy in the new table entries
*/
for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) {
- rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: Copy table for Host entry %d\n", Entry));
+ rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry);
MapP = &p->RIOConnectTable[Entry];
/*
@@ -344,7 +344,7 @@ struct rio_info * p;
** If it is a host, then we only need to fill in the name field.
*/
if ( MapP->ID==0 ) {
- rio_dprint(RIO_DEBUG_TABLE, ("Host entry found. Name %s\n",MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name);
bcopy(MapP->Name,HostP->Name,MAX_NAME_LEN);
continue;
}
@@ -357,7 +357,7 @@ struct rio_info * p;
HostMapP = &HostP->Mapping[MapP->ID-1];
if (MapP->Flags & SLOT_IN_USE) {
- rio_dprint(RIO_DEBUG_TABLE, ("Rta entry found. Name %s\n",MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name);
/*
** structure assign, then sort out the bits we shouldn't have done
*/
@@ -370,7 +370,7 @@ struct rio_info * p;
RIOReMapPorts(p, HostP, HostMapP );
}
else {
- rio_dprint(RIO_DEBUG_TABLE, ("TENTATIVE Rta entry found. Name %s\n",MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name);
}
}
@@ -420,11 +420,11 @@ struct rio_info * p;
*/
if (Host1 != Host)
{
- rio_dprint(RIO_DEBUG_TABLE, ("Default name %s already used\n", p->RIOHosts[Host].Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name);
bcopy("HOST 1",p->RIOHosts[Host].Name,7);
p->RIOHosts[Host].Name[5] += Host1;
}
- rio_dprint(RIO_DEBUG_TABLE, ("Assigning default name %s\n", p->RIOHosts[Host].Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name);
}
return 0;
}
@@ -447,13 +447,13 @@ struct rio_info * p;
disable(oldspl); /* strange but true! */
- rio_dprint(RIO_DEBUG_TABLE, ("Generating a table to return to config.rio\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n");
bzero((caddr_t)&p->RIOConnectTable[0],
sizeof(struct Map) * TOTAL_MAP_ENTRIES );
for ( Host=0; Host<RIO_HOSTS; Host++ ) {
- rio_dprint(RIO_DEBUG_TABLE, ("Processing host %d\n", Host));
+ rio_dprintk (RIO_DEBUG_TABLE, "Processing host %d\n", Host);
HostP = &p->RIOHosts[Host];
MapP = &p->RIOConnectTable[Next++];
MapP->HostUniqueNum = HostP->UniqueNum;
@@ -501,8 +501,8 @@ struct Map *MapP;
int work_done = 0;
unsigned long flags;
- rio_dprint(RIO_DEBUG_TABLE, ("Delete entry on host %x, rta %x\n",
- MapP->HostUniqueNum,MapP->RtaUniqueNum));
+ rio_dprintk (RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n",
+ MapP->HostUniqueNum, MapP->RtaUniqueNum);
for ( host=0; host < p->RIONumHosts; host++ ) {
HostP = &p->RIOHosts[host];
@@ -517,15 +517,15 @@ struct Map *MapP;
for ( entry=0; entry<MAX_RUP; entry++ ) {
if ( MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum ) {
HostMapP = &HostP->Mapping[entry];
- rio_dprint(RIO_DEBUG_TABLE, ("Found entry offset %d on host %s\n",
- entry,HostP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n",
+ entry, HostP->Name);
/*
** Check all four links of the unit are disconnected
*/
for ( link=0; link< LINKS_PER_UNIT; link++ ) {
if ( HostMapP->Topology[link].Unit != ROUTE_DISCONNECT ) {
- rio_dprint(RIO_DEBUG_TABLE, ("Entry is in use and cannot be deleted!\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n");
p->RIOError.Error = UNIT_IS_IN_USE;
rio_spin_unlock_irqrestore( &HostP->HostLock, flags);
return EBUSY;
@@ -540,7 +540,7 @@ struct Map *MapP;
if ( SysPort != NO_PORT ) {
for (port=SysPort; port < SysPort+PORTS_PER_RTA; port++) {
PortP = p->RIOPortp[port];
- rio_dprint(RIO_DEBUG_TABLE, ("Unmap port\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Unmap port\n");
rio_spin_lock_irqsave( &PortP->portSem, flags );
@@ -548,7 +548,7 @@ struct Map *MapP;
if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) {
- rio_dprint(RIO_DEBUG_TABLE, ("Gob on port\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Gob on port\n");
PortP->TxBufferIn = PortP->TxBufferOut = 0;
/* What should I do
wakeup( &PortP->TxBufferIn );
@@ -585,25 +585,25 @@ struct Map *MapP;
*/
Pkt = (PKT *) RIO_PTR(HostP->Caddr,
RWORD(*TxPktP));
- rio_dprint(RIO_DEBUG_TABLE, (
+ rio_dprintk (RIO_DEBUG_TABLE,
"Tx packet (%x) destination: Old %x:%x New %x:%x\n",
*TxPktP, Pkt->dest_unit,
- Pkt->dest_port, dest_unit, dest_port));
+ Pkt->dest_port, dest_unit, dest_port);
WWORD(Pkt->dest_unit, dest_unit);
WWORD(Pkt->dest_port, dest_port);
}
- rio_dprint(RIO_DEBUG_TABLE, (
+ rio_dprintk (RIO_DEBUG_TABLE,
"Port %d phb destination: Old %x:%x New %x:%x\n",
port, PortP->PhbP->destination & 0xff,
(PortP->PhbP->destination >> 8) & 0xff,
- dest_unit, dest_port));
+ dest_unit, dest_port);
WWORD(PortP->PhbP->destination,
dest_unit + (dest_port << 8));
}
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
}
}
- rio_dprint(RIO_DEBUG_TABLE, ("Entry nulled.\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Entry nulled.\n");
bzero((char *)HostMapP,sizeof(struct Map));
work_done++;
}
@@ -625,7 +625,7 @@ struct Map *MapP;
if ( work_done )
return 0;
- rio_dprint(RIO_DEBUG_TABLE, ("Couldn't find entry to be deleted\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n");
p->RIOError.Error = COULDNT_FIND_ENTRY;
return ENXIO;
}
@@ -638,32 +638,32 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP )
int link;
- rio_dprint(RIO_DEBUG_TABLE, ("Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
+ rio_dprintk (RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
MapP->HostUniqueNum,MapP->RtaUniqueNum,
- MapP->ID, (int)MapP->SysPort ));
+ MapP->ID, (int)MapP->SysPort);
if ((MapP->ID != (ushort)-1) &&
((int)MapP->ID < (int)1 || (int)MapP->ID > MAX_RUP ))
{
- rio_dprint(RIO_DEBUG_TABLE, ("Bad ID in map entry!\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
if (MapP->RtaUniqueNum == 0)
{
- rio_dprint(RIO_DEBUG_TABLE, ("Rta Unique number zero!\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Rta Unique number zero!\n");
p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO;
return EINVAL;
}
if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA) )
{
- rio_dprint(RIO_DEBUG_TABLE, ("Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA));
+ rio_dprintk (RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA);
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS) )
{
- rio_dprint(RIO_DEBUG_TABLE, ("Port %d not valid!\n",(int)MapP->SysPort));
+ rio_dprintk (RIO_DEBUG_TABLE, "Port %d not valid!\n",(int)MapP->SysPort);
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
@@ -677,7 +677,7 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP )
{
if ( *sptr<' ' || *sptr>'~' )
{
- rio_dprint(RIO_DEBUG_TABLE, ("Name entry contains non-printing characters!\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
p->RIOError.Error = BAD_CHARACTER_IN_NAME;
return EINVAL;
}
@@ -702,8 +702,8 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP )
{
int nNewID;
- rio_dprint(RIO_DEBUG_TABLE, ("Attempting to get a new ID for rta \"%s\"\n",
- MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n",
+ MapP->Name);
/*
** The idea here is to allow RTA's to be assigned
** before they actually appear on the network.
@@ -721,7 +721,7 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP )
return EBUSY;
}
MapP->ID = (ushort)nNewID + 1;
- rio_dprint(RIO_DEBUG_TABLE, ("Allocated ID %d for this new RTA.\n",MapP->ID));
+ rio_dprintk (RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID);
HostMapP = &p->RIOHosts[host].Mapping[nNewID];
HostMapP->RtaUniqueNum = MapP->RtaUniqueNum;
HostMapP->HostUniqueNum = MapP->HostUniqueNum;
@@ -747,9 +747,9 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP )
HostMapP->Flags |= RTA16_SECOND_SLOT;
HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID;
p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID;
- rio_dprint(RIO_DEBUG_TABLE, ("Cross referenced id %d to ID %d.\n",
+ rio_dprintk (RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n",
MapP->ID,
- p->RIOHosts[host].Mapping[unit].ID));
+ p->RIOHosts[host].Mapping[unit].ID);
}
}
@@ -757,7 +757,7 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP )
if ( HostMapP->Flags & SLOT_IN_USE )
{
- rio_dprint(RIO_DEBUG_TABLE, ("Map table slot for ID %d is already in use.\n",MapP->ID));
+ rio_dprintk (RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID);
p->RIOError.Error = ID_ALREADY_IN_USE;
return EBUSY;
}
@@ -791,15 +791,15 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP )
p->RIOLastPortsBooted = HostMapP->SysPort;
}
if (MapP->Flags & RTA16_SECOND_SLOT)
- rio_dprint(RIO_DEBUG_TABLE, ("Second map of RTA %s added to configuration\n",
- p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n",
+ p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name);
else
- rio_dprint(RIO_DEBUG_TABLE, ("RTA %s added to configuration\n",MapP->Name));
+ rio_dprintk (RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name);
return 0;
}
}
p->RIOError.Error = UNKNOWN_HOST_NUMBER;
- rio_dprint(RIO_DEBUG_TABLE, ("Unknown host %x\n",MapP->HostUniqueNum));
+ rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
return ENXIO;
}
@@ -822,7 +822,7 @@ struct Map *HostMapP;
CheckHostMapP( HostMapP );
#endif
- rio_dprint(RIO_DEBUG_TABLE, ("Mapping sysport %d to id %d\n",(int)HostMapP->SysPort, HostMapP->ID));
+ rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int)HostMapP->SysPort, HostMapP->ID);
/*
** We need to tell the UnixRups which sysport the rup corresponds to
@@ -833,26 +833,26 @@ struct Map *HostMapP;
return(0);
RtaType = GetUnitType(HostMapP->RtaUniqueNum);
- rio_dprint(RIO_DEBUG_TABLE, ("Mapping sysport %d-%d\n",
- (int)HostMapP->SysPort,(int)HostMapP->SysPort+PORTS_PER_RTA-1));
+ rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n",
+ (int)HostMapP->SysPort, (int)HostMapP->SysPort+PORTS_PER_RTA-1);
/*
** now map each of its eight ports
*/
for ( SubEnt=0; SubEnt<PORTS_PER_RTA; SubEnt++) {
- rio_dprint (RIO_DEBUG_TABLE, ("subent = %d, HostMapP->SysPort = %d\n",
- SubEnt, (int) HostMapP->SysPort));
+ rio_dprintk (RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n",
+ SubEnt, (int)HostMapP->SysPort);
SysPort = HostMapP->SysPort+SubEnt; /* portnumber within system */
/* portnumber on host */
HostPort = (HostMapP->ID-1)*PORTS_PER_RTA+SubEnt;
- rio_dprint (RIO_DEBUG_TABLE, ("c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp));
+ rio_dprintk (RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp);
PortP = p->RIOPortp[SysPort];
#if 0
PortP->TtyP = &p->channel[SysPort];
#endif
- rio_dprint(RIO_DEBUG_TABLE, ("Map port\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Map port\n");
/*
** Point at all the real neat data structures
@@ -1008,12 +1008,12 @@ struct Map* MapP;
struct Map *HostMapP;
char *sptr;
- rio_dprint(RIO_DEBUG_TABLE, ("Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
+ rio_dprintk (RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
MapP->HostUniqueNum,MapP->RtaUniqueNum,
- MapP->ID, (int)MapP->SysPort ));
+ MapP->ID, (int)MapP->SysPort);
if ( MapP->ID > MAX_RUP ) {
- rio_dprint(RIO_DEBUG_TABLE, ("Bad ID in map entry!\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
return EINVAL;
}
@@ -1023,7 +1023,7 @@ struct Map* MapP;
while ( *sptr ) {
if ( *sptr<' ' || *sptr>'~' ) {
- rio_dprint(RIO_DEBUG_TABLE, ("Name entry contains non-printing characters!\n"));
+ rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
p->RIOError.Error = BAD_CHARACTER_IN_NAME;
return EINVAL;
}
@@ -1052,6 +1052,6 @@ struct Map* MapP;
}
}
p->RIOError.Error = UNKNOWN_HOST_NUMBER;
- rio_dprint(RIO_DEBUG_TABLE, ("Unknown host %x\n",MapP->HostUniqueNum));
+ rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
return ENXIO;
}
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index cda417f3f..c9134e3fc 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -164,15 +164,15 @@ riotopen(struct tty_struct * tty, struct file * filp)
Modem = rio_ismodem (tty->device);
if ( p->RIOFailed ) {
- rio_dprint(RIO_DEBUG_TTY, ("System initialisation failed\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "System initialisation failed\n");
pseterr(ENXIO);
func_exit ();
return -ENXIO;
}
- rio_dprint(RIO_DEBUG_TTY, ("port open SysPort %d (%s) (mapped:%d)\n",
+ rio_dprintk (RIO_DEBUG_TTY, "port open SysPort %d (%s) (mapped:%d)\n",
SysPort, Modem ? "Modem" : "tty",
- p->RIOPortp[SysPort]->Mapped ) );
+ p->RIOPortp[SysPort]->Mapped);
/*
** Validate that we have received a legitimate request.
@@ -181,7 +181,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
** has been mapped onto a host.
*/
if (SysPort >= RIO_PORTS) { /* out of range ? */
- rio_dprint(RIO_DEBUG_TTY, ("Illegal port number %d\n",SysPort));
+ rio_dprintk (RIO_DEBUG_TTY, "Illegal port number %d\n",SysPort);
pseterr(ENXIO);
func_exit();
return -ENXIO;
@@ -197,7 +197,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
** The system doesn't know which RTA this port
** corresponds to.
*/
- rio_dprint(RIO_DEBUG_TTY, ("port not mapped into system\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "port not mapped into system\n");
func_exit ();
pseterr(ENXIO);
return -ENXIO;
@@ -206,17 +206,26 @@ riotopen(struct tty_struct * tty, struct file * filp)
tty->driver_data = PortP;
PortP->gs.tty = tty;
+ if (!PortP->gs.count)
+ rio_inc_mod_count ();
PortP->gs.count++;
- rio_dprint(RIO_DEBUG_TTY, ("%d bytes in tx buffer\n",
- PortP->gs.xmit_cnt));
- gs_init_port (&PortP->gs);
+ rio_dprintk (RIO_DEBUG_TTY, "%d bytes in tx buffer\n",
+ PortP->gs.xmit_cnt);
+
+ retval = gs_init_port (&PortP->gs);
+ if (retval) {
+ PortP->gs.count--;
+ if (PortP->gs.count)
+ rio_dec_mod_count ();
+ return -ENXIO;
+ }
/*
** If the host hasn't been booted yet, then
** fail
*/
if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
- rio_dprint(RIO_DEBUG_TTY, ("Host not running\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Host not running\n");
pseterr(ENXIO);
func_exit ();
return -ENXIO;
@@ -230,24 +239,24 @@ riotopen(struct tty_struct * tty, struct file * filp)
#if 0
if (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
if (PortP->WaitUntilBooted) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot\n");
do {
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
- rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
func_exit ();
return -EINTR;
}
if (repeat_this -- <= 0) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
RIOPreemptiveCmd(p, PortP, FCLOSE );
pseterr(EINTR);
func_exit ();
return -EIO;
}
} while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
- rio_dprint(RIO_DEBUG_TTY, ("RTA has been booted\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
} else {
- rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
pseterr(ENXIO);
func_exit ();
return 0;
@@ -258,10 +267,10 @@ riotopen(struct tty_struct * tty, struct file * filp)
easier to read and shorter. Now, if it works too that would
be great... -- REW
*/
- rio_dprint(RIO_DEBUG_TTY, ("Checking if RTA has booted... \n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Checking if RTA has booted... \n");
while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
if (!PortP->WaitUntilBooted) {
- rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
func_exit ();
return -ENXIO;
}
@@ -271,17 +280,17 @@ riotopen(struct tty_struct * tty, struct file * filp)
now. --REW
*/
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
- rio_dprint(RIO_DEBUG_TTY, ("RTA_wait_for_boot: EINTR in delay \n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");
func_exit ();
return -EINTR;
}
if (repeat_this -- <= 0) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
func_exit ();
return -EIO;
}
}
- rio_dprint(RIO_DEBUG_TTY, ("RTA has been booted\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
#endif
#if 0
tp = PortP->TtyP; /* get tty struct */
@@ -304,9 +313,9 @@ riotopen(struct tty_struct * tty, struct file * filp)
** for it to finish, so that it doesn't close us!
*/
while ( (PortP->State & RIO_CLOSING) && !p->RIOHalted ) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for RIO_CLOSING to go away\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
if (repeat_this -- <= 0) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for not idle closed broken by signal\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
RIOPreemptiveCmd(p, PortP, FCLOSE );
retval = -EINTR;
goto bombout;
@@ -321,7 +330,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
}
if ( !PortP->Mapped ) {
- rio_dprint(RIO_DEBUG_TTY, ("Port unmapped while closing!\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Port unmapped while closing!\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
retval = -ENXIO;
func_exit ();
@@ -344,8 +353,8 @@ riotopen(struct tty_struct * tty, struct file * filp)
}
if (!(PortP->firstOpen)) { /* First time ? */
- rio_dprint(RIO_DEBUG_TTY, ("First open for this port\n"));
- rio_inc_mod_count ();
+ rio_dprintk (RIO_DEBUG_TTY, "First open for this port\n");
+
PortP->firstOpen++;
PortP->CookMode = 0; /* XXX RIOCookMode(tp); */
@@ -375,7 +384,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
** wait for the port to be not closed.
*/
while ( !(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted ) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState);
/*
** 15.10.1998 ARG - ESIL 0759
** (Part) fix for port being trashed when opened whilst RTA "disconnected"
@@ -392,7 +401,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
*/
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish broken by signal\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
RIOPreemptiveCmd(p, PortP, FCLOSE );
func_exit ();
return -EINTR;
@@ -407,52 +416,67 @@ bombout:
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return retval;
}
- rio_dprint(RIO_DEBUG_TTY, ("PORT_ISOPEN found\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
}
#ifdef MODEM_SUPPORT
if (Modem) {
- rio_dprint(RIO_DEBUG_TTY, ("Modem - test for carrier\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Modem - test for carrier\n");
/*
** ACTION
** insert test for carrier here. -- ???
** I already see that test here. What's the deal? -- REW
*/
- if ((tp->tm.c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
+ if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
{
- rio_dprint(RIO_DEBUG_TTY, (PortP,DBG_OPEN,"open(%d) Modem carr on\n",SysPort));
+ rio_dprintk (RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
+ /*
tp->tm.c_state |= CARR_ON;
wakeup((caddr_t) &tp->tm.c_canq);
+ */
+ PortP->State |= RIO_CARR_ON;
+ wake_up_interruptible (&PortP->gs.open_wait);
}
else /* no carrier - wait for DCD */
{
- while (!(tp->tm.c_state&CARR_ON) &&
- !(filp->f_flags&O_NONBLOCK) && !p->RIOHalted )
- {
- rio_dprint(RIO_DEBUG_TTY, (PortP,DBG_OPEN,"open(%d) sleeping for carr on\n",SysPort));
- tp->tm.c_state |= WOPEN;
+ /*
+ while (!(PortP->gs.tty->termios->c_state & CARR_ON) &&
+ !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
+ */
+ while (!(PortP->State & RIO_CARR_ON) &&
+ !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) {
+
+ rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n",SysPort);
+ /*
+ PortP->gs.tty->termios->c_state |= WOPEN;
+ */
PortP->State |= RIO_WOPEN;
- if ( sleep((caddr_t)&tp->tm.c_canq, TTIPRI|PCATCH))
+#if 0
+ if ( sleep((caddr_t)&tp->tm.c_canqo, TTIPRI|PCATCH))
{
/*
** ACTION: verify that this is a good thing
** to do here. -- ???
** I think it's OK. -- REW
*/
- rio_dprint(RIO_DEBUG_TTY, ("open(%d) sleeping for carr broken by signal\n",
- SysPort));
+ rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n",
+ SysPort);
RIOPreemptiveCmd( p, PortP, FCLOSE );
+ /*
tp->tm.c_state &= ~WOPEN;
+ */
PortP->State &= ~RIO_WOPEN;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
func_exit ();
return -EINTR;
}
+#endif
}
PortP->State &= ~RIO_WOPEN;
}
- if ( RIOHalted )
+ if ( p->RIOHalted )
goto bombout;
+ rio_dprintk (RIO_DEBUG_TTY, "Setting RIO_MOPEN\n");
PortP->State |= RIO_MOPEN;
}
else
@@ -470,7 +494,7 @@ bombout:
goto bombout;
}
- rio_dprint(RIO_DEBUG_TTY, ("high level open done\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "high level open done\n");
#ifdef STATS
PortP->Stat.OpenCnt++;
@@ -482,7 +506,7 @@ bombout:
PortP->opens++;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
- rio_dprint(RIO_DEBUG_TTY, ("Returning from open\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Returning from open\n");
func_exit ();
return 0;
}
@@ -509,13 +533,13 @@ riotclose(void *ptr)
int Modem;
int rv =0;
- rio_dprint(RIO_DEBUG_TTY, ("port close SysPort %d\n",PortP->PortNum));
+ rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
/* PortP = p->RIOPortp[SysPort]; */
- rio_dprint(RIO_DEBUG_TTY, ("Port is at address 0x%x\n",(int)PortP));
+ rio_dprintk (RIO_DEBUG_TTY, "Port is at address 0x%x\n",(int)PortP);
/* tp = PortP->TtyP;*/ /* Get tty */
tty = PortP->gs.tty;
- rio_dprint(RIO_DEBUG_TTY, ("TTY is at address 0x%x\n",(int)tty));
+ rio_dprintk (RIO_DEBUG_TTY, "TTY is at address 0x%x\n",(int)tty);
Modem = rio_ismodem(tty->device);
#if 0
/* What F.CKING cache? Even then, a higly idle multiprocessor,
@@ -533,7 +557,7 @@ riotclose(void *ptr)
PortP->State |= RIO_CLOSING;
if ( (PortP->State & RIO_DELETED) ) {
- rio_dprint(RIO_DEBUG_TTY, ("Close on deleted RTA\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Close on deleted RTA\n");
deleted = 1;
}
@@ -543,7 +567,7 @@ riotclose(void *ptr)
goto close_end;
}
- rio_dprint(RIO_DEBUG_TTY, ("Clear bits\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Clear bits\n");
/*
** clear the open bits for this device
*/
@@ -561,7 +585,7 @@ riotclose(void *ptr)
** The port is still open for the other task -
** return, pretending that we are still active.
*/
- rio_dprint(RIO_DEBUG_TTY, ("Channel %d still open !\n",PortP->PortNum));
+ rio_dprintk (RIO_DEBUG_TTY, "Channel %d still open !\n",PortP->PortNum);
PortP->State &= ~RIO_CLOSING;
if (PortP->firstOpen)
PortP->firstOpen--;
@@ -569,7 +593,7 @@ riotclose(void *ptr)
return -EIO;
}
- rio_dprint(RIO_DEBUG_TTY, ("Closing down - everything must go!\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Closing down - everything must go!\n");
PortP->State &= ~RIO_DYNOROD;
@@ -578,7 +602,7 @@ riotclose(void *ptr)
** to drain down before closing. Bye-bye....
** (We never meant to do this)
*/
- rio_dprint(RIO_DEBUG_TTY, ("Timeout 1 starts\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Timeout 1 starts\n");
#if 0
if (!deleted)
@@ -587,14 +611,14 @@ riotclose(void *ptr)
cprintf("Need to flush the ttyport\n");
if (repeat_this -- <= 0) {
rv = -EINTR;
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for not idle closed broken by signal\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
RIOPreemptiveCmd(p, PortP, FCLOSE );
goto close_end;
}
- rio_dprint(RIO_DEBUG_TTY, ("Calling timeout to flush in closing\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (RIODelay_ni(PortP, HUNDRED_MS*10) == RIO_FAIL) {
- rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
rv = -EINTR;
rio_spin_lock_irqsave(&PortP->portSem, flags);
goto close_end;
@@ -611,7 +635,7 @@ riotclose(void *ptr)
** The port has been re-opened for the other task -
** return, pretending that we are still active.
*/
- rio_dprint(RIO_DEBUG_TTY, ("Channel %d re-open!\n", PortP->PortNum));
+ rio_dprintk (RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum);
PortP->State &= ~RIO_CLOSING;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (PortP->firstOpen)
@@ -638,12 +662,12 @@ riotclose(void *ptr)
while (try && (PortP->PortState & PORT_ISOPEN)) {
try--;
if (try == 0) {
- rio_dprint(RIO_DEBUG_TTY, ("Run out of tries - force the bugger shut!\n" ));
+ rio_dprintk (RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n" );
RIOPreemptiveCmd(p, PortP,FCLOSE);
break;
}
- rio_dprint(RIO_DEBUG_TTY, ("Close: PortState:ISOPEN is %d\n",
- PortP->PortState & PORT_ISOPEN));
+ rio_dprintk (RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n",
+ PortP->PortState & PORT_ISOPEN);
if ( p->RIOHalted ) {
RIOClearUp( PortP );
@@ -652,7 +676,7 @@ riotclose(void *ptr)
RIODelay_ni(PortP, HUNDRED_MS);
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
- rio_dprint(RIO_DEBUG_TTY, ("Close: try was %d on completion\n", try ));
+ rio_dprintk (RIO_DEBUG_TTY, "Close: try was %d on completion\n", try );
/* RIOPreemptiveCmd(p, PortP, FCLOSE); */
@@ -682,7 +706,7 @@ close_end:
if (PortP->firstOpen)
PortP->firstOpen--;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
- rio_dprint(RIO_DEBUG_TTY, ("Return from close\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Return from close\n");
return rv;
}
@@ -731,7 +755,7 @@ static void
RIOClearUp(PortP)
struct Port *PortP;
{
- rio_dprint(RIO_DEBUG_TTY, ("RIOHalted set\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "RIOHalted set\n");
PortP->Config = 0; /* Direct semaphore */
PortP->PortState = 0;
PortP->firstOpen = 0;
@@ -761,7 +785,7 @@ static int RIOShortCommand(struct rio_info *p, struct Port *PortP,
int retries = 20; /* at 10 per second -> 2 seconds */
unsigned long flags;
- rio_dprint(RIO_DEBUG_TTY, ("entering shortcommand.\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "entering shortcommand.\n");
#ifdef CHECK
CheckPortP( PortP );
if ( len < 1 || len > 2 )
@@ -769,7 +793,7 @@ static int RIOShortCommand(struct rio_info *p, struct Port *PortP,
#endif
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_TTY, ("Short command to deleted RTA ignored\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
return RIO_FAIL;
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
@@ -779,8 +803,8 @@ static int RIOShortCommand(struct rio_info *p, struct Port *PortP,
** be free again.
*/
while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted ) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting for not in use (%d)\n",
- retries));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting for not in use (%d)\n",
+ retries);
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (retries-- <= 0) {
return RIO_FAIL;
@@ -791,16 +815,16 @@ static int RIOShortCommand(struct rio_info *p, struct Port *PortP,
rio_spin_lock_irqsave(&PortP->portSem, flags);
}
if ( PortP->State & RIO_DELETED ) {
- rio_dprint(RIO_DEBUG_TTY, ("Short command to deleted RTA ignored\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return RIO_FAIL;
}
while ( !can_add_transmit(&PacketP,PortP) && !p->RIOHalted ) {
- rio_dprint(RIO_DEBUG_TTY, ("Waiting to add short command to queue (%d)\n", retries));
+ rio_dprintk (RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries);
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (retries-- <= 0) {
- rio_dprint(RIO_DEBUG_TTY, ("out of tries. Failing\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "out of tries. Failing\n");
return RIO_FAIL;
}
if ( RIODelay_ni(PortP, HUNDRED_MS)==RIO_FAIL ) {
@@ -865,11 +889,11 @@ register caddr_t arg;
int Modem = rio_ismodem(dev);
int ioctl_processed;
- rio_dprint(RIO_DEBUG_TTY, ("port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
- SysPort,cmd,arg,Modem?"Modem":"tty"));
+ rio_dprintk (RIO_DEBUG_TTY, "port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
+ SysPort, cmd, arg, Modem?"Modem":"tty") ;
if ( SysPort >= RIO_PORTS ) {
- rio_dprint(RIO_DEBUG_TTY, ("Bad port number %d\n",SysPort));
+ rio_dprintk (RIO_DEBUG_TTY, "Bad port number %d\n", SysPort);
return -ENXIO;
}
@@ -926,22 +950,22 @@ register caddr_t arg;
return 0;
case TCRIOTSTATE:
- rio_dprint(RIO_DEBUG_TTY, ("tbusy/tstop monitoring %sabled\n",
- arg ? "en" : "dis"));
+ rio_dprintk (RIO_DEBUG_TTY, "tbusy/tstop monitoring %sabled\n",
+ arg ? "en" : "dis");
/* MonitorTstate = 0 ;*/
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
RIOParam(PortP, CONFIG, Modem, OK_TO_SLEEP);
return 0;
case TCRIOSTATE: /* current state of Modem input pins */
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOSTATE\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE\n");
if (RIOPreemptiveCmd(p, PortP, MGET) == RIO_FAIL)
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOSTATE command failed\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE command failed\n");
PortP->State |= RIO_BUSY;
current = PortP->ModemState;
if ( copyout((caddr_t)&current, (int)arg,
sizeof(current))==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_TTY, ("Copyout failed\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Copyout failed\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
pseterr(EFAULT);
}
@@ -950,15 +974,15 @@ register caddr_t arg;
case TCRIOMBIS: /* Set modem lines */
case TCRIOMBIC: /* Clear modem lines */
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOMBIS/TCRIOMBIC\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIS/TCRIOMBIC\n");
if (cmd == TCRIOMBIS) {
uint state;
state = (uint)arg;
PortP->ModemState |= (ushort)state;
PortP->ModemLines = (ulong) arg;
if (RIOPreemptiveCmd(p, PortP, MBIS) == RIO_FAIL)
- rio_dprint(RIO_DEBUG_TTY, (
- "TCRIOMBIS command failed\n"));
+ rio_dprintk (RIO_DEBUG_TTY,
+ "TCRIOMBIS command failed\n");
}
else {
uint state;
@@ -967,17 +991,17 @@ register caddr_t arg;
PortP->ModemState &= ~(ushort)state;
PortP->ModemLines = (ulong) arg;
if (RIOPreemptiveCmd(p, PortP, MBIC) == RIO_FAIL)
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOMBIC command failed\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIC command failed\n");
}
PortP->State |= RIO_BUSY;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return 0;
case TCRIOXPON: /* set Xprint ON string */
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPON\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPON\n");
if ( copyin((int)arg, (caddr_t)PortP->Xprint.XpOn,
MAX_XP_CTRL_LEN)==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_TTY, ("Copyin failed\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
PortP->Xprint.XpOn[0] = '\0';
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
pseterr(EFAULT);
@@ -989,10 +1013,10 @@ register caddr_t arg;
return 0;
case TCRIOXPOFF: /* set Xprint OFF string */
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPOFF\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPOFF\n");
if ( copyin( (int)arg, (caddr_t)PortP->Xprint.XpOff,
MAX_XP_CTRL_LEN)==COPYFAIL ) {
- rio_dprint(RIO_DEBUG_TTY, ("Copyin failed\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
PortP->Xprint.XpOff[0] = '\0';
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
pseterr(EFAULT);
@@ -1004,10 +1028,10 @@ register caddr_t arg;
return 0;
case TCRIOXPCPS: /* set Xprint CPS string */
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPCPS\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPCPS\n");
if ( (uint)arg > p->RIOConf.MaxXpCps ||
(uint)arg < p->RIOConf.MinXpCps ) {
- rio_dprint(RIO_DEBUG_TTY, ("%d CPS out of range\n",arg));
+ rio_dprintk (RIO_DEBUG_TTY, "%d CPS out of range\n",arg);
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
pseterr(EINVAL);
return 0;
@@ -1017,7 +1041,7 @@ register caddr_t arg;
return 0;
case TCRIOXPRINT:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPRINT\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPRINT\n");
if ( copyout((caddr_t)&PortP->Xprint, (int)arg,
sizeof(struct Xprint))==COPYFAIL ) {
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -1027,25 +1051,25 @@ register caddr_t arg;
return 0;
case TCRIOIXANYON:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXANYON\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYON\n");
PortP->Config |= RIO_IXANY;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return 0;
case TCRIOIXANYOFF:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXANYOFF\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYOFF\n");
PortP->Config &= ~RIO_IXANY;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return 0;
case TCRIOIXONON:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXONON\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONON\n");
PortP->Config |= RIO_IXON;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return 0;
case TCRIOIXONOFF:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXONOFF\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONOFF\n");
PortP->Config &= ~RIO_IXON;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return 0;
@@ -1055,28 +1079,28 @@ register caddr_t arg;
** Added support for CTS and RTS flow control ioctls :
*/
case TCRIOCTSFLOWEN:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOCTSFLOWEN\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWEN\n");
PortP->Config |= RIO_CTSFLOW;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
return 0;
case TCRIOCTSFLOWDIS:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIOCTSFLOWDIS\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWDIS\n");
PortP->Config &= ~RIO_CTSFLOW;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
return 0;
case TCRIORTSFLOWEN:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIORTSFLOWEN\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWEN\n");
PortP->Config |= RIO_RTSFLOW;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
return 0;
case TCRIORTSFLOWDIS:
- rio_dprint(RIO_DEBUG_TTY, ("TCRIORTSFLOWDIS\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWDIS\n");
PortP->Config &= ~RIO_RTSFLOW;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
@@ -1100,13 +1124,13 @@ register caddr_t arg;
case TCSETAW:
case TCSETAF:
ioctl_processed++;
- rio_dprint(RIO_DEBUG_TTY, ("NON POSIX ioctl\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "NON POSIX ioctl\n");
ttyseth_pv(PortP, tp, (struct termios *)arg, 0);
break;
case TCSETAP: /* posix tcsetattr() */
case TCSETAWP: /* posix tcsetattr() */
case TCSETAFP: /* posix tcsetattr() */
- rio_dprint(RIO_DEBUG_TTY, ("NON POSIX SYSV ioctl\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "NON POSIX SYSV ioctl\n");
ttyseth_pv(PortP, tp, (struct termios *)arg, 1);
ioctl_processed++;
break;
@@ -1141,7 +1165,7 @@ register caddr_t arg;
#endif
case TIOCSETD:
case TIOCSETN:
- rio_dprint(RIO_DEBUG_TTY, ("wait for non-BUSY, semaphore set\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "wait for non-BUSY, semaphore set\n");
/*
** Wait for drain here, at least as far as the double buffer
** being empty.
@@ -1208,8 +1232,8 @@ register caddr_t arg;
PortP->CookMode = RIOCookMode(tp); /* Set new cooking mode */
- rio_dprint(RIO_DEBUG_TTY, ("RIOIoctl changed %d newcook %d oldcook %d\n",
- changed,PortP->CookMode,oldcook));
+ rio_dprintk (RIO_DEBUG_TTY, "RIOIoctl changed %d newcook %d oldcook %d\n",
+ changed,PortP->CookMode,oldcook);
#ifdef MODEM_SUPPORT
/*
@@ -1232,7 +1256,7 @@ register caddr_t arg;
*/
if (changed || oldcook != PortP->CookMode || (ioctl_processed)) {
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
- rio_dprint(RIO_DEBUG_TTY, ("Ioctl changing the PORT settings\n"));
+ rio_dprintk (RIO_DEBUG_TTY, "Ioctl changing the PORT settings\n");
RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
rio_spin_lock_irqsave(&PortP->portSem, flags);
}
diff --git a/drivers/char/saa5249.c b/drivers/char/saa5249.c
deleted file mode 100644
index 1213e2ee5..000000000
--- a/drivers/char/saa5249.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Cleaned up to use existing videodev interface and allow the idea
- * of multiple teletext decoders on the video4linux iface. Changed i2c
- * to cover addressing clashes on device busses. It's also rebuilt so
- * you can add arbitary multiple teletext devices to Linux video4linux
- * now (well 32 anyway).
- *
- * Alan Cox <Alan.Cox@linux.org>
- *
- * The original driver was heavily modified to match the i2c interface
- * It was truncated to use the WinTV boards, too.
- *
- * Copyright (c) 1998 Richard Guenther <richard.guenther@student.uni-tuebingen.de>
- *
- * $Id: saa5249.c,v 1.1 1998/03/30 22:23:23 alan Exp $
- *
- * Derived From
- *
- * vtx.c:
- * This is a loadable character-device-driver for videotext-interfaces
- * (aka teletext). Please check the Makefile/README for a list of supported
- * interfaces.
- *
- * Copyright (c) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.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 of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <stdarg.h>
-#include <linux/i2c.h>
-#include <linux/videotext.h>
-#include <linux/videodev.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#define VTX_VER_MAJ 1
-#define VTX_VER_MIN 7
-
-
-
-#define NUM_DAUS 4
-#define NUM_BUFS 8
-#define IF_NAME "SAA5249"
-
-static const int disp_modes[8][3] =
-{
- { 0x46, 0x03, 0x03 }, /* DISPOFF */
- { 0x46, 0xcc, 0xcc }, /* DISPNORM */
- { 0x44, 0x0f, 0x0f }, /* DISPTRANS */
- { 0x46, 0xcc, 0x46 }, /* DISPINS */
- { 0x44, 0x03, 0x03 }, /* DISPOFF, interlaced */
- { 0x44, 0xcc, 0xcc }, /* DISPNORM, interlaced */
- { 0x44, 0x0f, 0x0f }, /* DISPTRANS, interlaced */
- { 0x44, 0xcc, 0x46 } /* DISPINS, interlaced */
-};
-
-
-
-#define PAGE_WAIT (300*HZ/1000) /* Time between requesting page and */
- /* checking status bits */
-#define PGBUF_EXPIRE (15*HZ) /* Time to wait before retransmitting */
- /* page regardless of infobits */
-typedef struct {
- u8 pgbuf[VTX_VIRTUALSIZE]; /* Page-buffer */
- u8 laststat[10]; /* Last value of infobits for DAU */
- u8 sregs[7]; /* Page-request registers */
- unsigned long expire; /* Time when page will be expired */
- unsigned clrfound : 1; /* VTXIOCCLRFOUND has been called */
- unsigned stopped : 1; /* VTXIOCSTOPDAU has been called */
-} vdau_t;
-
-struct saa5249_device
-{
- vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */
- /* real DAU, so we have to simulate some more) */
- int vtx_use_count;
- int is_searching[NUM_DAUS];
- int disp_mode;
- int virtual_mode;
- struct i2c_client *client;
-};
-
-
-#define CCTWR 34 /* I²C write/read-address of vtx-chip */
-#define CCTRD 35
-#define NOACK_REPEAT 10 /* Retry access this many times on failure */
-#define CLEAR_DELAY (HZ/20) /* Time required to clear a page */
-#define READY_TIMEOUT (30*HZ/1000) /* Time to wait for ready signal of I²C-bus interface */
-#define INIT_DELAY 500 /* Time in usec to wait at initialization of CEA interface */
-#define START_DELAY 10 /* Time in usec to wait before starting write-cycle (CEA) */
-
-#define VTX_DEV_MINOR 0
-
-/* General defines and debugging support */
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE 1
-#endif
-#ifndef MIN
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-#define RESCHED \
- do { \
- if (current->need_resched) \
- schedule(); \
- } while (0)
-
-static struct video_device saa_template; /* Declared near bottom */
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-static struct i2c_client client_template;
-
-static int saa5249_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind)
-{
- int pgbuf;
- int err;
- struct i2c_client *client;
- struct video_device *vd;
- struct saa5249_device *t;
-
- printk(KERN_INFO "saa5249: teletext chip found.\n");
- client=kmalloc(sizeof(*client), GFP_KERNEL);
- if(client==NULL)
- return -ENOMEM;
- client_template.adapter = adap;
- client_template.addr = addr;
- memcpy(client, &client_template, sizeof(*client));
- t = kmalloc(sizeof(*t), GFP_KERNEL);
- if(t==NULL)
- {
- kfree(client);
- return -ENOMEM;
- }
- memset(t, 0, sizeof(*t));
- strcpy(client->name, IF_NAME);
-
- /*
- * Now create a video4linux device
- */
-
- client->data = vd=(struct video_device *)kmalloc(sizeof(struct video_device), GFP_KERNEL);
- if(vd==NULL)
- {
- kfree(t);
- kfree(client);
- return -ENOMEM;
- }
- memcpy(vd, &saa_template, sizeof(*vd));
-
- for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
- {
- memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
- memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
- memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
- t->vdau[pgbuf].expire = 0;
- t->vdau[pgbuf].clrfound = TRUE;
- t->vdau[pgbuf].stopped = TRUE;
- t->is_searching[pgbuf] = FALSE;
- }
- vd->priv=t;
-
- /*
- * Register it
- */
-
- if((err=video_register_device(vd, VFL_TYPE_VTX))<0)
- {
- kfree(t);
- kfree(vd);
- kfree(client);
- return err;
- }
- t->client = client;
- i2c_attach_client(client);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * We do most of the hard work when we become a device on the i2c.
- */
-
-static int saa5249_probe(struct i2c_adapter *adap)
-{
- /* Only attach these chips to the BT848 bus for now */
-
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- {
- return i2c_probe(adap, &addr_data, saa5249_attach);
- }
- return 0;
-}
-
-static int saa5249_detach(struct i2c_client *client)
-{
- struct video_device *vd=client->data;
- i2c_detach_client(client);
- video_unregister_device(vd);
- kfree(vd->priv);
- kfree(vd);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int saa5249_command(struct i2c_client *device,
- unsigned int cmd, void *arg)
-{
- return -EINVAL;
-}
-
-/* new I2C driver support */
-
-static struct i2c_driver i2c_driver_videotext =
-{
- IF_NAME, /* name */
- I2C_DRIVERID_SAA5249, /* in i2c.h */
- I2C_DF_NOTIFY,
- saa5249_probe,
- saa5249_detach,
- saa5249_command
-};
-
-static struct i2c_client client_template = {
- "(unset)",
- -1,
- 0,
- 0,
- NULL,
- &i2c_driver_videotext
-};
-
-/*
- * Wait the given number of jiffies (10ms). This calls the scheduler, so the actual
- * delay may be longer.
- */
-
-static void jdelay(unsigned long delay)
-{
- sigset_t oldblocked = current->blocked;
-
- spin_lock_irq(&current->sigmask_lock);
- sigfillset(&current->blocked);
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(delay);
-
- spin_lock_irq(&current->sigmask_lock);
- current->blocked = oldblocked;
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
-}
-
-
-/*
- * I2C interfaces
- */
-
-static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
-{
- char buf[64];
-
- buf[0] = reg;
- memcpy(buf+1, data, count);
-
- if(i2c_master_send(t->client, buf, count+1)==count+1)
- return 0;
- return -1;
-}
-
-static int i2c_senddata(struct saa5249_device *t, ...)
-{
- unsigned char buf[64];
- int v;
- int ct=0;
- va_list argp;
- va_start(argp,t);
-
- while((v=va_arg(argp,int))!=-1)
- buf[ct++]=v;
- return i2c_sendbuf(t, buf[0], ct-1, buf+1);
-}
-
-/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
- * handshaking is done by this routine, ack will be sent after the last byte to inhibit further
- * sending of data. If uaccess is TRUE, data is written to user-space with put_user.
- * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
- */
-
-static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
-{
- if(i2c_master_recv(t->client, buf, count)!=count)
- return -1;
- return 0;
-}
-
-
-/*
- * Standard character-device-driver functions
- */
-
-static int saa5249_ioctl(struct video_device *vd, unsigned int cmd, void *arg)
-{
- struct saa5249_device *t=vd->priv;
- static int virtual_mode = FALSE;
-
- switch(cmd)
- {
- case VTXIOCGETINFO:
- {
- vtx_info_t info;
- info.version_major = VTX_VER_MAJ;
- info.version_minor = VTX_VER_MIN;
- info.numpages = NUM_DAUS;
- /*info.cct_type = CCT_TYPE;*/
- if(copy_to_user((void*)arg, &info, sizeof(vtx_info_t)))
- return -EFAULT;
- return 0;
- }
-
- case VTXIOCCLRPAGE:
- {
- vtx_pagereq_t req;
-
- if(copy_from_user(&req, (void*)arg, sizeof(vtx_pagereq_t)))
- return -EFAULT;
- if (req.pgbuf < 0 || req.pgbuf >= NUM_DAUS)
- return -EINVAL;
- memset(t->vdau[req.pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
- t->vdau[req.pgbuf].clrfound = TRUE;
- return 0;
- }
-
- case VTXIOCCLRFOUND:
- {
- vtx_pagereq_t req;
-
- if(copy_from_user(&req, (void*)arg, sizeof(vtx_pagereq_t)))
- return -EFAULT;
- if (req.pgbuf < 0 || req.pgbuf >= NUM_DAUS)
- return -EINVAL;
- t->vdau[req.pgbuf].clrfound = TRUE;
- return 0;
- }
-
- case VTXIOCPAGEREQ:
- {
- vtx_pagereq_t req;
- if(copy_from_user(&req, (void*)arg, sizeof(vtx_pagereq_t)))
- return -EFAULT;
- if (!(req.pagemask & PGMASK_PAGE))
- req.page = 0;
- if (!(req.pagemask & PGMASK_HOUR))
- req.hour = 0;
- if (!(req.pagemask & PGMASK_MINUTE))
- req.minute = 0;
- if (req.page < 0 || req.page > 0x8ff) /* 7FF ?? */
- return -EINVAL;
- req.page &= 0x7ff;
- if (req.hour < 0 || req.hour > 0x3f || req.minute < 0 || req.minute > 0x7f ||
- req.pagemask < 0 || req.pagemask >= PGMASK_MAX || req.pgbuf < 0 || req.pgbuf >= NUM_DAUS)
- return -EINVAL;
- t->vdau[req.pgbuf].sregs[0] = (req.pagemask & PG_HUND ? 0x10 : 0) | (req.page / 0x100);
- t->vdau[req.pgbuf].sregs[1] = (req.pagemask & PG_TEN ? 0x10 : 0) | ((req.page / 0x10) & 0xf);
- t->vdau[req.pgbuf].sregs[2] = (req.pagemask & PG_UNIT ? 0x10 : 0) | (req.page & 0xf);
- t->vdau[req.pgbuf].sregs[3] = (req.pagemask & HR_TEN ? 0x10 : 0) | (req.hour / 0x10);
- t->vdau[req.pgbuf].sregs[4] = (req.pagemask & HR_UNIT ? 0x10 : 0) | (req.hour & 0xf);
- t->vdau[req.pgbuf].sregs[5] = (req.pagemask & MIN_TEN ? 0x10 : 0) | (req.minute / 0x10);
- t->vdau[req.pgbuf].sregs[6] = (req.pagemask & MIN_UNIT ? 0x10 : 0) | (req.minute & 0xf);
- t->vdau[req.pgbuf].stopped = FALSE;
- t->vdau[req.pgbuf].clrfound = TRUE;
- t->is_searching[req.pgbuf] = TRUE;
- return 0;
- }
-
- case VTXIOCGETSTAT:
- {
- vtx_pagereq_t req;
- u8 infobits[10];
- vtx_pageinfo_t info;
- int a;
-
- if(copy_from_user(&req, (void*)arg, sizeof(vtx_pagereq_t)))
- return -EFAULT;
- if (req.pgbuf < 0 || req.pgbuf >= NUM_DAUS)
- return -EINVAL;
- if (!t->vdau[req.pgbuf].stopped)
- {
- if (i2c_senddata(t, 2, 0, -1) ||
- i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req.pgbuf].sregs) ||
- i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) ||
- i2c_senddata(t, 2, 0, t->vdau[req.pgbuf].sregs[0] | 8, -1) ||
- i2c_senddata(t, 8, 0, 25, 0, -1))
- return -EIO;
- jdelay(PAGE_WAIT);
- if (i2c_getdata(t, 10, infobits))
- return -EIO;
-
- if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */
- (memcmp(infobits, t->vdau[req.pgbuf].laststat, sizeof(infobits)) ||
- time_after_eq(jiffies, t->vdau[req.pgbuf].expire)))
- { /* check if new page arrived */
- if (i2c_senddata(t, 8, 0, 0, 0, -1) ||
- i2c_getdata(t, VTX_PAGESIZE, t->vdau[req.pgbuf].pgbuf))
- return -EIO;
- t->vdau[req.pgbuf].expire = jiffies + PGBUF_EXPIRE;
- memset(t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE);
- if (t->virtual_mode)
- {
- /* Packet X/24 */
- if (i2c_senddata(t, 8, 0, 0x20, 0, -1) ||
- i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40))
- return -EIO;
- /* Packet X/27/0 */
- if (i2c_senddata(t, 8, 0, 0x21, 0, -1) ||
- i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40))
- return -EIO;
- /* Packet 8/30/0...8/30/15
- * FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30,
- * so we should undo this here.
- */
- if (i2c_senddata(t, 8, 0, 0x22, 0, -1) ||
- i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40))
- return -EIO;
- }
- t->vdau[req.pgbuf].clrfound = FALSE;
- memcpy(t->vdau[req.pgbuf].laststat, infobits, sizeof(infobits));
- }
- else
- {
- memcpy(infobits, t->vdau[req.pgbuf].laststat, sizeof(infobits));
- }
- }
- else
- {
- memcpy(infobits, t->vdau[req.pgbuf].laststat, sizeof(infobits));
- }
-
- info.pagenum = ((infobits[8] << 8) & 0x700) | ((infobits[1] << 4) & 0xf0) | (infobits[0] & 0x0f);
- if (info.pagenum < 0x100)
- info.pagenum += 0x800;
- info.hour = ((infobits[5] << 4) & 0x30) | (infobits[4] & 0x0f);
- info.minute = ((infobits[3] << 4) & 0x70) | (infobits[2] & 0x0f);
- info.charset = ((infobits[7] >> 1) & 7);
- info.delete = !!(infobits[3] & 8);
- info.headline = !!(infobits[5] & 4);
- info.subtitle = !!(infobits[5] & 8);
- info.supp_header = !!(infobits[6] & 1);
- info.update = !!(infobits[6] & 2);
- info.inter_seq = !!(infobits[6] & 4);
- info.dis_disp = !!(infobits[6] & 8);
- info.serial = !!(infobits[7] & 1);
- info.notfound = !!(infobits[8] & 0x10);
- info.pblf = !!(infobits[9] & 0x20);
- info.hamming = 0;
- for (a = 0; a <= 7; a++)
- {
- if (infobits[a] & 0xf0)
- {
- info.hamming = 1;
- break;
- }
- }
- if (t->vdau[req.pgbuf].clrfound)
- info.notfound = 1;
- if(copy_to_user(req.buffer, &info, sizeof(vtx_pageinfo_t)))
- return -EFAULT;
- if (!info.hamming && !info.notfound)
- {
- t->is_searching[req.pgbuf] = FALSE;
- }
- return 0;
- }
-
- case VTXIOCGETPAGE:
- {
- vtx_pagereq_t req;
- int start, end;
-
- if(copy_from_user(&req, (void*)arg, sizeof(vtx_pagereq_t)))
- return -EFAULT;
- if (req.pgbuf < 0 || req.pgbuf >= NUM_DAUS || req.start < 0 ||
- req.start > req.end || req.end >= (virtual_mode ? VTX_VIRTUALSIZE : VTX_PAGESIZE))
- return -EINVAL;
- if(copy_to_user(req.buffer, &t->vdau[req.pgbuf].pgbuf[req.start], req.end - req.start + 1))
- return -EFAULT;
-
- /*
- * Always read the time directly from SAA5249
- */
-
- if (req.start <= 39 && req.end >= 32)
- {
- int len;
- char buf[16];
- start = MAX(req.start, 32);
- end = MIN(req.end, 39);
- len=end-start+1;
- if (i2c_senddata(t, 8, 0, 0, start, -1) ||
- i2c_getdata(t, len, buf))
- return -EIO;
- if(copy_to_user(req.buffer+start-req.start, buf, len))
- return -EFAULT;
- }
- /* Insert the current header if DAU is still searching for a page */
- if (req.start <= 31 && req.end >= 7 && t->is_searching[req.pgbuf])
- {
- char buf[32];
- int len;
- start = MAX(req.start, 7);
- end = MIN(req.end, 31);
- len=end-start+1;
- if (i2c_senddata(t, 8, 0, 0, start, -1) ||
- i2c_getdata(t, len, buf))
- return -EIO;
- if(copy_to_user(req.buffer+start-req.start, buf, len))
- return -EFAULT;
- }
- return 0;
- }
-
- case VTXIOCSTOPDAU:
- {
- vtx_pagereq_t req;
-
- if(copy_from_user(&req, (void*)arg, sizeof(vtx_pagereq_t)))
- return -EFAULT;
- if (req.pgbuf < 0 || req.pgbuf >= NUM_DAUS)
- return -EINVAL;
- t->vdau[req.pgbuf].stopped = TRUE;
- t->is_searching[req.pgbuf] = FALSE;
- return 0;
- }
-
- case VTXIOCPUTPAGE:
- case VTXIOCSETDISP:
- case VTXIOCPUTSTAT:
- return 0;
-
- case VTXIOCCLRCACHE:
- {
- if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11,
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -1))
- return -EIO;
- if (i2c_senddata(t, 3, 0x20, -1))
- return -EIO;
- jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */
- return 0;
- }
-
- case VTXIOCSETVIRT:
- {
- /* The SAA5249 has virtual-row reception turned on always */
- t->virtual_mode = (int)arg;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-
-static int saa5249_open(struct video_device *vd, int nb)
-{
- struct saa5249_device *t=vd->priv;
- int pgbuf;
-
- if (t->client==NULL)
- return -ENODEV;
-
- if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */
- /* Turn off parity checks (we do this ourselves) */
- i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) ||
- /* Display TV-picture, no virtual rows */
- i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */
-
- {
- return -EIO;
- }
-
- for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
- {
- memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
- memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
- memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
- t->vdau[pgbuf].expire = 0;
- t->vdau[pgbuf].clrfound = TRUE;
- t->vdau[pgbuf].stopped = TRUE;
- t->is_searching[pgbuf] = FALSE;
- }
- t->virtual_mode=FALSE;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-
-
-static void saa5249_release(struct video_device *vd)
-{
- struct saa5249_device *t=vd->priv;
- i2c_senddata(t, 1, 0x20, -1); /* Turn off CCT */
- i2c_senddata(t, 5, 3, 3, -1); /* Turn off TV-display */
- MOD_DEC_USE_COUNT;
- return;
-}
-
-static long saa5249_write(struct video_device *v, const char *buf, unsigned long l, int nb)
-{
- return -EINVAL;
-}
-
-static int __init init_saa_5249 (void)
-{
- printk(KERN_INFO "SAA5249 driver (" IF_NAME " interface) for VideoText version %d.%d\n",
- VTX_VER_MAJ, VTX_VER_MIN);
- return i2c_add_driver(&i2c_driver_videotext);
-}
-
-static void __exit cleanup_saa_5249 (void)
-{
- i2c_del_driver(&i2c_driver_videotext);
-}
-
-module_init(init_saa_5249);
-module_exit(cleanup_saa_5249);
-
-static struct video_device saa_template =
-{
- IF_NAME,
- VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */
- VID_HARDWARE_SAA5249,
- saa5249_open,
- saa5249_release,
- NULL, /* read */
- saa5249_write,
- NULL, /* poll */
- saa5249_ioctl,
- /* the rest are null */
-};
-
diff --git a/drivers/char/saa7110.c b/drivers/char/saa7110.c
deleted file mode 100644
index 6146b84b9..000000000
--- a/drivers/char/saa7110.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- saa7110 - Philips SAA7110(A) video decoder driver
-
- Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl>
-
- 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 of the License, 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.
-*/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <linux/i2c-old.h>
-#include <linux/videodev.h>
-#include "linux/video_decoder.h"
-
-#define DEBUG(x...) /* remove when no long debugging */
-
-#define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */
-#define SAA7110_MAX_OUTPUT 0 /* its a decoder only */
-
-#define I2C_SAA7110 0x9C /* or 0x9E */
-
-#define I2C_DELAY 10 /* 10 us or 100khz */
-
-struct saa7110 {
- struct i2c_bus *bus;
- int addr;
- unsigned char reg[36];
-
- int norm;
- int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
-};
-
-/* ----------------------------------------------------------------------- */
-/* I2C support functions */
-/* ----------------------------------------------------------------------- */
-static
-int saa7110_write(struct saa7110 *decoder, unsigned char subaddr, unsigned char data)
-{
- int ack;
-
- LOCK_I2C_BUS(decoder->bus);
- i2c_start(decoder->bus);
- i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY);
- i2c_sendbyte(decoder->bus, subaddr, I2C_DELAY);
- ack = i2c_sendbyte(decoder->bus, data, I2C_DELAY);
- i2c_stop(decoder->bus);
- decoder->reg[subaddr] = data;
- UNLOCK_I2C_BUS(decoder->bus);
- return ack;
-}
-
-static
-int saa7110_write_block(struct saa7110* decoder, unsigned const char *data, unsigned int len)
-{
- unsigned subaddr = *data;
-
- LOCK_I2C_BUS(decoder->bus);
- i2c_start(decoder->bus);
- i2c_sendbyte(decoder->bus,decoder->addr,I2C_DELAY);
- while (len-- > 0) {
- if (i2c_sendbyte(decoder->bus,*data,0)) {
- i2c_stop(decoder->bus);
- return -EAGAIN;
- }
- decoder->reg[subaddr++] = *data++;
- }
- i2c_stop(decoder->bus);
- UNLOCK_I2C_BUS(decoder->bus);
-
- return 0;
-}
-
-static
-int saa7110_read(struct saa7110* decoder)
-{
- int data;
-
- LOCK_I2C_BUS(decoder->bus);
- i2c_start(decoder->bus);
- i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY);
- i2c_start(decoder->bus);
- i2c_sendbyte(decoder->bus, decoder->addr | 1, I2C_DELAY);
- data = i2c_readbyte(decoder->bus, 1);
- i2c_stop(decoder->bus);
- UNLOCK_I2C_BUS(decoder->bus);
- return data;
-}
-
-/* ----------------------------------------------------------------------- */
-/* SAA7110 functions */
-/* ----------------------------------------------------------------------- */
-static
-int saa7110_selmux(struct i2c_device *device, int chan)
-{
-static const unsigned char modes[9][8] = {
-/* mode 0 */ { 0x00, 0xD9, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 },
-/* mode 1 */ { 0x00, 0xD8, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 },
-/* mode 2 */ { 0x00, 0xBA, 0x07, 0x91, 0x03, 0x60, 0xB5, 0x05 },
-/* mode 3 */ { 0x00, 0xB8, 0x07, 0x91, 0x03, 0x60, 0xB5, 0x05 },
-/* mode 4 */ { 0x00, 0x7C, 0x07, 0xD2, 0x83, 0x60, 0xB5, 0x03 },
-/* mode 5 */ { 0x00, 0x78, 0x07, 0xD2, 0x83, 0x60, 0xB5, 0x03 },
-/* mode 6 */ { 0x80, 0x59, 0x17, 0x42, 0xA3, 0x44, 0x75, 0x12 },
-/* mode 7 */ { 0x80, 0x9A, 0x17, 0xB1, 0x13, 0x60, 0xB5, 0x14 },
-/* mode 8 */ { 0x80, 0x3C, 0x27, 0xC1, 0x23, 0x44, 0x75, 0x21 } };
- struct saa7110* decoder = device->data;
- const unsigned char* ptr = modes[chan];
-
- saa7110_write(decoder,0x06,ptr[0]); /* Luminance control */
- saa7110_write(decoder,0x20,ptr[1]); /* Analog Control #1 */
- saa7110_write(decoder,0x21,ptr[2]); /* Analog Control #2 */
- saa7110_write(decoder,0x22,ptr[3]); /* Mixer Control #1 */
- saa7110_write(decoder,0x2C,ptr[4]); /* Mixer Control #2 */
- saa7110_write(decoder,0x30,ptr[5]); /* ADCs gain control */
- saa7110_write(decoder,0x31,ptr[6]); /* Mixer Control #3 */
- saa7110_write(decoder,0x21,ptr[7]); /* Analog Control #2 */
-
- return 0;
-}
-
-static
-int determine_norm(struct i2c_device* dev)
-{
- struct saa7110* decoder = dev->data;
- int status;
-
- /* mode changed, start automatic detection */
- status = saa7110_read(decoder);
- if ((status & 3) == 0) {
- saa7110_write(decoder,0x06,0x80);
- if (status & 0x20) {
- DEBUG(printk(KERN_INFO "%s: norm=bw60\n",dev->name));
- saa7110_write(decoder,0x2E,0x81);
- return VIDEO_MODE_NTSC;
- }
- DEBUG(printk(KERN_INFO "%s: norm=bw50\n",dev->name));
- saa7110_write(decoder,0x2E,0x9A);
- return VIDEO_MODE_PAL;
- }
-
- saa7110_write(decoder,0x06,0x00);
- if (status & 0x20) { /* 60Hz */
- DEBUG(printk(KERN_INFO "%s: norm=ntsc\n",dev->name));
- saa7110_write(decoder,0x0D,0x06);
- saa7110_write(decoder,0x11,0x2C);
- saa7110_write(decoder,0x2E,0x81);
- return VIDEO_MODE_NTSC;
- }
-
- /* 50Hz -> PAL/SECAM */
- saa7110_write(decoder,0x0D,0x06);
- saa7110_write(decoder,0x11,0x59);
- saa7110_write(decoder,0x2E,0x9A);
-
- mdelay(150); /* pause 150 ms */
-
- status = saa7110_read(decoder);
- if ((status & 0x03) == 0x01) {
- DEBUG(printk(KERN_INFO "%s: norm=secam\n",dev->name));
- saa7110_write(decoder,0x0D,0x07);
- return VIDEO_MODE_SECAM;
- }
- DEBUG(printk(KERN_INFO "%s: norm=pal\n",dev->name));
- return VIDEO_MODE_PAL;
-}
-
-static
-int saa7110_attach(struct i2c_device *device)
-{
-static const unsigned char initseq[] = {
- 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF0, 0x00, 0x00,
- 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x06, 0x18, 0x90,
- 0x00, 0x2C, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
- 0xF0, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xD9, 0x17, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
- 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x81, 0x03,
- 0x40, 0x75, 0x01, 0x8C, 0x03};
- struct saa7110* decoder;
- int rv;
-
- device->data = decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL);
- if (device->data == 0)
- return -ENOMEM;
-
- MOD_INC_USE_COUNT;
-
- /* clear our private data */
- memset(decoder, 0, sizeof(struct saa7110));
- strcpy(device->name, "saa7110");
- decoder->bus = device->bus;
- decoder->addr = device->addr;
- decoder->norm = VIDEO_MODE_PAL;
- decoder->input = 0;
- decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
-
- rv = saa7110_write_block(decoder, initseq, sizeof(initseq));
- if (rv < 0)
- printk(KERN_ERR "%s_attach: init status %d\n", device->name, rv);
- else {
- saa7110_write(decoder,0x21,0x16);
- saa7110_write(decoder,0x0D,0x04);
- DEBUG(printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7110_read(decoder)));
- saa7110_write(decoder,0x0D,0x06);
- }
-
- /* setup and implicit mode 0 select has been performed */
- return 0;
-}
-
-static
-int saa7110_detach(struct i2c_device *device)
-{
- struct saa7110* decoder = device->data;
-
- DEBUG(printk(KERN_INFO "%s_detach\n",device->name));
-
- /* stop further output */
- saa7110_write(decoder,0x0E,0x00);
-
- kfree(device->data);
-
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static
-int saa7110_command(struct i2c_device *device, unsigned int cmd, void *arg)
-{
- struct saa7110* decoder = device->data;
- int v;
-
- switch (cmd) {
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *dc = arg;
- dc->flags = VIDEO_DECODER_PAL
- | VIDEO_DECODER_NTSC
- | VIDEO_DECODER_SECAM
- | VIDEO_DECODER_AUTO
- | VIDEO_DECODER_CCIR;
- dc->inputs = SAA7110_MAX_INPUT;
- dc->outputs = SAA7110_MAX_OUTPUT;
- }
- break;
-
- case DECODER_GET_STATUS:
- {
- struct saa7110* decoder = device->data;
- int status;
- int res = 0;
-
- status = i2c_read(device->bus,device->addr|1);
- if (status & 0x40)
- res |= DECODER_STATUS_GOOD;
- if (status & 0x03)
- res |= DECODER_STATUS_COLOR;
-
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- }
- *(int*)arg = res;
- }
- break;
-
- case DECODER_SET_NORM:
- v = *(int*)arg;
- if (decoder->norm != v) {
- decoder->norm = v;
- saa7110_write(decoder, 0x06, 0x00);
- switch (v) {
- case VIDEO_MODE_NTSC:
- saa7110_write(decoder, 0x0D, 0x06);
- saa7110_write(decoder, 0x11, 0x2C);
- saa7110_write(decoder, 0x30, 0x81);
-saa7110_write(decoder, 0x2A, 0xDF);
- break;
- case VIDEO_MODE_PAL:
- saa7110_write(decoder, 0x0D, 0x06);
- saa7110_write(decoder, 0x11, 0x59);
- saa7110_write(decoder, 0x2E, 0x9A);
- break;
- case VIDEO_MODE_SECAM:
- saa7110_write(decoder, 0x0D, 0x07);
- saa7110_write(decoder, 0x11, 0x59);
- saa7110_write(decoder, 0x2E, 0x9A);
- break;
- case VIDEO_MODE_AUTO:
- *(int*)arg = determine_norm(device);
- break;
- default:
- return -EPERM;
- }
- }
- break;
-
- case DECODER_SET_INPUT:
- v = *(int*)arg;
- if (v<0 || v>SAA7110_MAX_INPUT)
- return -EINVAL;
- if (decoder->input != v) {
- decoder->input = v;
- saa7110_selmux(device, v);
- }
- break;
-
- case DECODER_SET_OUTPUT:
- v = *(int*)arg;
- /* not much choice of outputs */
- if (v != 0)
- return -EINVAL;
- break;
-
- case DECODER_ENABLE_OUTPUT:
- v = *(int*)arg;
- if (decoder->enable != v) {
- decoder->enable = v;
- saa7110_write(decoder,0x0E, v ? 0x18 : 0x00);
- }
- break;
-
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7110_write(decoder, 0x19, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7110_write(decoder, 0x13, decoder->contrast >> 9);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7110_write(decoder, 0x12, decoder->sat >> 9);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7110_write(decoder, 0x07, (decoder->hue>>8)-128);
- }
- }
- break;
-
- case DECODER_DUMP:
- for (v=0; v<34; v+=16) {
- int j;
- DEBUG(printk(KERN_INFO "%s: %03x\n",device->name,v));
- for (j=0; j<16; j++) {
- DEBUG(printk(KERN_INFO " %02x",decoder->reg[v+j]));
- }
- DEBUG(printk(KERN_INFO "\n"));
- }
- break;
-
- default:
- DEBUG(printk(KERN_INFO "unknown saa7110_command??(%d)\n",cmd));
- return -EINVAL;
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct i2c_driver i2c_driver_saa7110 =
-{
- "saa7110", /* name */
-
- I2C_DRIVERID_VIDEODECODER, /* in i2c.h */
- I2C_SAA7110, I2C_SAA7110+1, /* Addr range */
-
- saa7110_attach,
- saa7110_detach,
- saa7110_command
-};
-
-EXPORT_NO_SYMBOLS;
-
-#ifdef MODULE
-int init_module(void)
-#else
-int saa7110_init(void)
-#endif
-{
- return i2c_register_driver(&i2c_driver_saa7110);
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
- i2c_unregister_driver(&i2c_driver_saa7110);
-}
-#endif
diff --git a/drivers/char/saa7111.c b/drivers/char/saa7111.c
deleted file mode 100644
index 1eeeca352..000000000
--- a/drivers/char/saa7111.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- saa7111 - Philips SAA7111A video decoder driver version 0.0.3
-
- Copyright (C) 1998 Dave Perks <dperks@ibm.net>
-
- 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 of the License, 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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <asm/segment.h>
-#include <linux/types.h>
-#include <linux/wrapper.h>
-
-#include <linux/videodev.h>
-#include <linux/version.h>
-#include <asm/uaccess.h>
-
-#include <linux/i2c-old.h>
-#include <linux/video_decoder.h>
-
-#define DEBUG(x) /* Debug driver */
-
-/* ----------------------------------------------------------------------- */
-
-struct saa7111 {
- struct i2c_bus *bus;
- int addr;
- unsigned char reg[32];
-
- int norm;
- int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
-};
-
-#define I2C_SAA7111 0x48
-
-#define I2C_DELAY 10
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7111_write(struct saa7111 *dev, unsigned char subaddr, unsigned char data)
-{
- int ack;
-
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
- dev->reg[subaddr] = data;
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- return ack;
-}
-
-static int saa7111_write_block(struct saa7111 *dev, unsigned const char *data, unsigned int len)
-{
- int ack = 0;
- unsigned subaddr;
-
- while (len > 1) {
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
- len -= 2;
- while (len > 1 && *data == ++subaddr) {
- data++;
- ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
- len -= 2;
- }
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- }
- return ack;
-}
-
-static int saa7111_read(struct saa7111 *dev, unsigned char subaddr)
-{
- int data;
-
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
- data = i2c_readbyte(dev->bus, 1);
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- return data;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7111_attach(struct i2c_device *device)
-{
- int i;
- struct saa7111 *decoder;
-
- static const unsigned char init[] =
- {
- 0x00, 0x00, /* 00 - ID byte */
- 0x01, 0x00, /* 01 - reserved */
-
- /*front end */
- 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
- 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
- 0x04, 0x00, /* 04 - GAI1=256 */
- 0x05, 0x00, /* 05 - GAI2=256 */
-
- /* decoder */
- 0x06, 0xf6, /* 06 - HSB at 13(50Hz) / 17(60Hz) pixels after end of last line */
- 0x07, 0xdd, /* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
- 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, HPLL=0, VNOI=0 */
- 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, UPTCV=0, APER=1 */
- 0x0a, 0x80, /* 0a - BRIG=128 */
- 0x0b, 0x47, /* 0b - CONT=1.109 */
- 0x0c, 0x40, /* 0c - SATN=1.0 */
- 0x0d, 0x00, /* 0d - HUE=0 */
- 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
- 0x0f, 0x00, /* 0f - reserved */
- 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
- 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
- 0x12, 0x00, /* 12 - output control 2 */
- 0x13, 0x00, /* 13 - output control 3 */
- 0x14, 0x00, /* 14 - reserved */
- 0x15, 0x00, /* 15 - VBI */
- 0x16, 0x00, /* 16 - VBI */
- 0x17, 0x00, /* 17 - VBI */
- };
-
- device->data = decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
- if (decoder == NULL) {
- return -ENOMEM;
- }
- MOD_INC_USE_COUNT;
-
- memset(decoder, 0, sizeof(struct saa7111));
- strcpy(device->name, "saa7111");
- decoder->bus = device->bus;
- decoder->addr = device->addr;
- decoder->norm = VIDEO_MODE_NTSC;
- decoder->input = 0;
- decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
-
- i = saa7111_write_block(decoder, init, sizeof(init));
- if (i < 0) {
- printk(KERN_ERR "%s_attach: init status %d\n", device->name, i);
- } else {
- printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7111_read(decoder, 0x00));
- }
- return 0;
-}
-
-
-static int saa7111_detach(struct i2c_device *device)
-{
- kfree(device->data);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int saa7111_command(struct i2c_device *device, unsigned int cmd, void *arg)
-{
- struct saa7111 *decoder = device->data;
-
- switch (cmd) {
-
-#if defined(DECODER_DUMP)
- case DECODER_DUMP:
- {
- int i;
-
- for (i = 0; i < 32; i += 16) {
- int j;
-
- printk("KERN_DEBUG %s: %03x", device->name, i);
- for (j = 0; j < 16; ++j) {
- printk(" %02x", saa7111_read(decoder, i + j));
- }
- printk("\n");
- }
- }
- break;
-#endif /* defined(DECODER_DUMP) */
-
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
-
- cap->flags
- = VIDEO_DECODER_PAL
- | VIDEO_DECODER_NTSC
- | VIDEO_DECODER_AUTO
- | VIDEO_DECODER_CCIR;
- cap->inputs = 8;
- cap->outputs = 1;
- }
- break;
-
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
-
- status = saa7111_read(decoder, 0x1f);
- res = 0;
- if ((status & (1 << 6)) == 0) {
- res |= DECODER_STATUS_GOOD;
- }
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & (1 << 5)) != 0) {
- res |= DECODER_STATUS_NTSC;
- } else {
- res |= DECODER_STATUS_PAL;
- }
- break;
- }
- if ((status & (1 << 0)) != 0) {
- res |= DECODER_STATUS_COLOR;
- }
- *iarg = res;
- }
- break;
-
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
-
- switch (*iarg) {
-
- case VIDEO_MODE_NTSC:
- saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x40);
- break;
-
- case VIDEO_MODE_PAL:
- saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x00);
- break;
-
- case VIDEO_MODE_AUTO:
- saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x80);
- break;
-
- default:
- return -EINVAL;
-
- }
- decoder->norm = *iarg;
- }
- break;
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
-
- if (*iarg < 0 || *iarg > 7) {
- return -EINVAL;
- }
- if (decoder->input != *iarg) {
- decoder->input = *iarg;
- /* select mode */
- saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8) | decoder->input);
- /* bypass chrominance trap for modes 4..7 */
- saa7111_write(decoder, 0x09, (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
- }
- }
- break;
-
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
- }
- break;
-
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- int enable = (*iarg != 0);
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
-
-// RJ: If output should be disabled (for playing videos), we also need a open PLL.
- // The input is set to 0 (where no input source is connected), although this
- // is not necessary.
- //
- // If output should be enabled, we have to reverse the above.
-
- if (decoder->enable) {
- saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8) | decoder->input);
- saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0xfb));
- saa7111_write(decoder, 0x11, (decoder->reg[0x11] & 0xf3) | 0x0c);
- } else {
- saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8));
- saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0xfb) | 0x04);
- saa7111_write(decoder, 0x11, (decoder->reg[0x11] & 0xf3));
- }
- }
- }
- break;
-
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7111_write(decoder, 0x0a, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7111_write(decoder, 0x0b, decoder->contrast >> 9);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7111_write(decoder, 0x0c, decoder->sat >> 9);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7111_write(decoder, 0x0d, (decoder->hue - 32768) >> 8);
- }
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct i2c_driver i2c_driver_saa7111 =
-{
- "saa7111", /* name */
- I2C_DRIVERID_VIDEODECODER, /* ID */
- I2C_SAA7111, I2C_SAA7111 + 1,
-
- saa7111_attach,
- saa7111_detach,
- saa7111_command
-};
-
-EXPORT_NO_SYMBOLS;
-
-#ifdef MODULE
-int init_module(void)
-#else
-int saa7111_init(void)
-#endif
-{
- return i2c_register_driver(&i2c_driver_saa7111);
-}
-
-
-
-#ifdef MODULE
-
-void cleanup_module(void)
-{
- i2c_unregister_driver(&i2c_driver_saa7111);
-}
-
-#endif
diff --git a/drivers/char/saa7121.h b/drivers/char/saa7121.h
deleted file mode 100644
index 74e37d405..000000000
--- a/drivers/char/saa7121.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* saa7121.h - saa7121 initializations
- Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
-
- 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 of the License, 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.
-
- */
-#ifndef __SAA7121_H__
-#define __SAA7121_H__
-
-#define NTSC_BURST_START 0x19 /* 28 */
-#define NTSC_BURST_END 0x1d /* 29 */
-#define NTSC_CHROMA_PHASE 0x67 /* 5a */
-#define NTSC_GAINU 0x76 /* 5b */
-#define NTSC_GAINV 0xa5 /* 5c */
-#define NTSC_BLACK_LEVEL 0x2a /* 5d */
-#define NTSC_BLANKING_LEVEL 0x2e /* 5e */
-#define NTSC_VBI_BLANKING 0x2e /* 5f */
-#define NTSC_DAC_CONTROL 0x11 /* 61 */
-#define NTSC_BURST_AMP 0x3f /* 62 */
-#define NTSC_SUBC3 0x1f /* 63 */
-#define NTSC_SUBC2 0x7c /* 64 */
-#define NTSC_SUBC1 0xf0 /* 65 */
-#define NTSC_SUBC0 0x21 /* 66 */
-#define NTSC_HTRIG 0x72 /* 6c */
-#define NTSC_VTRIG 0x00 /* 6c */
-#define NTSC_MULTI 0x30 /* 6e */
-#define NTSC_CCTTX 0x11 /* 6f */
-#define NTSC_FIRST_ACTIVE 0x12 /* 7a */
-#define NTSC_LAST_ACTIVE 0x02 /* 7b */
-#define NTSC_MSB_VERTICAL 0x40 /* 7c */
-
-#define PAL_BURST_START 0x21 /* 28 */
-#define PAL_BURST_END 0x1d /* 29 */
-#define PAL_CHROMA_PHASE 0x3f /* 5a */
-#define PAL_GAINU 0x7d /* 5b */
-#define PAL_GAINV 0xaf /* 5c */
-#define PAL_BLACK_LEVEL 0x23 /* 5d */
-#define PAL_BLANKING_LEVEL 0x35 /* 5e */
-#define PAL_VBI_BLANKING 0x35 /* 5f */
-#define PAL_DAC_CONTROL 0x02 /* 61 */
-#define PAL_BURST_AMP 0x2f /* 62 */
-#define PAL_SUBC3 0xcb /* 63 */
-#define PAL_SUBC2 0x8a /* 64 */
-#define PAL_SUBC1 0x09 /* 65 */
-#define PAL_SUBC0 0x2a /* 66 */
-#define PAL_HTRIG 0x86 /* 6c */
-#define PAL_VTRIG 0x04 /* 6d */
-#define PAL_MULTI 0x20 /* 6e */
-#define PAL_CCTTX 0x15 /* 6f */
-#define PAL_FIRST_ACTIVE 0x16 /* 7a */
-#define PAL_LAST_ACTIVE 0x36 /* 7b */
-#define PAL_MSB_VERTICAL 0x40 /* 7c */
-
-/* Initialization Sequence */
-
-static __u8 init7121ntsc[] = {
- 0x26, 0x0, 0x27, 0x0,
- 0x28, NTSC_BURST_START, 0x29, NTSC_BURST_END,
- 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
- 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
- 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
- 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
- 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
- 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
- 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
- 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
- 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
- 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
- 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
- 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
- 0x5a, NTSC_CHROMA_PHASE, 0x5b, NTSC_GAINU,
- 0x5c, NTSC_GAINV, 0x5d, NTSC_BLACK_LEVEL,
- 0x5e, NTSC_BLANKING_LEVEL, 0x5f, NTSC_VBI_BLANKING,
- 0x60, 0x0, 0x61, NTSC_DAC_CONTROL,
- 0x62, NTSC_BURST_AMP, 0x63, NTSC_SUBC3,
- 0x64, NTSC_SUBC2, 0x65, NTSC_SUBC1,
- 0x66, NTSC_SUBC0, 0x67, 0x80, 0x68, 0x80,
- 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
- 0x6c, NTSC_HTRIG, 0x6d, NTSC_VTRIG,
- 0x6e, NTSC_MULTI, 0x6f, NTSC_CCTTX,
- 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
- 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
- 0x78, 0x0, 0x79, 0x0, 0x7a, NTSC_FIRST_ACTIVE,
- 0x7b, NTSC_LAST_ACTIVE, 0x7c, NTSC_MSB_VERTICAL,
- 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
-};
-#define INIT7121LEN (sizeof(init7121ntsc)/2)
-
-static __u8 init7121pal[] = {
- 0x26, 0x0, 0x27, 0x0,
- 0x28, PAL_BURST_START, 0x29, PAL_BURST_END,
- 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
- 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
- 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
- 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
- 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
- 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
- 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
- 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
- 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
- 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
- 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
- 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
- 0x5a, PAL_CHROMA_PHASE, 0x5b, PAL_GAINU,
- 0x5c, PAL_GAINV, 0x5d, PAL_BLACK_LEVEL,
- 0x5e, PAL_BLANKING_LEVEL, 0x5f, PAL_VBI_BLANKING,
- 0x60, 0x0, 0x61, PAL_DAC_CONTROL,
- 0x62, PAL_BURST_AMP, 0x63, PAL_SUBC3,
- 0x64, PAL_SUBC2, 0x65, PAL_SUBC1,
- 0x66, PAL_SUBC0, 0x67, 0x80, 0x68, 0x80,
- 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
- 0x6c, PAL_HTRIG, 0x6d, PAL_VTRIG,
- 0x6e, PAL_MULTI, 0x6f, PAL_CCTTX,
- 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
- 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
- 0x78, 0x0, 0x79, 0x0, 0x7a, PAL_FIRST_ACTIVE,
- 0x7b, PAL_LAST_ACTIVE, 0x7c, PAL_MSB_VERTICAL,
- 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
-};
-#endif
diff --git a/drivers/char/saa7146.h b/drivers/char/saa7146.h
deleted file mode 100644
index 481308e6c..000000000
--- a/drivers/char/saa7146.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- saa7146.h - definitions philips saa7146 based cards
- Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
-
- 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 of the License, 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.
-*/
-
-#ifndef __SAA7146__
-#define __SAA7146__
-
-#define SAA7146_VERSION_CODE 0x000101
-
-#include <linux/types.h>
-#include <linux/wait.h>
-
-#include <linux/i2c.h>
-#include <linux/videodev.h>
-
-#ifndef O_NONCAP
-#define O_NONCAP O_TRUNC
-#endif
-
-#define MAX_GBUFFERS 2
-#define FBUF_SIZE 0x190000
-
-#ifdef __KERNEL__
-
-struct saa7146_window
-{
- int x, y;
- ushort width, height;
- ushort bpp, bpl;
- ushort swidth, sheight;
- short cropx, cropy;
- ushort cropwidth, cropheight;
- unsigned long vidadr;
- int color_fmt;
- ushort depth;
-};
-
-/* Per-open data for handling multiple opens on one device */
-struct device_open
-{
- int isopen;
- int noncapturing;
- struct saa7146 *dev;
-};
-#define MAX_OPENS 3
-
-struct saa7146
-{
- struct video_device video_dev;
- struct video_picture picture;
- struct video_audio audio_dev;
- struct video_info vidinfo;
- int user;
- int cap;
- int capuser;
- int irqstate; /* irq routine is state driven */
- int writemode;
- int playmode;
- unsigned int nr;
- unsigned long irq; /* IRQ used by SAA7146 card */
- unsigned short id;
- struct i2c_bus i2c;
- struct pci_dev *dev;
- unsigned char revision;
- unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */
- unsigned long saa7146_adr; /* bus address of IO mem from PCI BIOS */
- struct saa7146_window win;
- unsigned char *saa7146_mem; /* pointer to mapped IO memory */
- struct device_open open_data[MAX_OPENS];
-#define MAX_MARKS 16
- /* for a/v sync */
- int endmark[MAX_MARKS], endmarkhead, endmarktail;
- u32 *dmaRPS1, *pageRPS1, *dmaRPS2, *pageRPS2, *dmavid1, *dmavid2,
- *dmavid3, *dmaa1in, *dmaa1out, *dmaa2in, *dmaa2out,
- *pagedebi, *pagevid1, *pagevid2, *pagevid3, *pagea1in,
- *pagea1out, *pagea2in, *pagea2out;
- wait_queue_head_t i2cq, debiq, audq, vidq;
- u8 *vidbuf, *audbuf, *osdbuf, *dmadebi;
- int audhead, vidhead, osdhead, audtail, vidtail, osdtail;
- spinlock_t lock; /* the device lock */
-};
-#endif
-
-#ifdef _ALPHA_SAA7146
-#define saawrite(dat,adr) writel((dat),(char *) (saa->saa7146_adr+(adr)))
-#define saaread(adr) readl(saa->saa7146_adr+(adr))
-#else
-#define saawrite(dat,adr) writel((dat), (char *) (saa->saa7146_mem+(adr)))
-#define saaread(adr) readl(saa->saa7146_mem+(adr))
-#endif
-
-#define saaand(dat,adr) saawrite((dat) & saaread(adr), adr)
-#define saaor(dat,adr) saawrite((dat) | saaread(adr), adr)
-#define saaaor(dat,mask,adr) saawrite((dat) | ((mask) & saaread(adr)), adr)
-
-/* bitmask of attached hardware found */
-#define SAA7146_UNKNOWN 0x00000000
-#define SAA7146_SAA7111 0x00000001
-#define SAA7146_SAA7121 0x00000002
-#define SAA7146_IBMMPEG 0x00000004
-
-#endif
diff --git a/drivers/char/saa7146reg.h b/drivers/char/saa7146reg.h
deleted file mode 100644
index 6cc910f50..000000000
--- a/drivers/char/saa7146reg.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- saa7146.h - definitions philips saa7146 based cards
- Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
-
- 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 of the License, 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.
-*/
-
-#ifndef __SAA7146_REG__
-#define __SAA7146_REG__
-#define SAA7146_BASE_ODD1 0x00
-#define SAA7146_BASE_EVEN1 0x04
-#define SAA7146_PROT_ADDR1 0x08
-#define SAA7146_PITCH1 0x0c
-#define SAA7146_PAGE1 0x10
-#define SAA7146_NUM_LINE_BYTE1 0x14
-#define SAA7146_BASE_ODD2 0x18
-#define SAA7146_BASE_EVEN2 0x1c
-#define SAA7146_PROT_ADDR2 0x20
-#define SAA7146_PITCH2 0x24
-#define SAA7146_PAGE2 0x28
-#define SAA7146_NUM_LINE_BYTE2 0x2c
-#define SAA7146_BASE_ODD3 0x30
-#define SAA7146_BASE_EVEN3 0x34
-#define SAA7146_PROT_ADDR3 0x38
-#define SAA7146_PITCH3 0x3c
-#define SAA7146_PAGE3 0x40
-#define SAA7146_NUM_LINE_BYTE3 0x44
-#define SAA7146_PCI_BT_V1 0x48
-#define SAA7146_PCI_BT_V2 0x49
-#define SAA7146_PCI_BT_V3 0x4a
-#define SAA7146_PCI_BT_DEBI 0x4b
-#define SAA7146_PCI_BT_A 0x4c
-#define SAA7146_DD1_INIT 0x50
-#define SAA7146_DD1_STREAM_B 0x54
-#define SAA7146_DD1_STREAM_A 0x56
-#define SAA7146_BRS_CTRL 0x58
-#define SAA7146_HPS_CTRL 0x5c
-#define SAA7146_HPS_V_SCALE 0x60
-#define SAA7146_HPS_V_GAIN 0x64
-#define SAA7146_HPS_H_PRESCALE 0x68
-#define SAA7146_HPS_H_SCALE 0x6c
-#define SAA7146_BCS_CTRL 0x70
-#define SAA7146_CHROMA_KEY_RANGE 0x74
-#define SAA7146_CLIP_FORMAT_CTRL 0x78
-#define SAA7146_DEBI_CONFIG 0x7c
-#define SAA7146_DEBI_COMMAND 0x80
-#define SAA7146_DEBI_PAGE 0x84
-#define SAA7146_DEBI_AD 0x88
-#define SAA7146_I2C_TRANSFER 0x8c
-#define SAA7146_I2C_STATUS 0x90
-#define SAA7146_BASE_A1_IN 0x94
-#define SAA7146_PROT_A1_IN 0x98
-#define SAA7146_PAGE_A1_IN 0x9C
-#define SAA7146_BASE_A1_OUT 0xa0
-#define SAA7146_PROT_A1_OUT 0xa4
-#define SAA7146_PAGE_A1_OUT 0xa8
-#define SAA7146_BASE_A2_IN 0xac
-#define SAA7146_PROT_A2_IN 0xb0
-#define SAA7146_PAGE_A2_IN 0xb4
-#define SAA7146_BASE_A2_OUT 0xb8
-#define SAA7146_PROT_A2_OUT 0xbc
-#define SAA7146_PAGE_A2_OUT 0xc0
-#define SAA7146_RPS_PAGE0 0xc4
-#define SAA7146_RPS_PAGE1 0xc8
-#define SAA7146_RPS_THRESH0 0xcc
-#define SAA7146_RPS_THRESH1 0xd0
-#define SAA7146_RPS_TOV0 0xd4
-#define SAA7146_RPS_TOV1 0xd8
-#define SAA7146_IER 0xdc
-#define SAA7146_GPIO_CTRL 0xe0
-#define SAA7146_EC1SSR 0xe4
-#define SAA7146_EC2SSR 0xe8
-#define SAA7146_ECT1R 0xec
-#define SAA7146_ECT2R 0xf0
-#define SAA7146_ACON1 0xf4
-#define SAA7146_ACON2 0xf8
-#define SAA7146_MC1 0xfc
-#define SAA7146_MC2 0x100
-#define SAA7146_RPS_ADDR0 0x104
-#define SAA7146_RPS_ADDR1 0x108
-#define SAA7146_ISR 0x10c
-#define SAA7146_PSR 0x110
-#define SAA7146_SSR 0x114
-#define SAA7146_EC1R 0x118
-#define SAA7146_EC2R 0x11c
-#define SAA7146_VDP1 0x120
-#define SAA7146_VDP2 0x124
-#define SAA7146_VDP3 0x128
-#define SAA7146_ADP1 0x12c
-#define SAA7146_ADP2 0x130
-#define SAA7146_ADP3 0x134
-#define SAA7146_ADP4 0x138
-#define SAA7146_DDP 0x13c
-#define SAA7146_LEVEL_REP 0x140
-#define SAA7146_FB_BUFFER1 0x144
-#define SAA7146_FB_BUFFER2 0x148
-#define SAA7146_A_TIME_SLOT1 0x180
-#define SAA7146_A_TIME_SLOT2 0x1C0
-
-/* bitfield defines */
-#define MASK_31 0x80000000
-#define MASK_30 0x40000000
-#define MASK_29 0x20000000
-#define MASK_28 0x10000000
-#define MASK_27 0x08000000
-#define MASK_26 0x04000000
-#define MASK_25 0x02000000
-#define MASK_24 0x01000000
-#define MASK_23 0x00800000
-#define MASK_22 0x00400000
-#define MASK_21 0x00200000
-#define MASK_20 0x00100000
-#define MASK_19 0x00080000
-#define MASK_18 0x00040000
-#define MASK_17 0x00020000
-#define MASK_16 0x00010000
-#define MASK_15 0x00008000
-#define MASK_14 0x00004000
-#define MASK_13 0x00002000
-#define MASK_12 0x00001000
-#define MASK_11 0x00000800
-#define MASK_10 0x00000400
-#define MASK_09 0x00000200
-#define MASK_08 0x00000100
-#define MASK_07 0x00000080
-#define MASK_06 0x00000040
-#define MASK_05 0x00000020
-#define MASK_04 0x00000010
-#define MASK_03 0x00000008
-#define MASK_02 0x00000004
-#define MASK_01 0x00000002
-#define MASK_00 0x00000001
-#define MASK_B0 0x000000ff
-#define MASK_B1 0x0000ff00
-#define MASK_B2 0x00ff0000
-#define MASK_B3 0xff000000
-#define MASK_W0 0x0000ffff
-#define MASK_W1 0xffff0000
-#define MASK_PA 0xfffffffc
-#define MASK_PR 0xfffffffe
-#define MASK_ER 0xffffffff
-#define MASK_NONE 0x00000000
-
-#define SAA7146_PAGE_MAP_EN MASK_11
-/* main control register 1 */
-#define SAA7146_MC1_MRST_N MASK_15
-#define SAA7146_MC1_ERPS1 MASK_13
-#define SAA7146_MC1_ERPS0 MASK_12
-#define SAA7146_MC1_EDP MASK_11
-#define SAA7146_MC1_EVP MASK_10
-#define SAA7146_MC1_EAP MASK_09
-#define SAA7146_MC1_EI2C MASK_08
-#define SAA7146_MC1_TR_E_DEBI MASK_07
-#define SAA7146_MC1_TR_E_1 MASK_06
-#define SAA7146_MC1_TR_E_2 MASK_05
-#define SAA7146_MC1_TR_E_3 MASK_04
-#define SAA7146_MC1_TR_E_A2_OUT MASK_03
-#define SAA7146_MC1_TR_E_A2_IN MASK_02
-#define SAA7146_MC1_TR_E_A1_OUT MASK_01
-#define SAA7146_MC1_TR_E_A1_IN MASK_00
-/* main control register 2 */
-#define SAA7146_MC2_RPS_SIG4 MASK_15
-#define SAA7146_MC2_RPS_SIG3 MASK_14
-#define SAA7146_MC2_RPS_SIG2 MASK_13
-#define SAA7146_MC2_RPS_SIG1 MASK_12
-#define SAA7146_MC2_RPS_SIG0 MASK_11
-#define SAA7146_MC2_UPLD_D1_B MASK_10
-#define SAA7146_MC2_UPLD_D1_A MASK_09
-#define SAA7146_MC2_UPLD_BRS MASK_08
-#define SAA7146_MC2_UPLD_HPS_H MASK_06
-#define SAA7146_MC2_UPLD_HPS_V MASK_05
-#define SAA7146_MC2_UPLD_DMA3 MASK_04
-#define SAA7146_MC2_UPLD_DMA2 MASK_03
-#define SAA7146_MC2_UPLD_DMA1 MASK_02
-#define SAA7146_MC2_UPLD_DEBI MASK_01
-#define SAA7146_MC2_UPLD_I2C MASK_00
-/* Primary Status Register and Interrupt Enable/Status Registers */
-#define SAA7146_PSR_PPEF MASK_31
-#define SAA7146_PSR_PABO MASK_30
-#define SAA7146_PSR_PPED MASK_29
-#define SAA7146_PSR_RPS_I1 MASK_28
-#define SAA7146_PSR_RPS_I0 MASK_27
-#define SAA7146_PSR_RPS_LATE1 MASK_26
-#define SAA7146_PSR_RPS_LATE0 MASK_25
-#define SAA7146_PSR_RPS_E1 MASK_24
-#define SAA7146_PSR_RPS_E0 MASK_23
-#define SAA7146_PSR_RPS_TO1 MASK_22
-#define SAA7146_PSR_RPS_TO0 MASK_21
-#define SAA7146_PSR_UPLD MASK_20
-#define SAA7146_PSR_DEBI_S MASK_19
-#define SAA7146_PSR_DEBI_E MASK_18
-#define SAA7146_PSR_I2C_S MASK_17
-#define SAA7146_PSR_I2C_E MASK_16
-#define SAA7146_PSR_A2_IN MASK_15
-#define SAA7146_PSR_A2_OUT MASK_14
-#define SAA7146_PSR_A1_IN MASK_13
-#define SAA7146_PSR_A1_OUT MASK_12
-#define SAA7146_PSR_AFOU MASK_11
-#define SAA7146_PSR_V_PE MASK_10
-#define SAA7146_PSR_VFOU MASK_09
-#define SAA7146_PSR_FIDA MASK_08
-#define SAA7146_PSR_FIDB MASK_07
-#define SAA7146_PSR_PIN3 MASK_06
-#define SAA7146_PSR_PIN2 MASK_05
-#define SAA7146_PSR_PIN1 MASK_04
-#define SAA7146_PSR_PIN0 MASK_03
-#define SAA7146_PSR_ECS MASK_02
-#define SAA7146_PSR_EC3S MASK_01
-#define SAA7146_PSR_EC0S MASK_00
-/* Secondary Status Register */
-#define SAA7146_SSR_PRQ MASK_31
-#define SAA7146_SSR_PMA MASK_30
-#define SAA7146_SSR_RPS_RE1 MASK_29
-#define SAA7146_SSR_RPS_PE1 MASK_28
-#define SAA7146_SSR_RPS_A1 MASK_27
-#define SAA7146_SSR_RPS_RE0 MASK_26
-#define SAA7146_SSR_RPS_PE0 MASK_25
-#define SAA7146_SSR_RPS_A0 MASK_24
-#define SAA7146_SSR_DEBI_TO MASK_23
-#define SAA7146_SSR_DEBI_EF MASK_22
-#define SAA7146_SSR_I2C_EA MASK_21
-#define SAA7146_SSR_I2C_EW MASK_20
-#define SAA7146_SSR_I2C_ER MASK_19
-#define SAA7146_SSR_I2C_EL MASK_18
-#define SAA7146_SSR_I2C_EF MASK_17
-#define SAA7146_SSR_V3P MASK_16
-#define SAA7146_SSR_V2P MASK_15
-#define SAA7146_SSR_V1P MASK_14
-#define SAA7146_SSR_VF3 MASK_13
-#define SAA7146_SSR_VF2 MASK_12
-#define SAA7146_SSR_VF1 MASK_11
-#define SAA7146_SSR_AF2_IN MASK_10
-#define SAA7146_SSR_AF2_OUT MASK_09
-#define SAA7146_SSR_AF1_IN MASK_08
-#define SAA7146_SSR_AF1_OUT MASK_07
-#define SAA7146_SSR_VGT MASK_05
-#define SAA7146_SSR_LNQG MASK_04
-#define SAA7146_SSR_EC5S MASK_03
-#define SAA7146_SSR_EC4S MASK_02
-#define SAA7146_SSR_EC2S MASK_01
-#define SAA7146_SSR_EC1S MASK_00
-/* I2C status register */
-#define SAA7146_I2C_ABORT MASK_07
-#define SAA7146_I2C_SPERR MASK_06
-#define SAA7146_I2C_APERR MASK_05
-#define SAA7146_I2C_DTERR MASK_04
-#define SAA7146_I2C_DRERR MASK_03
-#define SAA7146_I2C_AL MASK_02
-#define SAA7146_I2C_ERR MASK_01
-#define SAA7146_I2C_BUSY MASK_00
-/* output formats */
-#define SAA7146_YUV422 0
-#define SAA7146_RGB16 0
-#define SAA7146_YUV444 1
-#define SAA7146_RGB24 1
-#define SAA7146_ARGB32 2
-#define SAA7146_YUV411 3
-#define SAA7146_ARGB15 3
-#define SAA7146_YUV2 4
-#define SAA7146_RGAB15 4
-#define SAA7146_Y8 6
-#define SAA7146_YUV8 7
-#define SAA7146_RGB8 7
-#define SAA7146_YUV444p 8
-#define SAA7146_YUV422p 9
-#define SAA7146_YUV420p 10
-#define SAA7146_YUV1620 11
-#define SAA7146_Y1 13
-#define SAA7146_Y2 14
-#define SAA7146_YUV1 15
-#endif
diff --git a/drivers/char/saa7185.c b/drivers/char/saa7185.c
deleted file mode 100644
index c30e6353b..000000000
--- a/drivers/char/saa7185.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- saa7185 - Philips SAA7185B video encoder driver version 0.0.3
-
- Copyright (C) 1998 Dave Perks <dperks@ibm.net>
-
- 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 of the License, 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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <asm/segment.h>
-#include <linux/types.h>
-#include <linux/wrapper.h>
-
-#include <linux/videodev.h>
-#include <linux/version.h>
-#include <asm/uaccess.h>
-
-#include <linux/i2c-old.h>
-#include <linux/video_encoder.h>
-
-#define DEBUG(x) x /* Debug driver */
-
-/* ----------------------------------------------------------------------- */
-
-struct saa7185 {
- struct i2c_bus *bus;
- int addr;
- unsigned char reg[128];
-
- int norm;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
-};
-
-#define I2C_SAA7185 0x88
-
-#define I2C_DELAY 10
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7185_write(struct saa7185 *dev, unsigned char subaddr, unsigned char data)
-{
- int ack;
-
- LOCK_I2C_BUS(dev->bus);
-
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
- dev->reg[subaddr] = data;
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- return ack;
-}
-
-static int saa7185_write_block(struct saa7185 *dev, unsigned const char *data, unsigned int len)
-{
- int ack = 0;
- unsigned subaddr;
-
- while (len > 1) {
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
- len -= 2;
- while (len > 1 && *data == ++subaddr) {
- data++;
- ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
- len -= 2;
- }
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- }
- return ack;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const unsigned char init_common[] =
-{
- 0x3a, 0x0f, /* CBENB=0, V656=0, VY2C=1, YUV2C=1, MY2C=1, MUV2C=1 */
-
- 0x42, 0x6b, /* OVLY0=107 */
- 0x43, 0x00, /* OVLU0=0 white */
- 0x44, 0x00, /* OVLV0=0 */
- 0x45, 0x22, /* OVLY1=34 */
- 0x46, 0xac, /* OVLU1=172 yellow */
- 0x47, 0x0e, /* OVLV1=14 */
- 0x48, 0x03, /* OVLY2=3 */
- 0x49, 0x1d, /* OVLU2=29 cyan */
- 0x4a, 0xac, /* OVLV2=172 */
- 0x4b, 0xf0, /* OVLY3=240 */
- 0x4c, 0xc8, /* OVLU3=200 green */
- 0x4d, 0xb9, /* OVLV3=185 */
- 0x4e, 0xd4, /* OVLY4=212 */
- 0x4f, 0x38, /* OVLU4=56 magenta */
- 0x50, 0x47, /* OVLV4=71 */
- 0x51, 0xc1, /* OVLY5=193 */
- 0x52, 0xe3, /* OVLU5=227 red */
- 0x53, 0x54, /* OVLV5=84 */
- 0x54, 0xa3, /* OVLY6=163 */
- 0x55, 0x54, /* OVLU6=84 blue */
- 0x56, 0xf2, /* OVLV6=242 */
- 0x57, 0x90, /* OVLY7=144 */
- 0x58, 0x00, /* OVLU7=0 black */
- 0x59, 0x00, /* OVLV7=0 */
-
- 0x5a, 0x00, /* CHPS=0 */
- 0x5b, 0x76, /* GAINU=118 */
- 0x5c, 0xa5, /* GAINV=165 */
- 0x5d, 0x3c, /* BLCKL=60 */
- 0x5e, 0x3a, /* BLNNL=58 */
- 0x5f, 0x3a, /* CCRS=0, BLNVB=58 */
- 0x60, 0x00, /* NULL */
-
-/* 0x61 - 0x66 set according to norm */
-
- 0x67, 0x00, /* 0 : caption 1st byte odd field */
- 0x68, 0x00, /* 0 : caption 2nd byte odd field */
- 0x69, 0x00, /* 0 : caption 1st byte even field */
- 0x6a, 0x00, /* 0 : caption 2nd byte even field */
-
- 0x6b, 0x91, /* MODIN=2, PCREF=0, SCCLN=17 */
- 0x6c, 0x20, /* SRCV1=0, TRCV2=1, ORCV1=0, PRCV1=0, CBLF=0, ORCV2=0, PRCV2=0 */
- 0x6d, 0x00, /* SRCM1=0, CCEN=0 */
-
- 0x6e, 0x0e, /* HTRIG=0x00e, approx. centered, at least for PAL */
- 0x6f, 0x00, /* HTRIG upper bits */
- 0x70, 0x20, /* PHRES=0, SBLN=1, VTRIG=0 */
-
-/* The following should not be needed */
-
- 0x71, 0x15, /* BMRQ=0x115 */
- 0x72, 0x90, /* EMRQ=0x690 */
- 0x73, 0x61, /* EMRQ=0x690, BMRQ=0x115 */
- 0x74, 0x00, /* NULL */
- 0x75, 0x00, /* NULL */
- 0x76, 0x00, /* NULL */
- 0x77, 0x15, /* BRCV=0x115 */
- 0x78, 0x90, /* ERCV=0x690 */
- 0x79, 0x61, /* ERCV=0x690, BRCV=0x115 */
-
-/* Field length controls */
-
- 0x7a, 0x70, /* FLC=0 */
-
-/* The following should not be needed if SBLN = 1 */
-
- 0x7b, 0x16, /* FAL=22 */
- 0x7c, 0x35, /* LAL=244 */
- 0x7d, 0x20, /* LAL=244, FAL=22 */
-};
-
-static const unsigned char init_pal[] =
-{
- 0x61, 0x1e, /* FISE=0, PAL=1, SCBW=1, RTCE=1, YGS=1, INPI=0, DOWN=0 */
- 0x62, 0xc8, /* DECTYP=1, BSTA=72 */
- 0x63, 0xcb, /* FSC0 */
- 0x64, 0x8a, /* FSC1 */
- 0x65, 0x09, /* FSC2 */
- 0x66, 0x2a, /* FSC3 */
-};
-
-static const unsigned char init_ntsc[] =
-{
- 0x61, 0x1d, /* FISE=1, PAL=0, SCBW=1, RTCE=1, YGS=1, INPI=0, DOWN=0 */
- 0x62, 0xe6, /* DECTYP=1, BSTA=102 */
- 0x63, 0x1f, /* FSC0 */
- 0x64, 0x7c, /* FSC1 */
- 0x65, 0xf0, /* FSC2 */
- 0x66, 0x21, /* FSC3 */
-};
-
-static int saa7185_attach(struct i2c_device *device)
-{
- int i;
- struct saa7185 *encoder;
-
- device->data = encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL);
- if (encoder == NULL) {
- return -ENOMEM;
- }
- MOD_INC_USE_COUNT;
-
- memset(encoder, 0, sizeof(struct saa7185));
- strcpy(device->name, "saa7185");
- encoder->bus = device->bus;
- encoder->addr = device->addr;
- encoder->norm = VIDEO_MODE_NTSC;
- encoder->enable = 1;
-
- i = saa7185_write_block(encoder, init_common, sizeof(init_common));
- if (i >= 0) {
- i = saa7185_write_block(encoder, init_ntsc, sizeof(init_ntsc));
- }
- if (i < 0) {
- printk(KERN_ERR "%s_attach: init error %d\n", device->name, i);
- }
- return 0;
-}
-
-
-static int saa7185_detach(struct i2c_device *device)
-{
- kfree(device->data);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int saa7185_command(struct i2c_device *device, unsigned int cmd, void *arg)
-{
- struct saa7185 *encoder = device->data;
-
- switch (cmd) {
-
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
-
- cap->flags
- = VIDEO_ENCODER_PAL
- | VIDEO_ENCODER_NTSC
- | VIDEO_ENCODER_SECAM
- | VIDEO_ENCODER_CCIR;
- cap->inputs = 1;
- cap->outputs = 1;
- }
- break;
-
- case ENCODER_SET_NORM:
- {
- int *iarg = arg;
-
- switch (*iarg) {
-
- case VIDEO_MODE_NTSC:
- saa7185_write_block(encoder, init_ntsc, sizeof(init_ntsc));
- break;
-
- case VIDEO_MODE_PAL:
- saa7185_write_block(encoder, init_pal, sizeof(init_pal));
- break;
-
- case VIDEO_MODE_SECAM:
- default:
- return -EINVAL;
-
- }
- encoder->norm = *iarg;
- }
- break;
-
- case ENCODER_SET_INPUT:
- {
- int *iarg = arg;
-
-#if 0
- /* not much choice of inputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
-#else
- /* RJ: *iarg = 0: input is from SA7111
- *iarg = 1: input is from ZR36060 */
-
- switch (*iarg) {
-
- case 0:
- /* Switch RTCE to 1 */
- saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
- break;
-
- case 1:
- /* Switch RTCE to 0 */
- saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
- break;
-
- default:
- return -EINVAL;
-
- }
-#endif
- }
- break;
-
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
- }
- break;
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
-
- encoder->enable = !!*iarg;
- saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xbf) | (encoder->enable ? 0x00 : 0x40));
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct i2c_driver i2c_driver_saa7185 =
-{
- "saa7185", /* name */
- I2C_DRIVERID_VIDEOENCODER, /* ID */
- I2C_SAA7185, I2C_SAA7185 + 1,
-
- saa7185_attach,
- saa7185_detach,
- saa7185_command
-};
-
-EXPORT_NO_SYMBOLS;
-
-#ifdef MODULE
-int init_module(void)
-#else
-int saa7185_init(void)
-#endif
-{
- return i2c_register_driver(&i2c_driver_saa7185);
-}
-
-
-
-#ifdef MODULE
-
-void cleanup_module(void)
-{
- i2c_unregister_driver(&i2c_driver_saa7185);
-}
-
-#endif
diff --git a/drivers/char/saa7196.h b/drivers/char/saa7196.h
deleted file mode 100644
index f92f21cfb..000000000
--- a/drivers/char/saa7196.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- Definitions for the Philips SAA7196 digital video decoder,
- scaler, and clock generator circuit (DESCpro), as used in
- the PlanB video input of the Powermac 7x00/8x00 series.
-
- Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
- The register defines are shamelessly copied from the meteor
- driver out of NetBSD (with permission),
- and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe
- (Thanks !)
-
- Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu)
-
- The default values used for PlanB are my mistakes.
-*/
-
-/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */
-
-#ifndef _SAA7196_H_
-#define _SAA7196_H_
-
-#define SAA7196_NUMREGS 0x31 /* Number of registers (used)*/
-#define NUM_SUPPORTED_NORM 3 /* Number of supported norms by PlanB */
-
-/* Decoder part: */
-#define SAA7196_IDEL 0x00 /* Increment delay */
-#define SAA7196_HSB5 0x01 /* H-sync begin; 50 hz */
-#define SAA7196_HSS5 0x02 /* H-sync stop; 50 hz */
-#define SAA7196_HCB5 0x03 /* H-clamp begin; 50 hz */
-#define SAA7196_HCS5 0x04 /* H-clamp stop; 50 hz */
-#define SAA7196_HSP5 0x05 /* H-sync after PHI1; 50 hz */
-#define SAA7196_LUMC 0x06 /* Luminance control */
-#define SAA7196_HUEC 0x07 /* Hue control */
-#define SAA7196_CKTQ 0x08 /* Colour Killer Threshold QAM (PAL, NTSC) */
-#define SAA7196_CKTS 0x09 /* Colour Killer Threshold SECAM */
-#define SAA7196_PALS 0x0a /* PAL switch sensitivity */
-#define SAA7196_SECAMS 0x0b /* SECAM switch sensitivity */
-#define SAA7196_CGAINC 0x0c /* Chroma gain control */
-#define SAA7196_STDC 0x0d /* Standard/Mode control */
-#define SAA7196_IOCC 0x0e /* I/O and Clock Control */
-#define SAA7196_CTRL1 0x0f /* Control #1 */
-#define SAA7196_CTRL2 0x10 /* Control #2 */
-#define SAA7196_CGAINR 0x11 /* Chroma Gain Reference */
-#define SAA7196_CSAT 0x12 /* Chroma Saturation */
-#define SAA7196_CONT 0x13 /* Luminance Contrast */
-#define SAA7196_HSB6 0x14 /* H-sync begin; 60 hz */
-#define SAA7196_HSS6 0x15 /* H-sync stop; 60 hz */
-#define SAA7196_HCB6 0x16 /* H-clamp begin; 60 hz */
-#define SAA7196_HCS6 0x17 /* H-clamp stop; 60 hz */
-#define SAA7196_HSP6 0x18 /* H-sync after PHI1; 60 hz */
-#define SAA7196_BRIG 0x19 /* Luminance Brightness */
-
-/* Scaler part: */
-#define SAA7196_FMTS 0x20 /* Formats and sequence */
-#define SAA7196_OUTPIX 0x21 /* Output data pixel/line */
-#define SAA7196_INPIX 0x22 /* Input data pixel/line */
-#define SAA7196_HWS 0x23 /* Horiz. window start */
-#define SAA7196_HFILT 0x24 /* Horiz. filter */
-#define SAA7196_OUTLINE 0x25 /* Output data lines/field */
-#define SAA7196_INLINE 0x26 /* Input data lines/field */
-#define SAA7196_VWS 0x27 /* Vertical window start */
-#define SAA7196_VYP 0x28 /* AFS/vertical Y processing */
-#define SAA7196_VBS 0x29 /* Vertical Bypass start */
-#define SAA7196_VBCNT 0x2a /* Vertical Bypass count */
-#define SAA7196_VBP 0x2b /* veritcal Bypass Polarity */
-#define SAA7196_VLOW 0x2c /* Colour-keying lower V limit */
-#define SAA7196_VHIGH 0x2d /* Colour-keying upper V limit */
-#define SAA7196_ULOW 0x2e /* Colour-keying lower U limit */
-#define SAA7196_UHIGH 0x2f /* Colour-keying upper U limit */
-#define SAA7196_DPATH 0x30 /* Data path setting */
-
-/* Initialization default values: */
-
-unsigned char saa_regs[NUM_SUPPORTED_NORM][SAA7196_NUMREGS] = {
-
-/* PAL, 768x576 (no scaling), composite video-in */
-/* Decoder: */
- { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
- 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x06, 0x3b, 0x98,
- 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
- 0xe9, 0xa2,
-/* Padding */
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
- 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
- 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
- 0x87 },
-
-/* NTSC, 640x480? (no scaling), composite video-in */
-/* Decoder: */
- { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x50, 0x00,
- 0xf8, 0xf0, 0xfe, 0xe0, 0x00, 0x06, 0x3b, 0x98,
- 0x00, 0x2c, 0x3d, 0x40, 0x34, 0x0a, 0xf4, 0xd2,
- 0xe9, 0x98,
-/* Padding */
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
- 0x72, 0x80, 0x80, 0x03, 0x89, 0xf0, 0xf0, 0x0d,
- 0xa0, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
- 0x87 },
-
-/* SECAM, 768x576 (no scaling), composite video-in */
-/* Decoder: */
- { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
- 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x07, 0x3b, 0x98,
- 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
- 0xe9, 0xa2,
-/* Padding */
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
- 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
- 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
- 0x87 }
- };
-
-#endif /* _SAA7196_H_ */
diff --git a/drivers/char/scan_keyb.c b/drivers/char/scan_keyb.c
index 1936e0b6e..f2435e9ec 100644
--- a/drivers/char/scan_keyb.c
+++ b/drivers/char/scan_keyb.c
@@ -82,18 +82,21 @@ int register_scan_keyboard(void (*scan)(unsigned char *buffer),
{
struct scan_keyboard *kbd;
- if((kbd=kmalloc(sizeof(struct scan_keyboard), GFP_KERNEL))==NULL)
+ kbd = kmalloc(sizeof(struct scan_keyboard), GFP_KERNEL);
+ if (kbd == NULL)
goto error_out;
kbd->scan=scan;
kbd->table=table;
kbd->length=length;
- kbd->s0=kbd->s1=NULL;
- if((kbd->s0=kmalloc(length, GFP_KERNEL))==NULL)
- goto error_mem_free;
- if((kbd->s1=kmalloc(length, GFP_KERNEL))==NULL)
- goto error_mem_free;
+ kbd->s0 = kmalloc(length, GFP_KERNEL);
+ if (kbd->s0 == NULL)
+ goto error_free_kbd;
+
+ kbd->s1 = kmalloc(length, GFP_KERNEL);
+ if (kbd->s1 == NULL)
+ goto error_free_s0;
kbd->scan(kbd->s0);
kbd->scan(kbd->s1);
@@ -103,11 +106,10 @@ int register_scan_keyboard(void (*scan)(unsigned char *buffer),
return 0;
- error_mem_free:
- if(kbd->s0)
- kfree(kbd->s0);
- if(kbd->s1)
- kfree(kbd->s1);
+ error_free_s0:
+ kfree(kbd->s0);
+
+ error_free_kbd:
kfree(kbd);
error_out:
diff --git a/drivers/char/serial.c b/drivers/char/serial.c
index 8ec857e06..f23f911ad 100644
--- a/drivers/char/serial.c
+++ b/drivers/char/serial.c
@@ -51,13 +51,16 @@
*
* 7/00: Support Timedia/Sunix/Exsys PCI cards
*
+ * 7/00: fix some returns on failure not using MOD_DEC_USE_COUNT.
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
* This module exports the following rs232 io functions:
*
* int rs_init(void);
*/
-static char *serial_version = "5.01";
-static char *serial_revdate = "2000-05-29";
+static char *serial_version = "5.02";
+static char *serial_revdate = "2000-08-09";
/*
* Serial driver configuration section. Here are the various options:
@@ -142,6 +145,10 @@ static char *serial_revdate = "2000-05-29";
#endif
#endif
+#ifdef MODULE
+#undef CONFIG_SERIAL_CONSOLE
+#endif
+
#define CONFIG_SERIAL_RSA
#define RS_STROBE_TIME (10*HZ)
@@ -260,8 +267,9 @@ static struct rs_multiport_struct rs_multiport[NR_IRQS];
static int IRQ_timeout[NR_IRQS];
#ifdef CONFIG_SERIAL_CONSOLE
static struct console sercons;
+static int lsr_break_flag = 0;
#endif
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
static unsigned long break_pressed; /* break, really ... */
#endif
@@ -281,7 +289,7 @@ static struct serial_uart_config uart_config[] = {
{ "16550", 1, 0 },
{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
{ "cirrus", 1, 0 }, /* usurped by cyclades.c */
- { "ST16650", 1, UART_CLEAR_FIFO |UART_STARTECH },
+ { "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
UART_STARTECH },
{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
@@ -302,7 +310,9 @@ static int probe_rsa[PORT_RSA_MAX];
static int force_rsa[PORT_RSA_MAX];
MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
#endif /* CONFIG_SERIAL_RSA */
static struct serial_state rs_table[RS_TABLE_SIZE] = {
@@ -313,7 +323,7 @@ static struct serial_state rs_table[RS_TABLE_SIZE] = {
#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP))
#define NR_PCI_BOARDS 8
-/* We don't unregister PCI boards right now */
+
static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS];
static int serial_pci_board_idx = 0;
@@ -573,6 +583,23 @@ static _INLINE_ void receive_chars(struct async_struct *info,
if (*status & UART_LSR_BI) {
*status &= ~(UART_LSR_FE | UART_LSR_PE);
icount->brk++;
+ /*
+ * We do the SysRQ and SAK checking
+ * here because otherwise the break
+ * may get masked by ignore_status_mask
+ * or read_status_mask.
+ */
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+ if (info->line == sercons.index) {
+ if (!break_pressed) {
+ break_pressed = jiffies;
+ goto ignore_char;
+ }
+ break_pressed = 0;
+ }
+#endif
+ if (info->flags & ASYNC_SAK)
+ do_SAK(tty);
} else if (*status & UART_LSR_PE)
icount->parity++;
else if (*status & UART_LSR_FE)
@@ -591,23 +618,19 @@ static _INLINE_ void receive_chars(struct async_struct *info,
goto ignore_char;
}
*status &= info->read_status_mask;
-
+
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (info->line == sercons.index) {
+ /* Recover the break flag from console xmit */
+ *status |= lsr_break_flag;
+ lsr_break_flag = 0;
+ }
+#endif
if (*status & (UART_LSR_BI)) {
#ifdef SERIAL_DEBUG_INTR
printk("handling break....");
#endif
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
- if (info->line == sercons.index) {
- if (!break_pressed) {
- break_pressed = jiffies;
- goto ignore_char;
- }
- break_pressed = 0;
- }
-#endif
*tty->flip.flag_buf_ptr = TTY_BREAK;
- if (info->flags & ASYNC_SAK)
- do_SAK(tty);
} else if (*status & UART_LSR_PE)
*tty->flip.flag_buf_ptr = TTY_PARITY;
else if (*status & UART_LSR_FE)
@@ -626,7 +649,7 @@ static _INLINE_ void receive_chars(struct async_struct *info,
goto ignore_char;
}
}
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
if (break_pressed && info->line == sercons.index) {
if (ch != 0 &&
time_before(jiffies, break_pressed + HZ*5)) {
@@ -1068,19 +1091,15 @@ static void rs_timer(unsigned long dummy)
mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
if (IRQ_ports[0]) {
- unsigned long next;
save_flags(flags); cli();
#ifdef CONFIG_SERIAL_SHARE_IRQ
rs_interrupt(0, NULL, NULL);
#else
rs_interrupt_single(0, NULL, NULL);
#endif
-
- next = jiffies + IRQ_timeout[0] - 2;
- if (next < jiffies + 1)
- next = jiffies + 1;
- mod_timer(&serial_timer, next);
restore_flags(flags);
+
+ mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
}
}
@@ -1115,7 +1134,7 @@ static void figure_IRQ_timeout(int irq)
}
if (!irq)
timeout = timeout / 2;
- IRQ_timeout[irq] = timeout ? timeout : 1;
+ IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
}
#ifdef CONFIG_SERIAL_RSA
@@ -2081,7 +2100,7 @@ static int set_serial_info(struct async_struct * info,
new_serial.irq = irq_cannonicalize(new_serial.irq);
- if ((new_serial.irq >= NR_IRQS) ||
+ if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
(new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
(new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
(new_serial.type == PORT_STARTECH)) {
@@ -2314,7 +2333,7 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
static int do_autoconfig(struct async_struct * info)
{
- int retval;
+ int irq, retval;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -2327,8 +2346,11 @@ static int do_autoconfig(struct async_struct * info)
autoconfig(info->state);
if ((info->state->flags & ASYNC_AUTO_IRQ) &&
(info->state->port != 0) &&
- (info->state->type != PORT_UNKNOWN))
- info->state->irq = detect_uart_irq(info->state);
+ (info->state->type != PORT_UNKNOWN)) {
+ irq = detect_uart_irq(info->state);
+ if (irq > 0)
+ info->state->irq = irq;
+ }
retval = startup(info);
if (retval)
@@ -3115,8 +3137,10 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
}
tty->driver_data = info;
info->tty = tty;
- if (serial_paranoia_check(info, tty->device, "rs_open"))
+ if (serial_paranoia_check(info, tty->device, "rs_open")) {
+ MOD_DEC_USE_COUNT;
return -ENODEV;
+ }
#ifdef SERIAL_DEBUG_OPEN
printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
@@ -3129,6 +3153,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
if (!tmp_buf) {
page = get_zeroed_page(GFP_KERNEL);
if (!page) {
+ MOD_DEC_USE_COUNT;
return -ENOMEM;
}
if (tmp_buf)
@@ -3144,6 +3169,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
(info->flags & ASYNC_CLOSING)) {
if (info->flags & ASYNC_CLOSING)
interruptible_sleep_on(&info->close_wait);
+ MOD_DEC_USE_COUNT;
#ifdef SERIAL_DO_RESTART
return ((info->flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS);
@@ -3157,6 +3183,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
*/
retval = startup(info);
if (retval) {
+ MOD_DEC_USE_COUNT;
return retval;
}
@@ -3166,6 +3193,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
printk("rs_open returning after block_til_ready with %d\n",
retval);
#endif
+ MOD_DEC_USE_COUNT;
return retval;
}
@@ -3490,6 +3518,7 @@ static void autoconfig_startech_uarts(struct async_struct *info,
* (Exoray@isys.ca) claims that it's needed for 952
* dual UART's (which are not recommended for new designs).
*/
+ info->ACR = 0;
serial_out(info, UART_LCR, 0xBF);
serial_out(info, UART_EFR, 0x10);
serial_out(info, UART_LCR, 0x00);
@@ -3808,10 +3837,11 @@ static _INLINE_ int get_pci_port(struct pci_dev *dev,
if (idx >= max_port)
return 1;
}
-
+
offset = board->first_uart_offset;
/* Timedia/SUNIX uses a mixture of BARs and offsets */
+ /* Ugh, this is ugly as all hell --- TYT */
if(dev->vendor == PCI_VENDOR_ID_TIMEDIA ) /* 0x1409 */
switch(idx) {
case 0: base_idx=0;
@@ -4094,6 +4124,62 @@ pci_inteli960ni_fn(struct pci_dev *dev,
return(0);
}
+/*
+ * Timedia has an explosion of boards, and to avoid the PCI table from
+ * growing *huge*, we use this function to collapse some 70 entries
+ * in the PCI table into one, for sanity's and compactness's sake.
+ */
+static unsigned short timedia_single_port[] = {
+ 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 };
+static unsigned short timedia_dual_port[] = {
+ 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
+ 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
+ 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
+ 0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
+ 0xD079, 0 };
+static unsigned short timedia_quad_port[] = {
+ 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
+ 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
+ 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
+ 0xB157, 0 };
+static unsigned short timedia_eight_port[] = {
+ 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
+ 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 };
+static struct timedia_struct {
+ int num;
+ unsigned short *ids;
+} timedia_data[] = {
+ { 1, timedia_single_port },
+ { 2, timedia_dual_port },
+ { 4, timedia_quad_port },
+ { 8, timedia_eight_port },
+ { 0, 0 }
+};
+
+static int
+#ifndef MODULE
+__init
+#endif
+pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+ int i, j;
+ unsigned short *ids;
+
+ if (!enable)
+ return 0;
+
+ for (i=0; timedia_data[i].num; i++) {
+ ids = timedia_data[i].ids;
+ for (j=0; ids[j]; j++) {
+ if (pci_get_subvendor(dev) == ids[j]) {
+ board->num_ports = timedia_data[i].num;
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
/*
* This is the configuration table for all of the PCI serial boards
@@ -4120,58 +4206,50 @@ static struct pci_board pci_boards[] __initdata = {
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232,
SPCI_FL_BASE1, 2, 1382400 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232,
SPCI_FL_BASE1, 8, 1382400 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232,
SPCI_FL_BASE1, 4, 1382400 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232,
SPCI_FL_BASE1, 2, 1382400 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485,
SPCI_FL_BASE1, 8, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4,
SPCI_FL_BASE1, 8, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485,
SPCI_FL_BASE1, 4, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2,
SPCI_FL_BASE1, 4, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485,
SPCI_FL_BASE1, 2, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
- PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6,
SPCI_FL_BASE1, 8, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
- PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1,
SPCI_FL_BASE1, 8, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
PCI_SUBVENDOR_ID_CONNECT_TECH,
- PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1,
SPCI_FL_BASE1, 4, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
- PCI_SUBVENDOR_ID_CONNECT_TECH,
- PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2,
- SPCI_FL_BASE1, 4, 921600 },
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960V2,
- PCI_SUBVENDOR_ID_CONNECT_TECH,
- PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485,
- SPCI_FL_BASE1, 2, 921600 },
{ PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200 },
@@ -4200,6 +4278,9 @@ static struct pci_board pci_boards[] __initdata = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE2, 8, 921600 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2, 4, 921600 },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_KEYSPAN,
PCI_SUBDEVICE_ID_KEYSPAN_SX2,
@@ -4269,75 +4350,10 @@ static struct pci_board pci_boards[] __initdata = {
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 },
- /* PCI_VENDOR_ID_TIMEDIA/Sunix, PCI_DEVICE_ID_TIMEDIA_1889, */
- { 0x1409, 0x7168, 0x1409, 0x0002, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4036A*/
- { 0x1409, 0x7168, 0x1409, 0x4025, SPCI_FL_BASE_TABLE, 1, 921600 }, /*4025A*/
- { 0x1409, 0x7168, 0x1409, 0x4027, SPCI_FL_BASE_TABLE, 1, 921600 }, /*4027A*/
- { 0x1409, 0x7168, 0x1409, 0x4028, SPCI_FL_BASE_TABLE, 1, 921600 }, /*4028D*/
- { 0x1409, 0x7168, 0x1409, 0x4036, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4036D*/
- { 0x1409, 0x7168, 0x1409, 0x4037, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4037A*/
- { 0x1409, 0x7168, 0x1409, 0x4038, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4038D*/
- { 0x1409, 0x7168, 0x1409, 0x4055, SPCI_FL_BASE_TABLE, 4, 921600 }, /*4055A*/
- { 0x1409, 0x7168, 0x1409, 0x4056, SPCI_FL_BASE_TABLE, 4, 921600 }, /*4056A*/
- { 0x1409, 0x7168, 0x1409, 0x4065, SPCI_FL_BASE_TABLE, 8, 921600 }, /*4065A*/
- { 0x1409, 0x7168, 0x1409, 0x4066, SPCI_FL_BASE_TABLE, 8, 921600 }, /*4066A*/
- { 0x1409, 0x7168, 0x1409, 0x4078, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4078A*/
- { 0x1409, 0x7168, 0x1409, 0x4079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4079H*/
- { 0x1409, 0x7168, 0x1409, 0x4085, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4085H*/
- { 0x1409, 0x7168, 0x1409, 0x4088, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4088A*/
- { 0x1409, 0x7168, 0x1409, 0x4089, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4089A*/
- { 0x1409, 0x7168, 0x1409, 0x4095, SPCI_FL_BASE_TABLE, 4, 921600 }, /*4095A*/
- { 0x1409, 0x7168, 0x1409, 0x4096, SPCI_FL_BASE_TABLE, 4, 921600 }, /*4096A*/
- { 0x1409, 0x7168, 0x1409, 0x5025, SPCI_FL_BASE_TABLE, 1, 921600 }, /*4025D*/
- { 0x1409, 0x7168, 0x1409, 0x5027, SPCI_FL_BASE_TABLE, 1, 921600 }, /*4027D*/
- { 0x1409, 0x7168, 0x1409, 0x5037, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4037D*/
- { 0x1409, 0x7168, 0x1409, 0x5056, SPCI_FL_BASE_TABLE, 4, 921600 }, /*4056R*/
- { 0x1409, 0x7168, 0x1409, 0x5065, SPCI_FL_BASE_TABLE, 8, 921600 }, /*4065R*/
- { 0x1409, 0x7168, 0x1409, 0x5066, SPCI_FL_BASE_TABLE, 8, 921600 }, /*4066R*/
- { 0x1409, 0x7168, 0x1409, 0x5078, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4078U*/
- { 0x1409, 0x7168, 0x1409, 0x5079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4079A*/
- { 0x1409, 0x7168, 0x1409, 0x5085, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4085U*/
- { 0x1409, 0x7168, 0x1409, 0x6079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4079R*/
- { 0x1409, 0x7168, 0x1409, 0x7079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4079S*/
- { 0x1409, 0x7168, 0x1409, 0x8079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4079D*/
- { 0x1409, 0x7168, 0x1409, 0x8137, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8137*/
- { 0x1409, 0x7168, 0x1409, 0x8138, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8138*/
- { 0x1409, 0x7168, 0x1409, 0x8156, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8156*/
- { 0x1409, 0x7168, 0x1409, 0x8157, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8157*/
- { 0x1409, 0x7168, 0x1409, 0x8166, SPCI_FL_BASE_TABLE, 8, 921600 }, /*8166*/
- { 0x1409, 0x7168, 0x1409, 0x8237, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8237*/
- { 0x1409, 0x7168, 0x1409, 0x8238, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8238*/
- { 0x1409, 0x7168, 0x1409, 0x8256, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8256*/
- { 0x1409, 0x7168, 0x1409, 0x8257, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8257*/
- { 0x1409, 0x7168, 0x1409, 0x9056, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9056A*/
- { 0x1409, 0x7168, 0x1409, 0x9066, SPCI_FL_BASE_TABLE, 8, 921600 }, /*9066A*/
- { 0x1409, 0x7168, 0x1409, 0x9079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4079E*/
- { 0x1409, 0x7168, 0x1409, 0x9137, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8137S*/
- { 0x1409, 0x7168, 0x1409, 0x9138, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8138S*/
- { 0x1409, 0x7168, 0x1409, 0x9156, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8156S*/
- { 0x1409, 0x7168, 0x1409, 0x9157, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8157S*/
- { 0x1409, 0x7168, 0x1409, 0x9158, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9158*/
- { 0x1409, 0x7168, 0x1409, 0x9159, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9159*/
- { 0x1409, 0x7168, 0x1409, 0x9166, SPCI_FL_BASE_TABLE, 8, 921600 }, /*8166S*/
- { 0x1409, 0x7168, 0x1409, 0x9167, SPCI_FL_BASE_TABLE, 8, 921600 }, /*9167*/
- { 0x1409, 0x7168, 0x1409, 0x9168, SPCI_FL_BASE_TABLE, 8, 921600 }, /*9168*/
- { 0x1409, 0x7168, 0x1409, 0x9237, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8237S*/
- { 0x1409, 0x7168, 0x1409, 0x9238, SPCI_FL_BASE_TABLE, 2, 921600 }, /*8238S*/
- { 0x1409, 0x7168, 0x1409, 0x9256, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8256S*/
- { 0x1409, 0x7168, 0x1409, 0x9257, SPCI_FL_BASE_TABLE, 4, 921600 }, /*8257S*/
- { 0x1409, 0x7168, 0x1409, 0xA056, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9056B*/
- { 0x1409, 0x7168, 0x1409, 0xA066, SPCI_FL_BASE_TABLE, 8, 921600 }, /*9066B*/
- { 0x1409, 0x7168, 0x1409, 0xA079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*4079F*/
- { 0x1409, 0x7168, 0x1409, 0xA157, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9157*/
- { 0x1409, 0x7168, 0x1409, 0xA158, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9158S*/
- { 0x1409, 0x7168, 0x1409, 0xA159, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9159S*/
- { 0x1409, 0x7168, 0x1409, 0xA167, SPCI_FL_BASE_TABLE, 8, 921600 }, /*9167S*/
- { 0x1409, 0x7168, 0x1409, 0xA168, SPCI_FL_BASE_TABLE, 8, 921600 }, /*9168S*/
- { 0x1409, 0x7168, 0x1409, 0xB056, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9056C*/
- { 0x1409, 0x7168, 0x1409, 0xB079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*9079A*/
- { 0x1409, 0x7168, 0x1409, 0xB157, SPCI_FL_BASE_TABLE, 4, 921600 }, /*9157S*/
- { 0x1409, 0x7168, 0x1409, 0xC079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*9079B*/
- { 0x1409, 0x7168, 0x1409, 0xD079, SPCI_FL_BASE_TABLE, 2, 921600 }, /*9079C*/
+ { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
+ PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID,
+ SPCI_FL_BASE_TABLE, 1, 921600,
+ 0, 0, pci_timedia_fn },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
@@ -4544,7 +4560,7 @@ static struct pci_board pci_boards[] __initdata = {
{ PCI_VENDOR_ID_ROCKWELL, 0x1004,
0x1048, 0x1500,
SPCI_FL_BASE1, 1, 115200 },
-#ifdef CONFIG_DDB5074
+#if CONFIG_DDB5074
/*
* NEC Vrc-5074 (Nile 4) builtin UART.
* Conditionally compiled in since this is a motherboard device.
@@ -4584,7 +4600,7 @@ static int _INLINE_ serial_pci_guess_board(struct pci_dev *dev,
for (i=0; i < 6; i++) {
if (IS_PCI_REGION_IOPORT(dev, i)) {
- num_port = 0;
+ num_port++;
if (first_port == -1)
first_port = i;
} else {
@@ -5081,16 +5097,6 @@ static int __init rs_init(void)
int i;
struct serial_state * state;
- if (serial_timer.function) {
- printk("RS_TIMER already set, another serial driver "
- "already loaded?\n");
-#ifdef MODULE
- printk("Can't load serial driver module over built-in "
- "serial driver\n");
-#endif
- return -EBUSY;
- }
-
init_bh(SERIAL_BH, do_serial_bh);
init_timer(&serial_timer);
serial_timer.function = rs_timer;
@@ -5423,6 +5429,8 @@ static void __exit rs_fini(void)
module_init(rs_init);
module_exit(rs_fini);
+MODULE_DESCRIPTION("Standard/generic (dumb) serial driver");
+MODULE_AUTHOR("Theodore Ts'o <tytso@mit.edu>");
/*
@@ -5441,10 +5449,17 @@ static struct async_struct async_sercons;
*/
static inline void wait_for_xmitr(struct async_struct *info)
{
- unsigned int tmout = 1000000;
+ unsigned int status, tmout = 1000000;
+
+ do {
+ status = serial_in(info, UART_LSR);
- while (--tmout &&
- ((serial_in(info, UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY));
+ if (status & UART_LSR_BI)
+ lsr_break_flag = UART_LSR_BI;
+
+ if (--tmout == 0)
+ break;
+ } while((status & BOTH_EMPTY) != BOTH_EMPTY);
}
diff --git a/drivers/char/serial_21285.c b/drivers/char/serial_21285.c
new file mode 100644
index 000000000..575cf0bc0
--- /dev/null
+++ b/drivers/char/serial_21285.c
@@ -0,0 +1,511 @@
+/*
+ * linux/drivers/char/serial_21285.c
+ *
+ * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
+ *
+ * Based on drivers/char/serial.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/dec21285.h>
+#include <asm/hardware.h>
+
+#define BAUD_BASE (mem_fclk_21285/64)
+
+#define SERIAL_21285_NAME "ttyFB"
+#define SERIAL_21285_MAJOR 204
+#define SERIAL_21285_MINOR 4
+
+#define SERIAL_21285_AUXNAME "cuafb"
+#define SERIAL_21285_AUXMAJOR 205
+#define SERIAL_21285_AUXMINOR 4
+
+static struct tty_driver rs285_driver, callout_driver;
+static int rs285_refcount;
+static struct tty_struct *rs285_table[1];
+
+static struct termios *rs285_termios[1];
+static struct termios *rs285_termios_locked[1];
+
+static char wbuf[1000], *putp = wbuf, *getp = wbuf, x_char;
+static struct tty_struct *rs285_tty;
+static int rs285_use_count;
+
+static int rs285_write_room(struct tty_struct *tty)
+{
+ return putp >= getp ? (sizeof(wbuf) - (long) putp + (long) getp) : ((long) getp - (long) putp - 1);
+}
+
+static void rs285_rx_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+ if (!rs285_tty) {
+ disable_irq(IRQ_CONRX);
+ return;
+ }
+ while (!(*CSR_UARTFLG & 0x10)) {
+ int ch, flag;
+ ch = *CSR_UARTDR;
+ flag = *CSR_RXSTAT;
+ if (flag & 4)
+ tty_insert_flip_char(rs285_tty, 0, TTY_OVERRUN);
+ if (flag & 2)
+ flag = TTY_PARITY;
+ else if (flag & 1)
+ flag = TTY_FRAME;
+ tty_insert_flip_char(rs285_tty, ch, flag);
+ }
+ tty_flip_buffer_push(rs285_tty);
+}
+
+static void rs285_send_xchar(struct tty_struct *tty, char ch)
+{
+ x_char = ch;
+ enable_irq(IRQ_CONTX);
+}
+
+static void rs285_throttle(struct tty_struct *tty)
+{
+ if (I_IXOFF(tty))
+ rs285_send_xchar(tty, STOP_CHAR(tty));
+}
+
+static void rs285_unthrottle(struct tty_struct *tty)
+{
+ if (I_IXOFF(tty)) {
+ if (x_char)
+ x_char = 0;
+ else
+ rs285_send_xchar(tty, START_CHAR(tty));
+ }
+}
+
+static void rs285_tx_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+ while (!(*CSR_UARTFLG & 0x20)) {
+ if (x_char) {
+ *CSR_UARTDR = x_char;
+ x_char = 0;
+ continue;
+ }
+ if (putp == getp) {
+ disable_irq(IRQ_CONTX);
+ break;
+ }
+ *CSR_UARTDR = *getp;
+ if (++getp >= wbuf + sizeof(wbuf))
+ getp = wbuf;
+ }
+ if (rs285_tty)
+ wake_up_interruptible(&rs285_tty->write_wait);
+}
+
+static inline int rs285_xmit(int ch)
+{
+ if (putp + 1 == getp || (putp + 1 == wbuf + sizeof(wbuf) && getp == wbuf))
+ return 0;
+ *putp = ch;
+ if (++putp >= wbuf + sizeof(wbuf))
+ putp = wbuf;
+ enable_irq(IRQ_CONTX);
+ return 1;
+}
+
+static int rs285_write(struct tty_struct *tty, int from_user,
+ const u_char * buf, int count)
+{
+ int i;
+
+ if (from_user && verify_area(VERIFY_READ, buf, count))
+ return -EINVAL;
+
+ for (i = 0; i < count; i++) {
+ char ch;
+ if (from_user)
+ __get_user(ch, buf + i);
+ else
+ ch = buf[i];
+ if (!rs285_xmit(ch))
+ break;
+ }
+ return i;
+}
+
+static void rs285_put_char(struct tty_struct *tty, u_char ch)
+{
+ rs285_xmit(ch);
+}
+
+static int rs285_chars_in_buffer(struct tty_struct *tty)
+{
+ return sizeof(wbuf) - rs285_write_room(tty);
+}
+
+static void rs285_flush_buffer(struct tty_struct *tty)
+{
+ disable_irq(IRQ_CONTX);
+ putp = getp = wbuf;
+ if (x_char)
+ enable_irq(IRQ_CONTX);
+}
+
+static inline void rs285_set_cflag(int cflag)
+{
+ int h_lcr, baud, quot;
+
+ switch (cflag & CSIZE) {
+ case CS5:
+ h_lcr = 0x10;
+ break;
+ case CS6:
+ h_lcr = 0x30;
+ break;
+ case CS7:
+ h_lcr = 0x50;
+ break;
+ default: /* CS8 */
+ h_lcr = 0x70;
+ break;
+
+ }
+ if (cflag & CSTOPB)
+ h_lcr |= 0x08;
+ if (cflag & PARENB)
+ h_lcr |= 0x02;
+ if (!(cflag & PARODD))
+ h_lcr |= 0x04;
+
+ switch (cflag & CBAUD) {
+ case B200: baud = 200; break;
+ case B300: baud = 300; break;
+ case B1200: baud = 1200; break;
+ case B1800: baud = 1800; break;
+ case B2400: baud = 2400; break;
+ case B4800: baud = 4800; break;
+ default:
+ case B9600: baud = 9600; break;
+ case B19200: baud = 19200; break;
+ case B38400: baud = 38400; break;
+ case B57600: baud = 57600; break;
+ case B115200: baud = 115200; break;
+ }
+
+ /*
+ * The documented expression for selecting the divisor is:
+ * BAUD_BASE / baud - 1
+ * However, typically BAUD_BASE is not divisible by baud, so
+ * we want to select the divisor that gives us the minimum
+ * error. Therefore, we want:
+ * int(BAUD_BASE / baud - 0.5) ->
+ * int(BAUD_BASE / baud - (baud >> 1) / baud) ->
+ * int((BAUD_BASE - (baud >> 1)) / baud)
+ */
+ quot = (BAUD_BASE - (baud >> 1)) / baud;
+
+ *CSR_UARTCON = 0;
+ *CSR_L_UBRLCR = quot & 0xff;
+ *CSR_M_UBRLCR = (quot >> 8) & 0x0f;
+ *CSR_H_UBRLCR = h_lcr;
+ *CSR_UARTCON = 1;
+}
+
+static void rs285_set_termios(struct tty_struct *tty, struct termios *old)
+{
+ if (old && tty->termios->c_cflag == old->c_cflag)
+ return;
+ rs285_set_cflag(tty->termios->c_cflag);
+}
+
+
+static void rs285_stop(struct tty_struct *tty)
+{
+ disable_irq(IRQ_CONTX);
+}
+
+static void rs285_start(struct tty_struct *tty)
+{
+ enable_irq(IRQ_CONTX);
+}
+
+static void rs285_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+ int orig_jiffies = jiffies;
+ while (*CSR_UARTFLG & 8) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ if (signal_pending(current))
+ break;
+ if (timeout && time_after(jiffies, orig_jiffies + timeout))
+ break;
+ }
+ current->state = TASK_RUNNING;
+}
+
+static int rs285_open(struct tty_struct *tty, struct file *filp)
+{
+ int line;
+
+ MOD_INC_USE_COUNT;
+ line = MINOR(tty->device) - tty->driver.minor_start;
+ if (line) {
+ MOD_DEC_USE_COUNT;
+ return -ENODEV;
+ }
+
+ tty->driver_data = NULL;
+ if (!rs285_tty)
+ rs285_tty = tty;
+
+ enable_irq(IRQ_CONRX);
+ rs285_use_count++;
+ return 0;
+}
+
+static void rs285_close(struct tty_struct *tty, struct file *filp)
+{
+ if (!--rs285_use_count) {
+ rs285_wait_until_sent(tty, 0);
+ disable_irq(IRQ_CONRX);
+ disable_irq(IRQ_CONTX);
+ rs285_tty = NULL;
+ }
+ MOD_DEC_USE_COUNT;
+}
+
+static int __init rs285_init(void)
+{
+ int baud = B9600;
+
+ if (machine_is_personal_server())
+ baud = B57600;
+
+ rs285_driver.magic = TTY_DRIVER_MAGIC;
+ rs285_driver.driver_name = "serial_21285";
+ rs285_driver.name = SERIAL_21285_NAME;
+ rs285_driver.major = SERIAL_21285_MAJOR;
+ rs285_driver.minor_start = SERIAL_21285_MINOR;
+ rs285_driver.num = 1;
+ rs285_driver.type = TTY_DRIVER_TYPE_SERIAL;
+ rs285_driver.subtype = SERIAL_TYPE_NORMAL;
+ rs285_driver.init_termios = tty_std_termios;
+ rs285_driver.init_termios.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
+ rs285_driver.flags = TTY_DRIVER_REAL_RAW;
+ rs285_driver.refcount = &rs285_refcount;
+ rs285_driver.table = rs285_table;
+ rs285_driver.termios = rs285_termios;
+ rs285_driver.termios_locked = rs285_termios_locked;
+
+ rs285_driver.open = rs285_open;
+ rs285_driver.close = rs285_close;
+ rs285_driver.write = rs285_write;
+ rs285_driver.put_char = rs285_put_char;
+ rs285_driver.write_room = rs285_write_room;
+ rs285_driver.chars_in_buffer = rs285_chars_in_buffer;
+ rs285_driver.flush_buffer = rs285_flush_buffer;
+ rs285_driver.throttle = rs285_throttle;
+ rs285_driver.unthrottle = rs285_unthrottle;
+ rs285_driver.send_xchar = rs285_send_xchar;
+ rs285_driver.set_termios = rs285_set_termios;
+ rs285_driver.stop = rs285_stop;
+ rs285_driver.start = rs285_start;
+ rs285_driver.wait_until_sent = rs285_wait_until_sent;
+
+ callout_driver = rs285_driver;
+ callout_driver.name = SERIAL_21285_AUXNAME;
+ callout_driver.major = SERIAL_21285_AUXMAJOR;
+ callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+ if (request_irq(IRQ_CONRX, rs285_rx_int, 0, "rs285", NULL))
+ panic("Couldn't get rx irq for rs285");
+
+ if (request_irq(IRQ_CONTX, rs285_tx_int, 0, "rs285", NULL))
+ panic("Couldn't get tx irq for rs285");
+
+ if (tty_register_driver(&rs285_driver))
+ printk(KERN_ERR "Couldn't register 21285 serial driver\n");
+ if (tty_register_driver(&callout_driver))
+ printk(KERN_ERR "Couldn't register 21285 callout driver\n");
+
+ return 0;
+}
+
+static void __exit rs285_fini(void)
+{
+ unsigned long flags;
+ int ret;
+
+ save_flags(flags);
+ cli();
+ ret = tty_unregister_driver(&callout_driver);
+ if (ret)
+ printk(KERN_ERR "Unable to unregister 21285 callout driver "
+ "(%d)\n", ret);
+ ret = tty_unregister_driver(&rs285_driver);
+ if (ret)
+ printk(KERN_ERR "Unable to unregister 21285 driver (%d)\n",
+ ret);
+ free_irq(IRQ_CONTX, NULL);
+ free_irq(IRQ_CONRX, NULL);
+ restore_flags(flags);
+}
+
+module_init(rs285_init);
+module_exit(rs285_fini);
+
+#ifdef CONFIG_SERIAL_21285_CONSOLE
+/************** console driver *****************/
+
+static void rs285_console_write(struct console *co, const char *s, u_int count)
+{
+ int i;
+
+ disable_irq(IRQ_CONTX);
+ for (i = 0; i < count; i++) {
+ while (*CSR_UARTFLG & 0x20);
+ *CSR_UARTDR = s[i];
+ if (s[i] == '\n') {
+ while (*CSR_UARTFLG & 0x20);
+ *CSR_UARTDR = '\r';
+ }
+ }
+ enable_irq(IRQ_CONTX);
+}
+
+static int rs285_console_wait_key(struct console *co)
+{
+ int c;
+
+ disable_irq(IRQ_CONRX);
+ while (*CSR_UARTFLG & 0x10);
+ c = *CSR_UARTDR;
+ enable_irq(IRQ_CONRX);
+ return c;
+}
+
+static kdev_t rs285_console_device(struct console *c)
+{
+ return MKDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
+}
+
+static int __init rs285_console_setup(struct console *co, char *options)
+{
+ int baud = 9600;
+ int bits = 8;
+ int parity = 'n';
+ int cflag = CREAD | HUPCL | CLOCAL;
+
+ if (machine_is_personal_server())
+ baud = 57600;
+
+ if (options) {
+ char *s = options;
+ baud = simple_strtoul(options, NULL, 10);
+ while (*s >= '0' && *s <= '9')
+ s++;
+ if (*s)
+ parity = *s++;
+ if (*s)
+ bits = *s - '0';
+ }
+
+ /*
+ * Now construct a cflag setting.
+ */
+ switch (baud) {
+ case 1200:
+ cflag |= B1200;
+ break;
+ case 2400:
+ cflag |= B2400;
+ break;
+ case 4800:
+ cflag |= B4800;
+ break;
+ case 9600:
+ cflag |= B9600;
+ break;
+ case 19200:
+ cflag |= B19200;
+ break;
+ case 38400:
+ cflag |= B38400;
+ break;
+ case 57600:
+ cflag |= B57600;
+ break;
+ case 115200:
+ cflag |= B115200;
+ break;
+ default:
+ cflag |= B9600;
+ break;
+ }
+ switch (bits) {
+ case 7:
+ cflag |= CS7;
+ break;
+ default:
+ cflag |= CS8;
+ break;
+ }
+ switch (parity) {
+ case 'o':
+ case 'O':
+ cflag |= PARODD;
+ break;
+ case 'e':
+ case 'E':
+ cflag |= PARENB;
+ break;
+ }
+ co->cflag = cflag;
+ rs285_set_cflag(cflag);
+ rs285_console_write(NULL, "\e[2J\e[Hboot ", 12);
+ if (options)
+ rs285_console_write(NULL, options, strlen(options));
+ else
+ rs285_console_write(NULL, "no options", 10);
+ rs285_console_write(NULL, "\n", 1);
+
+ return 0;
+}
+
+static struct console rs285_cons =
+{
+ SERIAL_21285_NAME,
+ rs285_console_write,
+ NULL,
+ rs285_console_device,
+ rs285_console_wait_key,
+ NULL,
+ rs285_console_setup,
+ CON_PRINTBUFFER,
+ -1,
+ 0,
+ NULL
+};
+
+void __init rs285_console_init(void)
+{
+ register_console(&rs285_cons);
+}
+
+#endif /* CONFIG_SERIAL_21285_CONSOLE */
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
deleted file mode 100644
index a0faeada4..000000000
--- a/drivers/char/stallion.c
+++ /dev/null
@@ -1,5329 +0,0 @@
-/*****************************************************************************/
-
-/*
- * stallion.c -- stallion multiport serial driver.
- *
- * Copyright (C) 1996-1999 Stallion Technologies (support@stallion.oz.au).
- * Copyright (C) 1994-1996 Greg Ungerer.
- *
- * This code is loosely based on the Linux serial driver, written by
- * Linus Torvalds, Theodore T'so and others.
- *
- * 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 of the License, 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.
- */
-
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/version.h> /* for linux/stallion.h */
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/cd1400.h>
-#include <linux/sc26198.h>
-#include <linux/comstats.h>
-#include <linux/stallion.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_PCI
-#include <linux/pci.h>
-#endif
-
-/*****************************************************************************/
-
-/*
- * Define different board types. Use the standard Stallion "assigned"
- * board numbers. Boards supported in this driver are abbreviated as
- * EIO = EasyIO and ECH = EasyConnection 8/32.
- */
-#define BRD_EASYIO 20
-#define BRD_ECH 21
-#define BRD_ECHMC 22
-#define BRD_ECHPCI 26
-#define BRD_ECH64PCI 27
-#define BRD_EASYIOPCI 28
-
-/*
- * Define a configuration structure to hold the board configuration.
- * Need to set this up in the code (for now) with the boards that are
- * to be configured into the system. This is what needs to be modified
- * when adding/removing/modifying boards. Each line entry in the
- * stl_brdconf[] array is a board. Each line contains io/irq/memory
- * ranges for that board (as well as what type of board it is).
- * Some examples:
- * { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },
- * This line would configure an EasyIO board (4 or 8, no difference),
- * at io address 2a0 and irq 10.
- * Another example:
- * { BRD_ECH, 0x2a8, 0x280, 0, 12, 0 },
- * This line will configure an EasyConnection 8/32 board at primary io
- * address 2a8, secondary io address 280 and irq 12.
- * Enter as many lines into this array as you want (only the first 4
- * will actually be used!). Any combination of EasyIO and EasyConnection
- * boards can be specified. EasyConnection 8/32 boards can share their
- * secondary io addresses between each other.
- *
- * NOTE: there is no need to put any entries in this table for PCI
- * boards. They will be found automatically by the driver - provided
- * PCI BIOS32 support is compiled into the kernel.
- */
-
-typedef struct {
- int brdtype;
- int ioaddr1;
- int ioaddr2;
- unsigned long memaddr;
- int irq;
- int irqtype;
-} stlconf_t;
-
-static stlconf_t stl_brdconf[] = {
- /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/
-};
-
-static int stl_nrbrds = sizeof(stl_brdconf) / sizeof(stlconf_t);
-
-/*****************************************************************************/
-
-/*
- * Define some important driver characteristics. Device major numbers
- * allocated as per Linux Device Registry.
- */
-#ifndef STL_SIOMEMMAJOR
-#define STL_SIOMEMMAJOR 28
-#endif
-#ifndef STL_SERIALMAJOR
-#define STL_SERIALMAJOR 24
-#endif
-#ifndef STL_CALLOUTMAJOR
-#define STL_CALLOUTMAJOR 25
-#endif
-
-#define STL_DRVTYPSERIAL 1
-#define STL_DRVTYPCALLOUT 2
-
-/*
- * Set the TX buffer size. Bigger is better, but we don't want
- * to chew too much memory with buffers!
- */
-#define STL_TXBUFLOW 512
-#define STL_TXBUFSIZE 4096
-
-/*****************************************************************************/
-
-/*
- * Define our local driver identity first. Set up stuff to deal with
- * all the local structures required by a serial tty driver.
- */
-static char *stl_drvtitle = "Stallion Multiport Serial Driver";
-static char *stl_drvname = "stallion";
-static char *stl_drvversion = "5.6.0";
-static char *stl_serialname = "ttyE";
-static char *stl_calloutname = "cue";
-
-static struct tty_driver stl_serial;
-static struct tty_driver stl_callout;
-static struct tty_struct *stl_ttys[STL_MAXDEVS];
-static struct termios *stl_termios[STL_MAXDEVS];
-static struct termios *stl_termioslocked[STL_MAXDEVS];
-static int stl_refcount = 0;
-
-/*
- * We will need to allocate a temporary write buffer for chars that
- * come direct from user space. The problem is that a copy from user
- * space might cause a page fault (typically on a system that is
- * swapping!). All ports will share one buffer - since if the system
- * is already swapping a shared buffer won't make things any worse.
- */
-static char *stl_tmpwritebuf;
-static DECLARE_MUTEX(stl_tmpwritesem);
-
-/*
- * Define a local default termios struct. All ports will be created
- * with this termios initially. Basically all it defines is a raw port
- * at 9600, 8 data bits, 1 stop bit.
- */
-static struct termios stl_deftermios = {
- 0,
- 0,
- (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
- 0,
- 0,
- INIT_C_CC
-};
-
-/*
- * Define global stats structures. Not used often, and can be
- * re-used for each stats call.
- */
-static comstats_t stl_comstats;
-static combrd_t stl_brdstats;
-static stlbrd_t stl_dummybrd;
-static stlport_t stl_dummyport;
-
-/*
- * Define global place to put buffer overflow characters.
- */
-static char stl_unwanted[SC26198_RXFIFOSIZE];
-
-/*
- * Keep track of what interrupts we have requested for us.
- * We don't need to request an interrupt twice if it is being
- * shared with another Stallion board.
- */
-static int stl_gotintrs[STL_MAXBRDS];
-static int stl_numintrs = 0;
-
-/*****************************************************************************/
-
-static stlbrd_t *stl_brds[STL_MAXBRDS];
-
-/*
- * Per board state flags. Used with the state field of the board struct.
- * Not really much here!
- */
-#define BRD_FOUND 0x1
-
-/*
- * Define the port structure istate flags. These set of flags are
- * modified at interrupt time - so setting and reseting them needs
- * to be atomic. Use the bit clear/setting routines for this.
- */
-#define ASYI_TXBUSY 1
-#define ASYI_TXLOW 2
-#define ASYI_DCDCHANGE 3
-#define ASYI_TXFLOWED 4
-
-/*
- * Define an array of board names as printable strings. Handy for
- * referencing boards when printing trace and stuff.
- */
-static char *stl_brdnames[] = {
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- "EasyIO",
- "EC8/32-AT",
- "EC8/32-MC",
- (char *) NULL,
- (char *) NULL,
- (char *) NULL,
- "EC8/32-PCI",
- "EC8/64-PCI",
- "EasyIO-PCI",
-};
-
-/*****************************************************************************/
-
-#ifdef MODULE
-/*
- * Define some string labels for arguments passed from the module
- * load line. These allow for easy board definitions, and easy
- * modification of the io, memory and irq resoucres.
- */
-
-static char *board0[4];
-static char *board1[4];
-static char *board2[4];
-static char *board3[4];
-
-static char **stl_brdsp[] = {
- (char **) &board0,
- (char **) &board1,
- (char **) &board2,
- (char **) &board3
-};
-
-/*
- * Define a set of common board names, and types. This is used to
- * parse any module arguments.
- */
-
-typedef struct stlbrdtype {
- char *name;
- int type;
-} stlbrdtype_t;
-
-static stlbrdtype_t stl_brdstr[] = {
- { "easyio", BRD_EASYIO },
- { "eio", BRD_EASYIO },
- { "20", BRD_EASYIO },
- { "ec8/32", BRD_ECH },
- { "ec8/32-at", BRD_ECH },
- { "ec8/32-isa", BRD_ECH },
- { "ech", BRD_ECH },
- { "echat", BRD_ECH },
- { "21", BRD_ECH },
- { "ec8/32-mc", BRD_ECHMC },
- { "ec8/32-mca", BRD_ECHMC },
- { "echmc", BRD_ECHMC },
- { "echmca", BRD_ECHMC },
- { "22", BRD_ECHMC },
- { "ec8/32-pc", BRD_ECHPCI },
- { "ec8/32-pci", BRD_ECHPCI },
- { "26", BRD_ECHPCI },
- { "ec8/64-pc", BRD_ECH64PCI },
- { "ec8/64-pci", BRD_ECH64PCI },
- { "ech-pci", BRD_ECH64PCI },
- { "echpci", BRD_ECH64PCI },
- { "echpc", BRD_ECH64PCI },
- { "27", BRD_ECH64PCI },
- { "easyio-pc", BRD_EASYIOPCI },
- { "easyio-pci", BRD_EASYIOPCI },
- { "eio-pci", BRD_EASYIOPCI },
- { "eiopci", BRD_EASYIOPCI },
- { "28", BRD_EASYIOPCI },
-};
-
-/*
- * Define the module agruments.
- */
-MODULE_AUTHOR("Greg Ungerer");
-MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
-
-MODULE_PARM(board0, "1-4s");
-MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]");
-MODULE_PARM(board1, "1-4s");
-MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]");
-MODULE_PARM(board2, "1-4s");
-MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]");
-MODULE_PARM(board3, "1-4s");
-MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]");
-
-#endif
-
-/*****************************************************************************/
-
-/*
- * Hardware ID bits for the EasyIO and ECH boards. These defines apply
- * to the directly accessible io ports of these boards (not the uarts -
- * they are in cd1400.h and sc26198.h).
- */
-#define EIO_8PORTRS 0x04
-#define EIO_4PORTRS 0x05
-#define EIO_8PORTDI 0x00
-#define EIO_8PORTM 0x06
-#define EIO_MK3 0x03
-#define EIO_IDBITMASK 0x07
-
-#define EIO_BRDMASK 0xf0
-#define ID_BRD4 0x10
-#define ID_BRD8 0x20
-#define ID_BRD16 0x30
-
-#define EIO_INTRPEND 0x08
-#define EIO_INTEDGE 0x00
-#define EIO_INTLEVEL 0x08
-#define EIO_0WS 0x10
-
-#define ECH_ID 0xa0
-#define ECH_IDBITMASK 0xe0
-#define ECH_BRDENABLE 0x08
-#define ECH_BRDDISABLE 0x00
-#define ECH_INTENABLE 0x01
-#define ECH_INTDISABLE 0x00
-#define ECH_INTLEVEL 0x02
-#define ECH_INTEDGE 0x00
-#define ECH_INTRPEND 0x01
-#define ECH_BRDRESET 0x01
-
-#define ECHMC_INTENABLE 0x01
-#define ECHMC_BRDRESET 0x02
-
-#define ECH_PNLSTATUS 2
-#define ECH_PNL16PORT 0x20
-#define ECH_PNLIDMASK 0x07
-#define ECH_PNLXPID 0x40
-#define ECH_PNLINTRPEND 0x80
-
-#define ECH_ADDR2MASK 0x1e0
-
-/*
- * Define the vector mapping bits for the programmable interrupt board
- * hardware. These bits encode the interrupt for the board to use - it
- * is software selectable (except the EIO-8M).
- */
-static unsigned char stl_vecmap[] = {
- 0xff, 0xff, 0xff, 0x04, 0x06, 0x05, 0xff, 0x07,
- 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03
-};
-
-/*
- * Set up enable and disable macros for the ECH boards. They require
- * the secondary io address space to be activated and deactivated.
- * This way all ECH boards can share their secondary io region.
- * If this is an ECH-PCI board then also need to set the page pointer
- * to point to the correct page.
- */
-#define BRDENABLE(brdnr,pagenr) \
- if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \
- outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDENABLE), \
- stl_brds[(brdnr)]->ioctrl); \
- else if (stl_brds[(brdnr)]->brdtype == BRD_ECHPCI) \
- outb((pagenr), stl_brds[(brdnr)]->ioctrl);
-
-#define BRDDISABLE(brdnr) \
- if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \
- outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE), \
- stl_brds[(brdnr)]->ioctrl);
-
-#define STL_CD1400MAXBAUD 230400
-#define STL_SC26198MAXBAUD 460800
-
-#define STL_BAUDBASE 115200
-#define STL_CLOSEDELAY (5 * HZ / 10)
-
-/*****************************************************************************/
-
-#ifdef CONFIG_PCI
-
-/*
- * Define the Stallion PCI vendor and device IDs.
- */
-#ifndef PCI_VENDOR_ID_STALLION
-#define PCI_VENDOR_ID_STALLION 0x124d
-#endif
-#ifndef PCI_DEVICE_ID_ECHPCI832
-#define PCI_DEVICE_ID_ECHPCI832 0x0000
-#endif
-#ifndef PCI_DEVICE_ID_ECHPCI864
-#define PCI_DEVICE_ID_ECHPCI864 0x0002
-#endif
-#ifndef PCI_DEVICE_ID_EIOPCI
-#define PCI_DEVICE_ID_EIOPCI 0x0003
-#endif
-
-/*
- * Define structure to hold all Stallion PCI boards.
- */
-typedef struct stlpcibrd {
- unsigned short vendid;
- unsigned short devid;
- int brdtype;
-} stlpcibrd_t;
-
-static stlpcibrd_t stl_pcibrds[] = {
- { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864, BRD_ECH64PCI },
- { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI, BRD_EASYIOPCI },
- { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832, BRD_ECHPCI },
- { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI },
-};
-
-static int stl_nrpcibrds = sizeof(stl_pcibrds) / sizeof(stlpcibrd_t);
-
-#endif
-
-/*****************************************************************************/
-
-/*
- * Define macros to extract a brd/port number from a minor number.
- */
-#define MINOR2BRD(min) (((min) & 0xc0) >> 6)
-#define MINOR2PORT(min) ((min) & 0x3f)
-
-/*
- * Define a baud rate table that converts termios baud rate selector
- * into the actual baud rate value. All baud rate calculations are
- * based on the actual baud rate required.
- */
-static unsigned int stl_baudrates[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
-};
-
-/*
- * Define some handy local macros...
- */
-#undef MIN
-#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
-
-#undef TOLOWER
-#define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
-
-/*****************************************************************************/
-
-/*
- * Declare all those functions in this driver!
- */
-
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-static void stl_argbrds(void);
-static int stl_parsebrd(stlconf_t *confp, char **argp);
-
-static unsigned long stl_atol(char *str);
-#endif
-
-int stl_init(void);
-static int stl_open(struct tty_struct *tty, struct file *filp);
-static void stl_close(struct tty_struct *tty, struct file *filp);
-static int stl_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
-static void stl_putchar(struct tty_struct *tty, unsigned char ch);
-static void stl_flushchars(struct tty_struct *tty);
-static int stl_writeroom(struct tty_struct *tty);
-static int stl_charsinbuffer(struct tty_struct *tty);
-static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static void stl_settermios(struct tty_struct *tty, struct termios *old);
-static void stl_throttle(struct tty_struct *tty);
-static void stl_unthrottle(struct tty_struct *tty);
-static void stl_stop(struct tty_struct *tty);
-static void stl_start(struct tty_struct *tty);
-static void stl_flushbuffer(struct tty_struct *tty);
-static void stl_breakctl(struct tty_struct *tty, int state);
-static void stl_waituntilsent(struct tty_struct *tty, int timeout);
-static void stl_sendxchar(struct tty_struct *tty, char ch);
-static void stl_hangup(struct tty_struct *tty);
-static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
-static int stl_portinfo(stlport_t *portp, int portnr, char *pos);
-static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data);
-
-static int stl_brdinit(stlbrd_t *brdp);
-static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
-static int stl_mapirq(int irq, char *name);
-static void stl_getserial(stlport_t *portp, struct serial_struct *sp);
-static int stl_setserial(stlport_t *portp, struct serial_struct *sp);
-static int stl_getbrdstats(combrd_t *bp);
-static int stl_getportstats(stlport_t *portp, comstats_t *cp);
-static int stl_clrportstats(stlport_t *portp, comstats_t *cp);
-static int stl_getportstruct(unsigned long arg);
-static int stl_getbrdstruct(unsigned long arg);
-static int stl_waitcarrier(stlport_t *portp, struct file *filp);
-static void stl_delay(int len);
-static void stl_intr(int irq, void *dev_id, struct pt_regs *regs);
-static void stl_eiointr(stlbrd_t *brdp);
-static void stl_echatintr(stlbrd_t *brdp);
-static void stl_echmcaintr(stlbrd_t *brdp);
-static void stl_echpciintr(stlbrd_t *brdp);
-static void stl_echpci64intr(stlbrd_t *brdp);
-static void stl_offintr(void *private);
-static void *stl_memalloc(int len);
-static stlbrd_t *stl_allocbrd(void);
-static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
-
-static inline int stl_initbrds(void);
-static inline int stl_initeio(stlbrd_t *brdp);
-static inline int stl_initech(stlbrd_t *brdp);
-static inline int stl_getbrdnr(void);
-
-#ifdef CONFIG_PCI
-static inline int stl_findpcibrds(void);
-static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp);
-#endif
-
-/*
- * CD1400 uart specific handling functions.
- */
-static void stl_cd1400setreg(stlport_t *portp, int regnr, int value);
-static int stl_cd1400getreg(stlport_t *portp, int regnr);
-static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value);
-static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
-static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
-static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp);
-static int stl_cd1400getsignals(stlport_t *portp);
-static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts);
-static void stl_cd1400ccrwait(stlport_t *portp);
-static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx);
-static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx);
-static void stl_cd1400disableintrs(stlport_t *portp);
-static void stl_cd1400sendbreak(stlport_t *portp, int len);
-static void stl_cd1400flowctrl(stlport_t *portp, int state);
-static void stl_cd1400sendflow(stlport_t *portp, int state);
-static void stl_cd1400flush(stlport_t *portp);
-static int stl_cd1400datastate(stlport_t *portp);
-static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase);
-static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase);
-static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr);
-static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr);
-static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr);
-
-static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr);
-
-/*
- * SC26198 uart specific handling functions.
- */
-static void stl_sc26198setreg(stlport_t *portp, int regnr, int value);
-static int stl_sc26198getreg(stlport_t *portp, int regnr);
-static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value);
-static int stl_sc26198getglobreg(stlport_t *portp, int regnr);
-static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
-static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
-static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp);
-static int stl_sc26198getsignals(stlport_t *portp);
-static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts);
-static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx);
-static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx);
-static void stl_sc26198disableintrs(stlport_t *portp);
-static void stl_sc26198sendbreak(stlport_t *portp, int len);
-static void stl_sc26198flowctrl(stlport_t *portp, int state);
-static void stl_sc26198sendflow(stlport_t *portp, int state);
-static void stl_sc26198flush(stlport_t *portp);
-static int stl_sc26198datastate(stlport_t *portp);
-static void stl_sc26198wait(stlport_t *portp);
-static void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty);
-static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase);
-static void stl_sc26198txisr(stlport_t *port);
-static void stl_sc26198rxisr(stlport_t *port, unsigned int iack);
-static void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch);
-static void stl_sc26198rxbadchars(stlport_t *portp);
-static void stl_sc26198otherisr(stlport_t *port, unsigned int iack);
-
-/*****************************************************************************/
-
-/*
- * Generic UART support structure.
- */
-typedef struct uart {
- int (*panelinit)(stlbrd_t *brdp, stlpanel_t *panelp);
- void (*portinit)(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
- void (*setport)(stlport_t *portp, struct termios *tiosp);
- int (*getsignals)(stlport_t *portp);
- void (*setsignals)(stlport_t *portp, int dtr, int rts);
- void (*enablerxtx)(stlport_t *portp, int rx, int tx);
- void (*startrxtx)(stlport_t *portp, int rx, int tx);
- void (*disableintrs)(stlport_t *portp);
- void (*sendbreak)(stlport_t *portp, int len);
- void (*flowctrl)(stlport_t *portp, int state);
- void (*sendflow)(stlport_t *portp, int state);
- void (*flush)(stlport_t *portp);
- int (*datastate)(stlport_t *portp);
- void (*intr)(stlpanel_t *panelp, unsigned int iobase);
-} uart_t;
-
-/*
- * Define some macros to make calling these functions nice and clean.
- */
-#define stl_panelinit (* ((uart_t *) panelp->uartp)->panelinit)
-#define stl_portinit (* ((uart_t *) portp->uartp)->portinit)
-#define stl_setport (* ((uart_t *) portp->uartp)->setport)
-#define stl_getsignals (* ((uart_t *) portp->uartp)->getsignals)
-#define stl_setsignals (* ((uart_t *) portp->uartp)->setsignals)
-#define stl_enablerxtx (* ((uart_t *) portp->uartp)->enablerxtx)
-#define stl_startrxtx (* ((uart_t *) portp->uartp)->startrxtx)
-#define stl_disableintrs (* ((uart_t *) portp->uartp)->disableintrs)
-#define stl_sendbreak (* ((uart_t *) portp->uartp)->sendbreak)
-#define stl_flowctrl (* ((uart_t *) portp->uartp)->flowctrl)
-#define stl_sendflow (* ((uart_t *) portp->uartp)->sendflow)
-#define stl_flush (* ((uart_t *) portp->uartp)->flush)
-#define stl_datastate (* ((uart_t *) portp->uartp)->datastate)
-
-/*****************************************************************************/
-
-/*
- * CD1400 UART specific data initialization.
- */
-static uart_t stl_cd1400uart = {
- stl_cd1400panelinit,
- stl_cd1400portinit,
- stl_cd1400setport,
- stl_cd1400getsignals,
- stl_cd1400setsignals,
- stl_cd1400enablerxtx,
- stl_cd1400startrxtx,
- stl_cd1400disableintrs,
- stl_cd1400sendbreak,
- stl_cd1400flowctrl,
- stl_cd1400sendflow,
- stl_cd1400flush,
- stl_cd1400datastate,
- stl_cd1400eiointr
-};
-
-/*
- * Define the offsets within the register bank of a cd1400 based panel.
- * These io address offsets are common to the EasyIO board as well.
- */
-#define EREG_ADDR 0
-#define EREG_DATA 4
-#define EREG_RXACK 5
-#define EREG_TXACK 6
-#define EREG_MDACK 7
-
-#define EREG_BANKSIZE 8
-
-#define CD1400_CLK 25000000
-#define CD1400_CLK8M 20000000
-
-/*
- * Define the cd1400 baud rate clocks. These are used when calculating
- * what clock and divisor to use for the required baud rate. Also
- * define the maximum baud rate allowed, and the default base baud.
- */
-static int stl_cd1400clkdivs[] = {
- CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4
-};
-
-/*****************************************************************************/
-
-/*
- * SC26198 UART specific data initization.
- */
-static uart_t stl_sc26198uart = {
- stl_sc26198panelinit,
- stl_sc26198portinit,
- stl_sc26198setport,
- stl_sc26198getsignals,
- stl_sc26198setsignals,
- stl_sc26198enablerxtx,
- stl_sc26198startrxtx,
- stl_sc26198disableintrs,
- stl_sc26198sendbreak,
- stl_sc26198flowctrl,
- stl_sc26198sendflow,
- stl_sc26198flush,
- stl_sc26198datastate,
- stl_sc26198intr
-};
-
-/*
- * Define the offsets within the register bank of a sc26198 based panel.
- */
-#define XP_DATA 0
-#define XP_ADDR 1
-#define XP_MODID 2
-#define XP_STATUS 2
-#define XP_IACK 3
-
-#define XP_BANKSIZE 4
-
-/*
- * Define the sc26198 baud rate table. Offsets within the table
- * represent the actual baud rate selector of sc26198 registers.
- */
-static unsigned int sc26198_baudtable[] = {
- 50, 75, 150, 200, 300, 450, 600, 900, 1200, 1800, 2400, 3600,
- 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200,
- 230400, 460800, 921600
-};
-
-#define SC26198_NRBAUDS (sizeof(sc26198_baudtable) / sizeof(unsigned int))
-
-/*****************************************************************************/
-
-/*
- * Define the driver info for a user level control device. Used mainly
- * to get at port stats - only not using the port device itself.
- */
-static struct file_operations stl_fsiomem = {
- owner: THIS_MODULE,
- ioctl: stl_memioctl,
-};
-
-/*****************************************************************************/
-
-static devfs_handle_t devfs_handle = NULL;
-
-#ifdef MODULE
-
-/*
- * Loadable module initialization stuff.
- */
-
-int init_module()
-{
- unsigned long flags;
-
-#if DEBUG
- printk("init_module()\n");
-#endif
-
- save_flags(flags);
- cli();
- stl_init();
- restore_flags(flags);
-
- return(0);
-}
-
-/*****************************************************************************/
-
-void cleanup_module()
-{
- stlbrd_t *brdp;
- stlpanel_t *panelp;
- stlport_t *portp;
- unsigned long flags;
- int i, j, k;
-
-#if DEBUG
- printk("cleanup_module()\n");
-#endif
-
- printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle,
- stl_drvversion);
-
- save_flags(flags);
- cli();
-
-/*
- * Free up all allocated resources used by the ports. This includes
- * memory and interrupts. As part of this process we will also do
- * a hangup on every open port - to try to flush out any processes
- * hanging onto ports.
- */
- i = tty_unregister_driver(&stl_serial);
- j = tty_unregister_driver(&stl_callout);
- if (i || j) {
- printk("STALLION: failed to un-register tty driver, "
- "errno=%d,%d\n", -i, -j);
- restore_flags(flags);
- return;
- }
- devfs_unregister (devfs_handle);
- if ((i = devfs_unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
- printk("STALLION: failed to un-register serial memory device, "
- "errno=%d\n", -i);
-
- if (stl_tmpwritebuf != (char *) NULL)
- kfree(stl_tmpwritebuf);
-
- for (i = 0; (i < stl_nrbrds); i++) {
- if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
- continue;
- for (j = 0; (j < STL_MAXPANELS); j++) {
- panelp = brdp->panels[j];
- if (panelp == (stlpanel_t *) NULL)
- continue;
- for (k = 0; (k < STL_PORTSPERPANEL); k++) {
- portp = panelp->ports[k];
- if (portp == (stlport_t *) NULL)
- continue;
- if (portp->tty != (struct tty_struct *) NULL)
- stl_hangup(portp->tty);
- if (portp->tx.buf != (char *) NULL)
- kfree(portp->tx.buf);
- kfree(portp);
- }
- kfree(panelp);
- }
-
- release_region(brdp->ioaddr1, brdp->iosize1);
- if (brdp->iosize2 > 0)
- release_region(brdp->ioaddr2, brdp->iosize2);
-
- kfree(brdp);
- stl_brds[i] = (stlbrd_t *) NULL;
- }
-
- for (i = 0; (i < stl_numintrs); i++)
- free_irq(stl_gotintrs[i], NULL);
-
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Check for any arguments passed in on the module load command line.
- */
-
-static void stl_argbrds()
-{
- stlconf_t conf;
- stlbrd_t *brdp;
- int nrargs, i;
-
-#if DEBUG
- printk("stl_argbrds()\n");
-#endif
-
- nrargs = sizeof(stl_brdsp) / sizeof(char **);
-
- for (i = stl_nrbrds; (i < nrargs); i++) {
- memset(&conf, 0, sizeof(conf));
- if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
- continue;
- if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
- continue;
- stl_nrbrds = i + 1;
- brdp->brdnr = i;
- brdp->brdtype = conf.brdtype;
- brdp->ioaddr1 = conf.ioaddr1;
- brdp->ioaddr2 = conf.ioaddr2;
- brdp->irq = conf.irq;
- brdp->irqtype = conf.irqtype;
- stl_brdinit(brdp);
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Convert an ascii string number into an unsigned long.
- */
-
-static unsigned long stl_atol(char *str)
-{
- unsigned long val;
- int base, c;
- char *sp;
-
- val = 0;
- sp = str;
- if ((*sp == '0') && (*(sp+1) == 'x')) {
- base = 16;
- sp += 2;
- } else if (*sp == '0') {
- base = 8;
- sp++;
- } else {
- base = 10;
- }
-
- for (; (*sp != 0); sp++) {
- c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
- if ((c < 0) || (c >= base)) {
- printk("STALLION: invalid argument %s\n", str);
- val = 0;
- break;
- }
- val = (val * base) + c;
- }
- return(val);
-}
-
-/*****************************************************************************/
-
-/*
- * Parse the supplied argument string, into the board conf struct.
- */
-
-static int stl_parsebrd(stlconf_t *confp, char **argp)
-{
- char *sp;
- int nrbrdnames, i;
-
-#if DEBUG
- printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
-#endif
-
- if ((argp[0] == (char *) NULL) || (*argp[0] == 0))
- return(0);
-
- for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
- *sp = TOLOWER(*sp);
-
- nrbrdnames = sizeof(stl_brdstr) / sizeof(stlbrdtype_t);
- for (i = 0; (i < nrbrdnames); i++) {
- if (strcmp(stl_brdstr[i].name, argp[0]) == 0)
- break;
- }
- if (i >= nrbrdnames) {
- printk("STALLION: unknown board name, %s?\n", argp[0]);
- return(0);
- }
-
- confp->brdtype = stl_brdstr[i].type;
-
- i = 1;
- if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
- confp->ioaddr1 = stl_atol(argp[i]);
- i++;
- if (confp->brdtype == BRD_ECH) {
- if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
- confp->ioaddr2 = stl_atol(argp[i]);
- i++;
- }
- if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
- confp->irq = stl_atol(argp[i]);
- return(1);
-}
-
-#endif
-
-/*****************************************************************************/
-
-/*
- * Local driver kernel memory allocation routine.
- */
-
-static void *stl_memalloc(int len)
-{
- return((void *) kmalloc(len, GFP_KERNEL));
-}
-
-/*****************************************************************************/
-
-/*
- * Allocate a new board structure. Fill out the basic info in it.
- */
-
-static stlbrd_t *stl_allocbrd()
-{
- stlbrd_t *brdp;
-
- brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
- if (brdp == (stlbrd_t *) NULL) {
- printk("STALLION: failed to allocate memory (size=%d)\n",
- sizeof(stlbrd_t));
- return((stlbrd_t *) NULL);
- }
-
- memset(brdp, 0, sizeof(stlbrd_t));
- brdp->magic = STL_BOARDMAGIC;
- return(brdp);
-}
-
-/*****************************************************************************/
-
-static int stl_open(struct tty_struct *tty, struct file *filp)
-{
- stlport_t *portp;
- stlbrd_t *brdp;
- unsigned int minordev;
- int brdnr, panelnr, portnr, rc;
-
-#if DEBUG
- printk("stl_open(tty=%x,filp=%x): device=%x\n", (int) tty,
- (int) filp, tty->device);
-#endif
-
- minordev = MINOR(tty->device);
- brdnr = MINOR2BRD(minordev);
- if (brdnr >= stl_nrbrds)
- return(-ENODEV);
- brdp = stl_brds[brdnr];
- if (brdp == (stlbrd_t *) NULL)
- return(-ENODEV);
- minordev = MINOR2PORT(minordev);
- for (portnr = -1, panelnr = 0; (panelnr < STL_MAXPANELS); panelnr++) {
- if (brdp->panels[panelnr] == (stlpanel_t *) NULL)
- break;
- if (minordev < brdp->panels[panelnr]->nrports) {
- portnr = minordev;
- break;
- }
- minordev -= brdp->panels[panelnr]->nrports;
- }
- if (portnr < 0)
- return(-ENODEV);
-
- portp = brdp->panels[panelnr]->ports[portnr];
- if (portp == (stlport_t *) NULL)
- return(-ENODEV);
-
- MOD_INC_USE_COUNT;
-
-/*
- * On the first open of the device setup the port hardware, and
- * initialize the per port data structure.
- */
- portp->tty = tty;
- tty->driver_data = portp;
- portp->refcount++;
-
- if ((portp->flags & ASYNC_INITIALIZED) == 0) {
- if (portp->tx.buf == (char *) NULL) {
- portp->tx.buf = (char *) stl_memalloc(STL_TXBUFSIZE);
- if (portp->tx.buf == (char *) NULL)
- return(-ENOMEM);
- portp->tx.head = portp->tx.buf;
- portp->tx.tail = portp->tx.buf;
- }
- stl_setport(portp, tty->termios);
- portp->sigs = stl_getsignals(portp);
- stl_setsignals(portp, 1, 1);
- stl_enablerxtx(portp, 1, 1);
- stl_startrxtx(portp, 1, 0);
- clear_bit(TTY_IO_ERROR, &tty->flags);
- portp->flags |= ASYNC_INITIALIZED;
- }
-
-/*
- * Check if this port is in the middle of closing. If so then wait
- * until it is closed then return error status, based on flag settings.
- * The sleep here does not need interrupt protection since the wakeup
- * for it is done with the same context.
- */
- if (portp->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&portp->close_wait);
- if (portp->flags & ASYNC_HUP_NOTIFY)
- return(-EAGAIN);
- return(-ERESTARTSYS);
- }
-
-/*
- * Based on type of open being done check if it can overlap with any
- * previous opens still in effect. If we are a normal serial device
- * then also we might have to wait for carrier.
- */
- if (tty->driver.subtype == STL_DRVTYPCALLOUT) {
- if (portp->flags & ASYNC_NORMAL_ACTIVE)
- return(-EBUSY);
- if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
- if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
- (portp->session != current->session))
- return(-EBUSY);
- if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
- (portp->pgrp != current->pgrp))
- return(-EBUSY);
- }
- portp->flags |= ASYNC_CALLOUT_ACTIVE;
- } else {
- if (filp->f_flags & O_NONBLOCK) {
- if (portp->flags & ASYNC_CALLOUT_ACTIVE)
- return(-EBUSY);
- } else {
- if ((rc = stl_waitcarrier(portp, filp)) != 0)
- return(rc);
- }
- portp->flags |= ASYNC_NORMAL_ACTIVE;
- }
-
- if ((portp->refcount == 1) && (portp->flags & ASYNC_SPLIT_TERMIOS)) {
- if (tty->driver.subtype == STL_DRVTYPSERIAL)
- *tty->termios = portp->normaltermios;
- else
- *tty->termios = portp->callouttermios;
- stl_setport(portp, tty->termios);
- }
-
- portp->session = current->session;
- portp->pgrp = current->pgrp;
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Possibly need to wait for carrier (DCD signal) to come high. Say
- * maybe because if we are clocal then we don't need to wait...
- */
-
-static int stl_waitcarrier(stlport_t *portp, struct file *filp)
-{
- unsigned long flags;
- int rc, doclocal;
-
-#if DEBUG
- printk("stl_waitcarrier(portp=%x,filp=%x)\n", (int) portp, (int) filp);
-#endif
-
- rc = 0;
- doclocal = 0;
-
- if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
- if (portp->normaltermios.c_cflag & CLOCAL)
- doclocal++;
- } else {
- if (portp->tty->termios->c_cflag & CLOCAL)
- doclocal++;
- }
-
- save_flags(flags);
- cli();
- portp->openwaitcnt++;
- if (! tty_hung_up_p(filp))
- portp->refcount--;
-
- for (;;) {
- if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0)
- stl_setsignals(portp, 1, 1);
- if (tty_hung_up_p(filp) ||
- ((portp->flags & ASYNC_INITIALIZED) == 0)) {
- if (portp->flags & ASYNC_HUP_NOTIFY)
- rc = -EBUSY;
- else
- rc = -ERESTARTSYS;
- break;
- }
- if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
- ((portp->flags & ASYNC_CLOSING) == 0) &&
- (doclocal || (portp->sigs & TIOCM_CD))) {
- break;
- }
- if (signal_pending(current)) {
- rc = -ERESTARTSYS;
- break;
- }
- interruptible_sleep_on(&portp->open_wait);
- }
-
- if (! tty_hung_up_p(filp))
- portp->refcount++;
- portp->openwaitcnt--;
- restore_flags(flags);
-
- return(rc);
-}
-
-/*****************************************************************************/
-
-static void stl_close(struct tty_struct *tty, struct file *filp)
-{
- stlport_t *portp;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_close(tty=%x,filp=%x)\n", (int) tty, (int) filp);
-#endif
-
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
-
- save_flags(flags);
- cli();
- if (tty_hung_up_p(filp)) {
- MOD_DEC_USE_COUNT;
- restore_flags(flags);
- return;
- }
- if ((tty->count == 1) && (portp->refcount != 1))
- portp->refcount = 1;
- if (portp->refcount-- > 1) {
- MOD_DEC_USE_COUNT;
- restore_flags(flags);
- return;
- }
-
- portp->refcount = 0;
- portp->flags |= ASYNC_CLOSING;
-
- if (portp->flags & ASYNC_NORMAL_ACTIVE)
- portp->normaltermios = *tty->termios;
- if (portp->flags & ASYNC_CALLOUT_ACTIVE)
- portp->callouttermios = *tty->termios;
-
-/*
- * May want to wait for any data to drain before closing. The BUSY
- * flag keeps track of whether we are still sending or not - it is
- * very accurate for the cd1400, not quite so for the sc26198.
- * (The sc26198 has no "end-of-data" interrupt only empty FIFO)
- */
- tty->closing = 1;
- if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, portp->closing_wait);
- stl_waituntilsent(tty, (HZ / 2));
-
- portp->flags &= ~ASYNC_INITIALIZED;
- stl_disableintrs(portp);
- if (tty->termios->c_cflag & HUPCL)
- stl_setsignals(portp, 0, 0);
- stl_enablerxtx(portp, 0, 0);
- stl_flushbuffer(tty);
- portp->istate = 0;
- if (portp->tx.buf != (char *) NULL) {
- kfree(portp->tx.buf);
- portp->tx.buf = (char *) NULL;
- portp->tx.head = (char *) NULL;
- portp->tx.tail = (char *) NULL;
- }
- set_bit(TTY_IO_ERROR, &tty->flags);
- if (tty->ldisc.flush_buffer)
- (tty->ldisc.flush_buffer)(tty);
-
- tty->closing = 0;
- portp->tty = (struct tty_struct *) NULL;
-
- if (portp->openwaitcnt) {
- if (portp->close_delay)
- stl_delay(portp->close_delay);
- wake_up_interruptible(&portp->open_wait);
- }
-
- portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE |
- ASYNC_CLOSING);
- wake_up_interruptible(&portp->close_wait);
- MOD_DEC_USE_COUNT;
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Wait for a specified delay period, this is not a busy-loop. It will
- * give up the processor while waiting. Unfortunately this has some
- * rather intimate knowledge of the process management stuff.
- */
-
-static void stl_delay(int len)
-{
-#if DEBUG
- printk("stl_delay(len=%d)\n", len);
-#endif
- if (len > 0) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(len);
- current->state = TASK_RUNNING;
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Write routine. Take data and stuff it in to the TX ring queue.
- * If transmit interrupts are not running then start them.
- */
-
-static int stl_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
-{
- stlport_t *portp;
- unsigned int len, stlen;
- unsigned char *chbuf;
- char *head, *tail;
-
-#if DEBUG
- printk("stl_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
- (int) tty, from_user, (int) buf, count);
-#endif
-
- if ((tty == (struct tty_struct *) NULL) ||
- (stl_tmpwritebuf == (char *) NULL))
- return(0);
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return(0);
- if (portp->tx.buf == (char *) NULL)
- return(0);
-
-/*
- * If copying direct from user space we must cater for page faults,
- * causing us to "sleep" here for a while. To handle this copy in all
- * the data we need now, into a local buffer. Then when we got it all
- * copy it into the TX buffer.
- */
- chbuf = (unsigned char *) buf;
- if (from_user) {
- head = portp->tx.head;
- tail = portp->tx.tail;
- len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) :
- (tail - head - 1);
- count = MIN(len, count);
-
- down(&stl_tmpwritesem);
- copy_from_user(stl_tmpwritebuf, chbuf, count);
- chbuf = &stl_tmpwritebuf[0];
- }
-
- head = portp->tx.head;
- tail = portp->tx.tail;
- if (head >= tail) {
- len = STL_TXBUFSIZE - (head - tail) - 1;
- stlen = STL_TXBUFSIZE - (head - portp->tx.buf);
- } else {
- len = tail - head - 1;
- stlen = len;
- }
-
- len = MIN(len, count);
- count = 0;
- while (len > 0) {
- stlen = MIN(len, stlen);
- memcpy(head, chbuf, stlen);
- len -= stlen;
- chbuf += stlen;
- count += stlen;
- head += stlen;
- if (head >= (portp->tx.buf + STL_TXBUFSIZE)) {
- head = portp->tx.buf;
- stlen = tail - head;
- }
- }
- portp->tx.head = head;
-
- clear_bit(ASYI_TXLOW, &portp->istate);
- stl_startrxtx(portp, -1, 1);
-
- if (from_user)
- up(&stl_tmpwritesem);
-
- return(count);
-}
-
-/*****************************************************************************/
-
-static void stl_putchar(struct tty_struct *tty, unsigned char ch)
-{
- stlport_t *portp;
- unsigned int len;
- char *head, *tail;
-
-#if DEBUG
- printk("stl_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
- if (portp->tx.buf == (char *) NULL)
- return;
-
- head = portp->tx.head;
- tail = portp->tx.tail;
-
- len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail)) : (tail - head);
- len--;
-
- if (len > 0) {
- *head++ = ch;
- if (head >= (portp->tx.buf + STL_TXBUFSIZE))
- head = portp->tx.buf;
- }
- portp->tx.head = head;
-}
-
-/*****************************************************************************/
-
-/*
- * If there are any characters in the buffer then make sure that TX
- * interrupts are on and get'em out. Normally used after the putchar
- * routine has been called.
- */
-
-static void stl_flushchars(struct tty_struct *tty)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_flushchars(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
- if (portp->tx.buf == (char *) NULL)
- return;
-
-#if 0
- if (tty->stopped || tty->hw_stopped ||
- (portp->tx.head == portp->tx.tail))
- return;
-#endif
- stl_startrxtx(portp, -1, 1);
-}
-
-/*****************************************************************************/
-
-static int stl_writeroom(struct tty_struct *tty)
-{
- stlport_t *portp;
- char *head, *tail;
-
-#if DEBUG
- printk("stl_writeroom(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return(0);
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return(0);
- if (portp->tx.buf == (char *) NULL)
- return(0);
-
- head = portp->tx.head;
- tail = portp->tx.tail;
- return((head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1));
-}
-
-/*****************************************************************************/
-
-/*
- * Return number of chars in the TX buffer. Normally we would just
- * calculate the number of chars in the buffer and return that, but if
- * the buffer is empty and TX interrupts are still on then we return
- * that the buffer still has 1 char in it. This way whoever called us
- * will not think that ALL chars have drained - since the UART still
- * must have some chars in it (we are busy after all).
- */
-
-static int stl_charsinbuffer(struct tty_struct *tty)
-{
- stlport_t *portp;
- unsigned int size;
- char *head, *tail;
-
-#if DEBUG
- printk("stl_charsinbuffer(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return(0);
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return(0);
- if (portp->tx.buf == (char *) NULL)
- return(0);
-
- head = portp->tx.head;
- tail = portp->tx.tail;
- size = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
- if ((size == 0) && test_bit(ASYI_TXBUSY, &portp->istate))
- size = 1;
- return(size);
-}
-
-/*****************************************************************************/
-
-/*
- * Generate the serial struct info.
- */
-
-static void stl_getserial(stlport_t *portp, struct serial_struct *sp)
-{
- struct serial_struct sio;
- stlbrd_t *brdp;
-
-#if DEBUG
- printk("stl_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
-#endif
-
- memset(&sio, 0, sizeof(struct serial_struct));
- sio.line = portp->portnr;
- sio.port = portp->ioaddr;
- sio.flags = portp->flags;
- sio.baud_base = portp->baud_base;
- sio.close_delay = portp->close_delay;
- sio.closing_wait = portp->closing_wait;
- sio.custom_divisor = portp->custom_divisor;
- sio.hub6 = 0;
- if (portp->uartp == &stl_cd1400uart) {
- sio.type = PORT_CIRRUS;
- sio.xmit_fifo_size = CD1400_TXFIFOSIZE;
- } else {
- sio.type = PORT_UNKNOWN;
- sio.xmit_fifo_size = SC26198_TXFIFOSIZE;
- }
-
- brdp = stl_brds[portp->brdnr];
- if (brdp != (stlbrd_t *) NULL)
- sio.irq = brdp->irq;
-
- copy_to_user(sp, &sio, sizeof(struct serial_struct));
-}
-
-/*****************************************************************************/
-
-/*
- * Set port according to the serial struct info.
- * At this point we do not do any auto-configure stuff, so we will
- * just quietly ignore any requests to change irq, etc.
- */
-
-static int stl_setserial(stlport_t *portp, struct serial_struct *sp)
-{
- struct serial_struct sio;
-
-#if DEBUG
- printk("stl_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
-#endif
-
- copy_from_user(&sio, sp, sizeof(struct serial_struct));
- if (!capable(CAP_SYS_ADMIN)) {
- if ((sio.baud_base != portp->baud_base) ||
- (sio.close_delay != portp->close_delay) ||
- ((sio.flags & ~ASYNC_USR_MASK) !=
- (portp->flags & ~ASYNC_USR_MASK)))
- return(-EPERM);
- }
-
- portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
- (sio.flags & ASYNC_USR_MASK);
- portp->baud_base = sio.baud_base;
- portp->close_delay = sio.close_delay;
- portp->closing_wait = sio.closing_wait;
- portp->custom_divisor = sio.custom_divisor;
- stl_setport(portp, portp->tty->termios);
- return(0);
-}
-
-/*****************************************************************************/
-
-static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
-{
- stlport_t *portp;
- unsigned int ival;
- int rc;
-
-#if DEBUG
- printk("stl_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
- (int) tty, (int) file, cmd, (int) arg);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return(-ENODEV);
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return(-ENODEV);
-
- if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
- (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
- if (tty->flags & (1 << TTY_IO_ERROR))
- return(-EIO);
- }
-
- rc = 0;
-
- switch (cmd) {
- case TIOCGSOFTCAR:
- rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
- (unsigned int *) arg);
- break;
- case TIOCSSOFTCAR:
- if ((rc = verify_area(VERIFY_READ, (void *) arg,
- sizeof(int))) == 0) {
- get_user(ival, (unsigned int *) arg);
- tty->termios->c_cflag =
- (tty->termios->c_cflag & ~CLOCAL) |
- (ival ? CLOCAL : 0);
- }
- break;
- case TIOCMGET:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(unsigned int))) == 0) {
- ival = stl_getsignals(portp);
- put_user(ival, (unsigned int *) arg);
- }
- break;
- case TIOCMBIS:
- if ((rc = verify_area(VERIFY_READ, (void *) arg,
- sizeof(unsigned int))) == 0) {
- get_user(ival, (unsigned int *) arg);
- stl_setsignals(portp, ((ival & TIOCM_DTR) ? 1 : -1),
- ((ival & TIOCM_RTS) ? 1 : -1));
- }
- break;
- case TIOCMBIC:
- if ((rc = verify_area(VERIFY_READ, (void *) arg,
- sizeof(unsigned int))) == 0) {
- get_user(ival, (unsigned int *) arg);
- stl_setsignals(portp, ((ival & TIOCM_DTR) ? 0 : -1),
- ((ival & TIOCM_RTS) ? 0 : -1));
- }
- break;
- case TIOCMSET:
- if ((rc = verify_area(VERIFY_READ, (void *) arg,
- sizeof(unsigned int))) == 0) {
- get_user(ival, (unsigned int *) arg);
- stl_setsignals(portp, ((ival & TIOCM_DTR) ? 1 : 0),
- ((ival & TIOCM_RTS) ? 1 : 0));
- }
- break;
- case TIOCGSERIAL:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(struct serial_struct))) == 0)
- stl_getserial(portp, (struct serial_struct *) arg);
- break;
- case TIOCSSERIAL:
- if ((rc = verify_area(VERIFY_READ, (void *) arg,
- sizeof(struct serial_struct))) == 0)
- rc = stl_setserial(portp, (struct serial_struct *) arg);
- break;
- case COM_GETPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(comstats_t))) == 0)
- rc = stl_getportstats(portp, (comstats_t *) arg);
- break;
- case COM_CLRPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(comstats_t))) == 0)
- rc = stl_clrportstats(portp, (comstats_t *) arg);
- break;
- case TIOCSERCONFIG:
- case TIOCSERGWILD:
- case TIOCSERSWILD:
- case TIOCSERGETLSR:
- case TIOCSERGSTRUCT:
- case TIOCSERGETMULTI:
- case TIOCSERSETMULTI:
- default:
- rc = -ENOIOCTLCMD;
- break;
- }
-
- return(rc);
-}
-
-/*****************************************************************************/
-
-static void stl_settermios(struct tty_struct *tty, struct termios *old)
-{
- stlport_t *portp;
- struct termios *tiosp;
-
-#if DEBUG
- printk("stl_settermios(tty=%x,old=%x)\n", (int) tty, (int) old);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
-
- tiosp = tty->termios;
- if ((tiosp->c_cflag == old->c_cflag) &&
- (tiosp->c_iflag == old->c_iflag))
- return;
-
- stl_setport(portp, tiosp);
- stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0),
- -1);
- if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) {
- tty->hw_stopped = 0;
- stl_start(tty);
- }
- if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
- wake_up_interruptible(&portp->open_wait);
-}
-
-/*****************************************************************************/
-
-/*
- * Attempt to flow control who ever is sending us data. Based on termios
- * settings use software or/and hardware flow control.
- */
-
-static void stl_throttle(struct tty_struct *tty)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_throttle(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
- stl_flowctrl(portp, 0);
-}
-
-/*****************************************************************************/
-
-/*
- * Unflow control the device sending us data...
- */
-
-static void stl_unthrottle(struct tty_struct *tty)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_unthrottle(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
- stl_flowctrl(portp, 1);
-}
-
-/*****************************************************************************/
-
-/*
- * Stop the transmitter. Basically to do this we will just turn TX
- * interrupts off.
- */
-
-static void stl_stop(struct tty_struct *tty)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_stop(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
- stl_startrxtx(portp, -1, 0);
-}
-
-/*****************************************************************************/
-
-/*
- * Start the transmitter again. Just turn TX interrupts back on.
- */
-
-static void stl_start(struct tty_struct *tty)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_start(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
- stl_startrxtx(portp, -1, 1);
-}
-
-/*****************************************************************************/
-
-/*
- * Hangup this port. This is pretty much like closing the port, only
- * a little more brutal. No waiting for data to drain. Shutdown the
- * port and maybe drop signals.
- */
-
-static void stl_hangup(struct tty_struct *tty)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_hangup(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
-
- portp->flags &= ~ASYNC_INITIALIZED;
- stl_disableintrs(portp);
- if (tty->termios->c_cflag & HUPCL)
- stl_setsignals(portp, 0, 0);
- stl_enablerxtx(portp, 0, 0);
- stl_flushbuffer(tty);
- portp->istate = 0;
- set_bit(TTY_IO_ERROR, &tty->flags);
- if (portp->tx.buf != (char *) NULL) {
- kfree(portp->tx.buf);
- portp->tx.buf = (char *) NULL;
- portp->tx.head = (char *) NULL;
- portp->tx.tail = (char *) NULL;
- }
- portp->tty = (struct tty_struct *) NULL;
- portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
- portp->refcount = 0;
- wake_up_interruptible(&portp->open_wait);
-}
-
-/*****************************************************************************/
-
-static void stl_flushbuffer(struct tty_struct *tty)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_flushbuffer(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
-
- stl_flush(portp);
- wake_up_interruptible(&tty->write_wait);
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
-}
-
-/*****************************************************************************/
-
-static void stl_breakctl(struct tty_struct *tty, int state)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_breakctl(tty=%x,state=%d)\n", (int) tty, state);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
-
- stl_sendbreak(portp, ((state == -1) ? 1 : 2));
-}
-
-/*****************************************************************************/
-
-static void stl_waituntilsent(struct tty_struct *tty, int timeout)
-{
- stlport_t *portp;
- unsigned long tend;
-
-#if DEBUG
- printk("stl_waituntilsent(tty=%x,timeout=%d)\n", (int) tty, timeout);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
-
- if (timeout == 0)
- timeout = HZ;
- tend = jiffies + timeout;
-
- while (stl_datastate(portp)) {
- if (signal_pending(current))
- break;
- stl_delay(2);
- if (time_after_eq(jiffies, tend))
- break;
- }
-}
-
-/*****************************************************************************/
-
-static void stl_sendxchar(struct tty_struct *tty, char ch)
-{
- stlport_t *portp;
-
-#if DEBUG
- printk("stl_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stlport_t *) NULL)
- return;
-
- if (ch == STOP_CHAR(tty))
- stl_sendflow(portp, 0);
- else if (ch == START_CHAR(tty))
- stl_sendflow(portp, 1);
- else
- stl_putchar(tty, ch);
-}
-
-/*****************************************************************************/
-
-#define MAXLINE 80
-
-/*
- * Format info for a specified port. The line is deliberately limited
- * to 80 characters. (If it is too long it will be truncated, if too
- * short then padded with spaces).
- */
-
-static int stl_portinfo(stlport_t *portp, int portnr, char *pos)
-{
- char *sp;
- int sigs, cnt;
-
- sp = pos;
- sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
- portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
- (int) portp->stats.txtotal, (int) portp->stats.rxtotal);
-
- if (portp->stats.rxframing)
- sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
- if (portp->stats.rxparity)
- sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
- if (portp->stats.rxbreaks)
- sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
- if (portp->stats.rxoverrun)
- sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
-
- sigs = stl_getsignals(portp);
- cnt = sprintf(sp, "%s%s%s%s%s ",
- (sigs & TIOCM_RTS) ? "|RTS" : "",
- (sigs & TIOCM_CTS) ? "|CTS" : "",
- (sigs & TIOCM_DTR) ? "|DTR" : "",
- (sigs & TIOCM_CD) ? "|DCD" : "",
- (sigs & TIOCM_DSR) ? "|DSR" : "");
- *sp = ' ';
- sp += cnt;
-
- for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
- *sp++ = ' ';
- if (cnt >= MAXLINE)
- pos[(MAXLINE - 2)] = '+';
- pos[(MAXLINE - 1)] = '\n';
-
- return(MAXLINE);
-}
-
-/*****************************************************************************/
-
-/*
- * Port info, read from the /proc file system.
- */
-
-static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- stlbrd_t *brdp;
- stlpanel_t *panelp;
- stlport_t *portp;
- int brdnr, panelnr, portnr, totalport;
- int curoff, maxoff;
- char *pos;
-
-#if DEBUG
- printk("stl_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x,"
- "data=%x\n", (int) page, (int) start, (int) off, count,
- (int) eof, (int) data);
-#endif
-
- pos = page;
- totalport = 0;
- curoff = 0;
-
- if (off == 0) {
- pos += sprintf(pos, "%s: version %s", stl_drvtitle,
- stl_drvversion);
- while (pos < (page + MAXLINE - 1))
- *pos++ = ' ';
- *pos++ = '\n';
- }
- curoff = MAXLINE;
-
-/*
- * We scan through for each board, panel and port. The offset is
- * calculated on the fly, and irrelevant ports are skipped.
- */
- for (brdnr = 0; (brdnr < stl_nrbrds); brdnr++) {
- brdp = stl_brds[brdnr];
- if (brdp == (stlbrd_t *) NULL)
- continue;
- if (brdp->state == 0)
- continue;
-
- maxoff = curoff + (brdp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- continue;
- }
-
- totalport = brdnr * STL_MAXPORTS;
- for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
- panelp = brdp->panels[panelnr];
- if (panelp == (stlpanel_t *) NULL)
- continue;
-
- maxoff = curoff + (panelp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- totalport += panelp->nrports;
- continue;
- }
-
- for (portnr = 0; (portnr < panelp->nrports); portnr++,
- totalport++) {
- portp = panelp->ports[portnr];
- if (portp == (stlport_t *) NULL)
- continue;
- if (off >= (curoff += MAXLINE))
- continue;
- if ((pos - page + MAXLINE) > count)
- goto stl_readdone;
- pos += stl_portinfo(portp, totalport, pos);
- }
- }
- }
-
- *eof = 1;
-
-stl_readdone:
- *start = page;
- return(pos - page);
-}
-
-/*****************************************************************************/
-
-/*
- * All board interrupts are vectored through here first. This code then
- * calls off to the approrpriate board interrupt handlers.
- */
-
-static void stl_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
- stlbrd_t *brdp;
- int i;
-
-#if DEBUG
- printk("stl_intr(irq=%d,regs=%x)\n", irq, (int) regs);
-#endif
-
- for (i = 0; (i < stl_nrbrds); i++) {
- if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
- continue;
- if (brdp->state == 0)
- continue;
- (* brdp->isr)(brdp);
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for EasyIO board types.
- */
-
-static void stl_eiointr(stlbrd_t *brdp)
-{
- stlpanel_t *panelp;
- unsigned int iobase;
-
- panelp = brdp->panels[0];
- iobase = panelp->iobase;
- while (inb(brdp->iostatus) & EIO_INTRPEND)
- (* panelp->isr)(panelp, iobase);
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for ECH-AT board types.
- */
-
-static void stl_echatintr(stlbrd_t *brdp)
-{
- stlpanel_t *panelp;
- unsigned int ioaddr;
- int bnknr;
-
- outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
-
- while (inb(brdp->iostatus) & ECH_INTRPEND) {
- for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
- ioaddr = brdp->bnkstataddr[bnknr];
- if (inb(ioaddr) & ECH_PNLINTRPEND) {
- panelp = brdp->bnk2panel[bnknr];
- (* panelp->isr)(panelp, (ioaddr & 0xfffc));
- }
- }
- }
-
- outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for ECH-MCA board types.
- */
-
-static void stl_echmcaintr(stlbrd_t *brdp)
-{
- stlpanel_t *panelp;
- unsigned int ioaddr;
- int bnknr;
-
- while (inb(brdp->iostatus) & ECH_INTRPEND) {
- for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
- ioaddr = brdp->bnkstataddr[bnknr];
- if (inb(ioaddr) & ECH_PNLINTRPEND) {
- panelp = brdp->bnk2panel[bnknr];
- (* panelp->isr)(panelp, (ioaddr & 0xfffc));
- }
- }
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for ECH-PCI board types.
- */
-
-static void stl_echpciintr(stlbrd_t *brdp)
-{
- stlpanel_t *panelp;
- unsigned int ioaddr;
- int bnknr, recheck;
-
- while (1) {
- recheck = 0;
- for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
- outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl);
- ioaddr = brdp->bnkstataddr[bnknr];
- if (inb(ioaddr) & ECH_PNLINTRPEND) {
- panelp = brdp->bnk2panel[bnknr];
- (* panelp->isr)(panelp, (ioaddr & 0xfffc));
- recheck++;
- }
- }
- if (! recheck)
- break;
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for ECH-8/64-PCI board types.
- */
-
-static void stl_echpci64intr(stlbrd_t *brdp)
-{
- stlpanel_t *panelp;
- unsigned int ioaddr;
- int bnknr;
-
- while (inb(brdp->ioctrl) & 0x1) {
- for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
- ioaddr = brdp->bnkstataddr[bnknr];
- if (inb(ioaddr) & ECH_PNLINTRPEND) {
- panelp = brdp->bnk2panel[bnknr];
- (* panelp->isr)(panelp, (ioaddr & 0xfffc));
- }
- }
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Service an off-level request for some channel.
- */
-static void stl_offintr(void *private)
-{
- stlport_t *portp;
- struct tty_struct *tty;
- unsigned int oldsigs;
-
- portp = private;
-
-#if DEBUG
- printk("stl_offintr(portp=%x)\n", (int) portp);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
-
- tty = portp->tty;
- if (tty == (struct tty_struct *) NULL)
- return;
-
- lock_kernel();
- if (test_bit(ASYI_TXLOW, &portp->istate)) {
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
- wake_up_interruptible(&tty->write_wait);
- }
- if (test_bit(ASYI_DCDCHANGE, &portp->istate)) {
- clear_bit(ASYI_DCDCHANGE, &portp->istate);
- oldsigs = portp->sigs;
- portp->sigs = stl_getsignals(portp);
- if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
- wake_up_interruptible(&portp->open_wait);
- if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
- if (portp->flags & ASYNC_CHECK_CD) {
- if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
- (portp->flags & ASYNC_CALLOUT_NOHUP))) {
- tty_hangup(tty);
- }
- }
- }
- }
- unlock_kernel();
-}
-
-/*****************************************************************************/
-
-/*
- * Map in interrupt vector to this driver. Check that we don't
- * already have this vector mapped, we might be sharing this
- * interrupt across multiple boards.
- */
-
-static int __init stl_mapirq(int irq, char *name)
-{
- int rc, i;
-
-#if DEBUG
- printk("stl_mapirq(irq=%d,name=%s)\n", irq, name);
-#endif
-
- rc = 0;
- for (i = 0; (i < stl_numintrs); i++) {
- if (stl_gotintrs[i] == irq)
- break;
- }
- if (i >= stl_numintrs) {
- if (request_irq(irq, stl_intr, SA_SHIRQ, name, NULL) != 0) {
- printk("STALLION: failed to register interrupt "
- "routine for %s irq=%d\n", name, irq);
- rc = -ENODEV;
- } else {
- stl_gotintrs[stl_numintrs++] = irq;
- }
- }
- return(rc);
-}
-
-/*****************************************************************************/
-
-/*
- * Initialize all the ports on a panel.
- */
-
-static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
-{
- stlport_t *portp;
- int chipmask, i;
-
-#if DEBUG
- printk("stl_initports(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
-#endif
-
- chipmask = stl_panelinit(brdp, panelp);
-
-/*
- * All UART's are initialized (if found!). Now go through and setup
- * each ports data structures.
- */
- for (i = 0; (i < panelp->nrports); i++) {
- portp = (stlport_t *) stl_memalloc(sizeof(stlport_t));
- if (portp == (stlport_t *) NULL) {
- printk("STALLION: failed to allocate memory "
- "(size=%d)\n", sizeof(stlport_t));
- break;
- }
- memset(portp, 0, sizeof(stlport_t));
-
- portp->magic = STL_PORTMAGIC;
- portp->portnr = i;
- portp->brdnr = panelp->brdnr;
- portp->panelnr = panelp->panelnr;
- portp->uartp = panelp->uartp;
- portp->clk = brdp->clk;
- portp->baud_base = STL_BAUDBASE;
- portp->close_delay = STL_CLOSEDELAY;
- portp->closing_wait = 30 * HZ;
- portp->normaltermios = stl_deftermios;
- portp->callouttermios = stl_deftermios;
- portp->tqueue.routine = stl_offintr;
- portp->tqueue.data = portp;
- init_waitqueue_head(&portp->open_wait);
- init_waitqueue_head(&portp->close_wait);
- portp->stats.brd = portp->brdnr;
- portp->stats.panel = portp->panelnr;
- portp->stats.port = portp->portnr;
- panelp->ports[i] = portp;
- stl_portinit(brdp, panelp, portp);
- }
-
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Try to find and initialize an EasyIO board.
- */
-
-static inline int stl_initeio(stlbrd_t *brdp)
-{
- stlpanel_t *panelp;
- unsigned int status;
- char *name;
- int rc;
-
-#if DEBUG
- printk("stl_initeio(brdp=%x)\n", (int) brdp);
-#endif
-
- brdp->ioctrl = brdp->ioaddr1 + 1;
- brdp->iostatus = brdp->ioaddr1 + 2;
-
- status = inb(brdp->iostatus);
- if ((status & EIO_IDBITMASK) == EIO_MK3)
- brdp->ioctrl++;
-
-/*
- * Handle board specific stuff now. The real difference is PCI
- * or not PCI.
- */
- if (brdp->brdtype == BRD_EASYIOPCI) {
- brdp->iosize1 = 0x80;
- brdp->iosize2 = 0x80;
- name = "serial(EIO-PCI)";
- outb(0x41, (brdp->ioaddr2 + 0x4c));
- } else {
- brdp->iosize1 = 8;
- name = "serial(EIO)";
- if ((brdp->irq < 0) || (brdp->irq > 15) ||
- (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
- printk("STALLION: invalid irq=%d for brd=%d\n",
- brdp->irq, brdp->brdnr);
- return(-EINVAL);
- }
- outb((stl_vecmap[brdp->irq] | EIO_0WS |
- ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)),
- brdp->ioctrl);
- }
-
- if (check_region(brdp->ioaddr1, brdp->iosize1)) {
- printk("STALLION: Warning, board %d I/O address %x conflicts "
- "with another device\n", brdp->brdnr, brdp->ioaddr1);
- }
- if (brdp->iosize2 > 0) {
- if (check_region(brdp->ioaddr2, brdp->iosize2)) {
- printk("STALLION: Warning, board %d I/O address %x "
- "conflicts with another device\n",
- brdp->brdnr, brdp->ioaddr2);
- }
- }
-
-/*
- * Everything looks OK, so let's go ahead and probe for the hardware.
- */
- brdp->clk = CD1400_CLK;
- brdp->isr = stl_eiointr;
-
- switch (status & EIO_IDBITMASK) {
- case EIO_8PORTM:
- brdp->clk = CD1400_CLK8M;
- /* fall thru */
- case EIO_8PORTRS:
- case EIO_8PORTDI:
- brdp->nrports = 8;
- break;
- case EIO_4PORTRS:
- brdp->nrports = 4;
- break;
- case EIO_MK3:
- switch (status & EIO_BRDMASK) {
- case ID_BRD4:
- brdp->nrports = 4;
- break;
- case ID_BRD8:
- brdp->nrports = 8;
- break;
- case ID_BRD16:
- brdp->nrports = 16;
- break;
- default:
- return(-ENODEV);
- }
- break;
- default:
- return(-ENODEV);
- }
-
-/*
- * We have verfied that the board is actually present, so now we
- * can complete the setup.
- */
- request_region(brdp->ioaddr1, brdp->iosize1, name);
- if (brdp->iosize2 > 0)
- request_region(brdp->ioaddr2, brdp->iosize2, name);
-
- panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
- if (panelp == (stlpanel_t *) NULL) {
- printk("STALLION: failed to allocate memory (size=%d)\n",
- sizeof(stlpanel_t));
- return(-ENOMEM);
- }
- memset(panelp, 0, sizeof(stlpanel_t));
-
- panelp->magic = STL_PANELMAGIC;
- panelp->brdnr = brdp->brdnr;
- panelp->panelnr = 0;
- panelp->nrports = brdp->nrports;
- panelp->iobase = brdp->ioaddr1;
- panelp->hwid = status;
- if ((status & EIO_IDBITMASK) == EIO_MK3) {
- panelp->uartp = (void *) &stl_sc26198uart;
- panelp->isr = stl_sc26198intr;
- } else {
- panelp->uartp = (void *) &stl_cd1400uart;
- panelp->isr = stl_cd1400eiointr;
- }
-
- brdp->panels[0] = panelp;
- brdp->nrpanels = 1;
- brdp->state |= BRD_FOUND;
- brdp->hwid = status;
- rc = stl_mapirq(brdp->irq, name);
- return(rc);
-}
-
-/*****************************************************************************/
-
-/*
- * Try to find an ECH board and initialize it. This code is capable of
- * dealing with all types of ECH board.
- */
-
-static int inline stl_initech(stlbrd_t *brdp)
-{
- stlpanel_t *panelp;
- unsigned int status, nxtid, ioaddr, conflict;
- int panelnr, banknr, i;
- char *name;
-
-#if DEBUG
- printk("stl_initech(brdp=%x)\n", (int) brdp);
-#endif
-
- status = 0;
- conflict = 0;
-
-/*
- * Set up the initial board register contents for boards. This varies a
- * bit between the different board types. So we need to handle each
- * separately. Also do a check that the supplied IRQ is good.
- */
- switch (brdp->brdtype) {
-
- case BRD_ECH:
- brdp->isr = stl_echatintr;
- brdp->ioctrl = brdp->ioaddr1 + 1;
- brdp->iostatus = brdp->ioaddr1 + 1;
- status = inb(brdp->iostatus);
- if ((status & ECH_IDBITMASK) != ECH_ID)
- return(-ENODEV);
- if ((brdp->irq < 0) || (brdp->irq > 15) ||
- (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
- printk("STALLION: invalid irq=%d for brd=%d\n",
- brdp->irq, brdp->brdnr);
- return(-EINVAL);
- }
- status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1);
- status |= (stl_vecmap[brdp->irq] << 1);
- outb((status | ECH_BRDRESET), brdp->ioaddr1);
- brdp->ioctrlval = ECH_INTENABLE |
- ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE);
- for (i = 0; (i < 10); i++)
- outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
- brdp->iosize1 = 2;
- brdp->iosize2 = 32;
- name = "serial(EC8/32)";
- outb(status, brdp->ioaddr1);
- break;
-
- case BRD_ECHMC:
- brdp->isr = stl_echmcaintr;
- brdp->ioctrl = brdp->ioaddr1 + 0x20;
- brdp->iostatus = brdp->ioctrl;
- status = inb(brdp->iostatus);
- if ((status & ECH_IDBITMASK) != ECH_ID)
- return(-ENODEV);
- if ((brdp->irq < 0) || (brdp->irq > 15) ||
- (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
- printk("STALLION: invalid irq=%d for brd=%d\n",
- brdp->irq, brdp->brdnr);
- return(-EINVAL);
- }
- outb(ECHMC_BRDRESET, brdp->ioctrl);
- outb(ECHMC_INTENABLE, brdp->ioctrl);
- brdp->iosize1 = 64;
- name = "serial(EC8/32-MC)";
- break;
-
- case BRD_ECHPCI:
- brdp->isr = stl_echpciintr;
- brdp->ioctrl = brdp->ioaddr1 + 2;
- brdp->iosize1 = 4;
- brdp->iosize2 = 8;
- name = "serial(EC8/32-PCI)";
- break;
-
- case BRD_ECH64PCI:
- brdp->isr = stl_echpci64intr;
- brdp->ioctrl = brdp->ioaddr2 + 0x40;
- outb(0x43, (brdp->ioaddr1 + 0x4c));
- brdp->iosize1 = 0x80;
- brdp->iosize2 = 0x80;
- name = "serial(EC8/64-PCI)";
- break;
-
- default:
- printk("STALLION: unknown board type=%d\n", brdp->brdtype);
- return(-EINVAL);
- break;
- }
-
-/*
- * Check boards for possible IO address conflicts. We won't actually
- * do anything about it here, just issue a warning...
- */
- conflict = check_region(brdp->ioaddr1, brdp->iosize1) ?
- brdp->ioaddr1 : 0;
- if ((conflict == 0) && (brdp->iosize2 > 0))
- conflict = check_region(brdp->ioaddr2, brdp->iosize2) ?
- brdp->ioaddr2 : 0;
- if (conflict) {
- printk("STALLION: Warning, board %d I/O address %x conflicts "
- "with another device\n", brdp->brdnr, conflict);
- }
-
- request_region(brdp->ioaddr1, brdp->iosize1, name);
- if (brdp->iosize2 > 0)
- request_region(brdp->ioaddr2, brdp->iosize2, name);
-
-/*
- * Scan through the secondary io address space looking for panels.
- * As we find'em allocate and initialize panel structures for each.
- */
- brdp->clk = CD1400_CLK;
- brdp->hwid = status;
-
- ioaddr = brdp->ioaddr2;
- banknr = 0;
- panelnr = 0;
- nxtid = 0;
-
- for (i = 0; (i < STL_MAXPANELS); i++) {
- if (brdp->brdtype == BRD_ECHPCI) {
- outb(nxtid, brdp->ioctrl);
- ioaddr = brdp->ioaddr2;
- }
- status = inb(ioaddr + ECH_PNLSTATUS);
- if ((status & ECH_PNLIDMASK) != nxtid)
- break;
- panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
- if (panelp == (stlpanel_t *) NULL) {
- printk("STALLION: failed to allocate memory "
- "(size=%d)\n", sizeof(stlpanel_t));
- break;
- }
- memset(panelp, 0, sizeof(stlpanel_t));
- panelp->magic = STL_PANELMAGIC;
- panelp->brdnr = brdp->brdnr;
- panelp->panelnr = panelnr;
- panelp->iobase = ioaddr;
- panelp->pagenr = nxtid;
- panelp->hwid = status;
- brdp->bnk2panel[banknr] = panelp;
- brdp->bnkpageaddr[banknr] = nxtid;
- brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS;
-
- if (status & ECH_PNLXPID) {
- panelp->uartp = (void *) &stl_sc26198uart;
- panelp->isr = stl_sc26198intr;
- if (status & ECH_PNL16PORT) {
- panelp->nrports = 16;
- brdp->bnk2panel[banknr] = panelp;
- brdp->bnkpageaddr[banknr] = nxtid;
- brdp->bnkstataddr[banknr++] = ioaddr + 4 +
- ECH_PNLSTATUS;
- } else {
- panelp->nrports = 8;
- }
- } else {
- panelp->uartp = (void *) &stl_cd1400uart;
- panelp->isr = stl_cd1400echintr;
- if (status & ECH_PNL16PORT) {
- panelp->nrports = 16;
- panelp->ackmask = 0x80;
- if (brdp->brdtype != BRD_ECHPCI)
- ioaddr += EREG_BANKSIZE;
- brdp->bnk2panel[banknr] = panelp;
- brdp->bnkpageaddr[banknr] = ++nxtid;
- brdp->bnkstataddr[banknr++] = ioaddr +
- ECH_PNLSTATUS;
- } else {
- panelp->nrports = 8;
- panelp->ackmask = 0xc0;
- }
- }
-
- nxtid++;
- ioaddr += EREG_BANKSIZE;
- brdp->nrports += panelp->nrports;
- brdp->panels[panelnr++] = panelp;
- if ((brdp->brdtype != BRD_ECHPCI) &&
- (ioaddr >= (brdp->ioaddr2 + brdp->iosize2)))
- break;
- }
-
- brdp->nrpanels = panelnr;
- brdp->nrbnks = banknr;
- if (brdp->brdtype == BRD_ECH)
- outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
-
- brdp->state |= BRD_FOUND;
- i = stl_mapirq(brdp->irq, name);
- return(i);
-}
-
-/*****************************************************************************/
-
-/*
- * Initialize and configure the specified board.
- * Scan through all the boards in the configuration and see what we
- * can find. Handle EIO and the ECH boards a little differently here
- * since the initial search and setup is very different.
- */
-
-static int __init stl_brdinit(stlbrd_t *brdp)
-{
- int i;
-
-#if DEBUG
- printk("stl_brdinit(brdp=%x)\n", (int) brdp);
-#endif
-
- switch (brdp->brdtype) {
- case BRD_EASYIO:
- case BRD_EASYIOPCI:
- stl_initeio(brdp);
- break;
- case BRD_ECH:
- case BRD_ECHMC:
- case BRD_ECHPCI:
- case BRD_ECH64PCI:
- stl_initech(brdp);
- break;
- default:
- printk("STALLION: board=%d is unknown board type=%d\n",
- brdp->brdnr, brdp->brdtype);
- return(ENODEV);
- }
-
- stl_brds[brdp->brdnr] = brdp;
- if ((brdp->state & BRD_FOUND) == 0) {
- printk("STALLION: %s board not found, board=%d io=%x irq=%d\n",
- stl_brdnames[brdp->brdtype], brdp->brdnr,
- brdp->ioaddr1, brdp->irq);
- return(ENODEV);
- }
-
- for (i = 0; (i < STL_MAXPANELS); i++)
- if (brdp->panels[i] != (stlpanel_t *) NULL)
- stl_initports(brdp, brdp->panels[i]);
-
- printk("STALLION: %s found, board=%d io=%x irq=%d "
- "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype],
- brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels,
- brdp->nrports);
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Find the next available board number that is free.
- */
-
-static inline int stl_getbrdnr()
-{
- int i;
-
- for (i = 0; (i < STL_MAXBRDS); i++) {
- if (stl_brds[i] == (stlbrd_t *) NULL) {
- if (i >= stl_nrbrds)
- stl_nrbrds = i + 1;
- return(i);
- }
- }
- return(-1);
-}
-
-/*****************************************************************************/
-
-#ifdef CONFIG_PCI
-
-/*
- * We have a Stallion board. Allocate a board structure and
- * initialize it. Read its IO and IRQ resources from PCI
- * configuration space.
- */
-
-static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
-{
- stlbrd_t *brdp;
-
-#if DEBUG
- printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype,
- devp->bus->number, devp->devfn);
-#endif
-
- if (pci_enable_device(devp))
- return(-EIO);
- if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
- return(-ENOMEM);
- if ((brdp->brdnr = stl_getbrdnr()) < 0) {
- printk("STALLION: too many boards found, "
- "maximum supported %d\n", STL_MAXBRDS);
- return(0);
- }
- brdp->brdtype = brdtype;
-
-/*
- * Different Stallion boards use the BAR registers in different ways,
- * so set up io addresses based on board type.
- */
-#if DEBUG
- printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__,
- pci_resource_start(devp, 0), pci_resource_start(devp, 1),
- pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq);
-#endif
-
-/*
- * We have all resources from the board, so let's setup the actual
- * board structure now.
- */
- switch (brdtype) {
- case BRD_ECHPCI:
- brdp->ioaddr2 = pci_resource_start(devp, 0);
- brdp->ioaddr1 = pci_resource_start(devp, 1);
- break;
- case BRD_ECH64PCI:
- brdp->ioaddr2 = pci_resource_start(devp, 2);
- brdp->ioaddr1 = pci_resource_start(devp, 1);
- break;
- case BRD_EASYIOPCI:
- brdp->ioaddr1 = pci_resource_start(devp, 2);
- brdp->ioaddr2 = pci_resource_start(devp, 1);
- break;
- default:
- printk("STALLION: unknown PCI board type=%d\n", brdtype);
- break;
- }
-
- brdp->irq = devp->irq;
- stl_brdinit(brdp);
-
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Find all Stallion PCI boards that might be installed. Initialize each
- * one as it is found.
- */
-
-
-static inline int stl_findpcibrds()
-{
- struct pci_dev *dev = NULL;
- int i, rc;
-
-#if DEBUG
- printk("stl_findpcibrds()\n");
-#endif
-
- if (! pci_present())
- return(0);
-
- for (i = 0; (i < stl_nrpcibrds); i++)
- while ((dev = pci_find_device(stl_pcibrds[i].vendid,
- stl_pcibrds[i].devid, dev))) {
-
-/*
- * Found a device on the PCI bus that has our vendor and
- * device ID. Need to check now that it is really us.
- */
- if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
- continue;
-
- rc = stl_initpcibrd(stl_pcibrds[i].brdtype, dev);
- if (rc)
- return(rc);
- }
-
- return(0);
-}
-
-#endif
-
-/*****************************************************************************/
-
-/*
- * Scan through all the boards in the configuration and see what we
- * can find. Handle EIO and the ECH boards a little differently here
- * since the initial search and setup is too different.
- */
-
-static inline int stl_initbrds()
-{
- stlbrd_t *brdp;
- stlconf_t *confp;
- int i;
-
-#if DEBUG
- printk("stl_initbrds()\n");
-#endif
-
- if (stl_nrbrds > STL_MAXBRDS) {
- printk("STALLION: too many boards in configuration table, "
- "truncating to %d\n", STL_MAXBRDS);
- stl_nrbrds = STL_MAXBRDS;
- }
-
-/*
- * Firstly scan the list of static boards configured. Allocate
- * resources and initialize the boards as found.
- */
- for (i = 0; (i < stl_nrbrds); i++) {
- confp = &stl_brdconf[i];
-#ifdef MODULE
- stl_parsebrd(confp, stl_brdsp[i]);
-#endif
- if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
- return(-ENOMEM);
- brdp->brdnr = i;
- brdp->brdtype = confp->brdtype;
- brdp->ioaddr1 = confp->ioaddr1;
- brdp->ioaddr2 = confp->ioaddr2;
- brdp->irq = confp->irq;
- brdp->irqtype = confp->irqtype;
- stl_brdinit(brdp);
- }
-
-/*
- * Find any dynamically supported boards. That is via module load
- * line options or auto-detected on the PCI bus.
- */
-#ifdef MODULE
- stl_argbrds();
-#endif
-#ifdef CONFIG_PCI
- stl_findpcibrds();
-#endif
-
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the board stats structure to user app.
- */
-
-static int stl_getbrdstats(combrd_t *bp)
-{
- stlbrd_t *brdp;
- stlpanel_t *panelp;
- int i;
-
- copy_from_user(&stl_brdstats, bp, sizeof(combrd_t));
- if (stl_brdstats.brd >= STL_MAXBRDS)
- return(-ENODEV);
- brdp = stl_brds[stl_brdstats.brd];
- if (brdp == (stlbrd_t *) NULL)
- return(-ENODEV);
-
- memset(&stl_brdstats, 0, sizeof(combrd_t));
- stl_brdstats.brd = brdp->brdnr;
- stl_brdstats.type = brdp->brdtype;
- stl_brdstats.hwid = brdp->hwid;
- stl_brdstats.state = brdp->state;
- stl_brdstats.ioaddr = brdp->ioaddr1;
- stl_brdstats.ioaddr2 = brdp->ioaddr2;
- stl_brdstats.irq = brdp->irq;
- stl_brdstats.nrpanels = brdp->nrpanels;
- stl_brdstats.nrports = brdp->nrports;
- for (i = 0; (i < brdp->nrpanels); i++) {
- panelp = brdp->panels[i];
- stl_brdstats.panels[i].panel = i;
- stl_brdstats.panels[i].hwid = panelp->hwid;
- stl_brdstats.panels[i].nrports = panelp->nrports;
- }
-
- copy_to_user(bp, &stl_brdstats, sizeof(combrd_t));
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Resolve the referenced port number into a port struct pointer.
- */
-
-static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
-{
- stlbrd_t *brdp;
- stlpanel_t *panelp;
-
- if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
- return((stlport_t *) NULL);
- brdp = stl_brds[brdnr];
- if (brdp == (stlbrd_t *) NULL)
- return((stlport_t *) NULL);
- if ((panelnr < 0) || (panelnr >= brdp->nrpanels))
- return((stlport_t *) NULL);
- panelp = brdp->panels[panelnr];
- if (panelp == (stlpanel_t *) NULL)
- return((stlport_t *) NULL);
- if ((portnr < 0) || (portnr >= panelp->nrports))
- return((stlport_t *) NULL);
- return(panelp->ports[portnr]);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the port stats structure to user app. A NULL port struct
- * pointer passed in means that we need to find out from the app
- * what port to get stats for (used through board control device).
- */
-
-static int stl_getportstats(stlport_t *portp, comstats_t *cp)
-{
- unsigned char *head, *tail;
- unsigned long flags;
-
- if (portp == (stlport_t *) NULL) {
- copy_from_user(&stl_comstats, cp, sizeof(comstats_t));
- portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
- stl_comstats.port);
- if (portp == (stlport_t *) NULL)
- return(-ENODEV);
- }
-
- portp->stats.state = portp->istate;
- portp->stats.flags = portp->flags;
- portp->stats.hwid = portp->hwid;
-
- portp->stats.ttystate = 0;
- portp->stats.cflags = 0;
- portp->stats.iflags = 0;
- portp->stats.oflags = 0;
- portp->stats.lflags = 0;
- portp->stats.rxbuffered = 0;
-
- save_flags(flags);
- cli();
- if (portp->tty != (struct tty_struct *) NULL) {
- if (portp->tty->driver_data == portp) {
- portp->stats.ttystate = portp->tty->flags;
- portp->stats.rxbuffered = portp->tty->flip.count;
- if (portp->tty->termios != (struct termios *) NULL) {
- portp->stats.cflags = portp->tty->termios->c_cflag;
- portp->stats.iflags = portp->tty->termios->c_iflag;
- portp->stats.oflags = portp->tty->termios->c_oflag;
- portp->stats.lflags = portp->tty->termios->c_lflag;
- }
- }
- }
- restore_flags(flags);
-
- head = portp->tx.head;
- tail = portp->tx.tail;
- portp->stats.txbuffered = ((head >= tail) ? (head - tail) :
- (STL_TXBUFSIZE - (tail - head)));
-
- portp->stats.signals = (unsigned long) stl_getsignals(portp);
-
- copy_to_user(cp, &portp->stats, sizeof(comstats_t));
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Clear the port stats structure. We also return it zeroed out...
- */
-
-static int stl_clrportstats(stlport_t *portp, comstats_t *cp)
-{
- if (portp == (stlport_t *) NULL) {
- copy_from_user(&stl_comstats, cp, sizeof(comstats_t));
- portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
- stl_comstats.port);
- if (portp == (stlport_t *) NULL)
- return(-ENODEV);
- }
-
- memset(&portp->stats, 0, sizeof(comstats_t));
- portp->stats.brd = portp->brdnr;
- portp->stats.panel = portp->panelnr;
- portp->stats.port = portp->portnr;
- copy_to_user(cp, &portp->stats, sizeof(comstats_t));
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the entire driver ports structure to a user app.
- */
-
-static int stl_getportstruct(unsigned long arg)
-{
- stlport_t *portp;
-
- copy_from_user(&stl_dummyport, (void *) arg, sizeof(stlport_t));
- portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
- stl_dummyport.portnr);
- if (portp == (stlport_t *) NULL)
- return(-ENODEV);
- copy_to_user((void *) arg, portp, sizeof(stlport_t));
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the entire driver board structure to a user app.
- */
-
-static int stl_getbrdstruct(unsigned long arg)
-{
- stlbrd_t *brdp;
-
- copy_from_user(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t));
- if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
- return(-ENODEV);
- brdp = stl_brds[stl_dummybrd.brdnr];
- if (brdp == (stlbrd_t *) NULL)
- return(-ENODEV);
- copy_to_user((void *) arg, brdp, sizeof(stlbrd_t));
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * The "staliomem" device is also required to do some special operations
- * on the board and/or ports. In this driver it is mostly used for stats
- * collection.
- */
-
-static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
-{
- int brdnr, rc;
-
-#if DEBUG
- printk("stl_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip,
- (int) fp, cmd, (int) arg);
-#endif
-
- brdnr = MINOR(ip->i_rdev);
- if (brdnr >= STL_MAXBRDS)
- return(-ENODEV);
- rc = 0;
-
- switch (cmd) {
- case COM_GETPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(comstats_t))) == 0)
- rc = stl_getportstats((stlport_t *) NULL,
- (comstats_t *) arg);
- break;
- case COM_CLRPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(comstats_t))) == 0)
- rc = stl_clrportstats((stlport_t *) NULL,
- (comstats_t *) arg);
- break;
- case COM_GETBRDSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(combrd_t))) == 0)
- rc = stl_getbrdstats((combrd_t *) arg);
- break;
- case COM_READPORT:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(stlport_t))) == 0)
- rc = stl_getportstruct(arg);
- break;
- case COM_READBOARD:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(stlbrd_t))) == 0)
- rc = stl_getbrdstruct(arg);
- break;
- default:
- rc = -ENOIOCTLCMD;
- break;
- }
-
- return(rc);
-}
-
-/*****************************************************************************/
-
-int __init stl_init(void)
-{
- printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
-
- stl_initbrds();
-
-/*
- * Allocate a temporary write buffer.
- */
- stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE);
- if (stl_tmpwritebuf == (char *) NULL)
- printk("STALLION: failed to allocate memory (size=%d)\n",
- STL_TXBUFSIZE);
-
-/*
- * Set up a character driver for per board stuff. This is mainly used
- * to do stats ioctls on the ports.
- */
- if (devfs_register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
- printk("STALLION: failed to register serial board device\n");
- devfs_handle = devfs_mk_dir (NULL, "staliomem", NULL);
- devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
- STL_SIOMEMMAJOR, 0,
- S_IFCHR | S_IRUSR | S_IWUSR,
- &stl_fsiomem, NULL);
-
-/*
- * Set up the tty driver structure and register us as a driver.
- * Also setup the callout tty device.
- */
- memset(&stl_serial, 0, sizeof(struct tty_driver));
- stl_serial.magic = TTY_DRIVER_MAGIC;
- stl_serial.driver_name = stl_drvname;
- stl_serial.name = stl_serialname;
- stl_serial.major = STL_SERIALMAJOR;
- stl_serial.minor_start = 0;
- stl_serial.num = STL_MAXBRDS * STL_MAXPORTS;
- stl_serial.type = TTY_DRIVER_TYPE_SERIAL;
- stl_serial.subtype = STL_DRVTYPSERIAL;
- stl_serial.init_termios = stl_deftermios;
- stl_serial.flags = TTY_DRIVER_REAL_RAW;
- stl_serial.refcount = &stl_refcount;
- stl_serial.table = stl_ttys;
- stl_serial.termios = stl_termios;
- stl_serial.termios_locked = stl_termioslocked;
-
- stl_serial.open = stl_open;
- stl_serial.close = stl_close;
- stl_serial.write = stl_write;
- stl_serial.put_char = stl_putchar;
- stl_serial.flush_chars = stl_flushchars;
- stl_serial.write_room = stl_writeroom;
- stl_serial.chars_in_buffer = stl_charsinbuffer;
- stl_serial.ioctl = stl_ioctl;
- stl_serial.set_termios = stl_settermios;
- stl_serial.throttle = stl_throttle;
- stl_serial.unthrottle = stl_unthrottle;
- stl_serial.stop = stl_stop;
- stl_serial.start = stl_start;
- stl_serial.hangup = stl_hangup;
- stl_serial.flush_buffer = stl_flushbuffer;
- stl_serial.break_ctl = stl_breakctl;
- stl_serial.wait_until_sent = stl_waituntilsent;
- stl_serial.send_xchar = stl_sendxchar;
- stl_serial.read_proc = stl_readproc;
-
- stl_callout = stl_serial;
- stl_callout.name = stl_calloutname;
- stl_callout.major = STL_CALLOUTMAJOR;
- stl_callout.subtype = STL_DRVTYPCALLOUT;
- stl_callout.read_proc = 0;
-
- if (tty_register_driver(&stl_serial))
- printk("STALLION: failed to register serial driver\n");
- if (tty_register_driver(&stl_callout))
- printk("STALLION: failed to register callout driver\n");
-
- return(0);
-}
-
-/*****************************************************************************/
-/* CD1400 HARDWARE FUNCTIONS */
-/*****************************************************************************/
-
-/*
- * These functions get/set/update the registers of the cd1400 UARTs.
- * Access to the cd1400 registers is via an address/data io port pair.
- * (Maybe should make this inline...)
- */
-
-static int stl_cd1400getreg(stlport_t *portp, int regnr)
-{
- outb((regnr + portp->uartaddr), portp->ioaddr);
- return(inb(portp->ioaddr + EREG_DATA));
-}
-
-static void stl_cd1400setreg(stlport_t *portp, int regnr, int value)
-{
- outb((regnr + portp->uartaddr), portp->ioaddr);
- outb(value, portp->ioaddr + EREG_DATA);
-}
-
-static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value)
-{
- outb((regnr + portp->uartaddr), portp->ioaddr);
- if (inb(portp->ioaddr + EREG_DATA) != value) {
- outb(value, portp->ioaddr + EREG_DATA);
- return(1);
- }
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Inbitialize the UARTs in a panel. We don't care what sort of board
- * these ports are on - since the port io registers are almost
- * identical when dealing with ports.
- */
-
-static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
-{
- unsigned int gfrcr;
- int chipmask, i, j;
- int nrchips, uartaddr, ioaddr;
-
-#if DEBUG
- printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
-#endif
-
- BRDENABLE(panelp->brdnr, panelp->pagenr);
-
-/*
- * Check that each chip is present and started up OK.
- */
- chipmask = 0;
- nrchips = panelp->nrports / CD1400_PORTS;
- for (i = 0; (i < nrchips); i++) {
- if (brdp->brdtype == BRD_ECHPCI) {
- outb((panelp->pagenr + (i >> 1)), brdp->ioctrl);
- ioaddr = panelp->iobase;
- } else {
- ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1));
- }
- uartaddr = (i & 0x01) ? 0x080 : 0;
- outb((GFRCR + uartaddr), ioaddr);
- outb(0, (ioaddr + EREG_DATA));
- outb((CCR + uartaddr), ioaddr);
- outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
- outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
- outb((GFRCR + uartaddr), ioaddr);
- for (j = 0; (j < CCR_MAXWAIT); j++) {
- if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0)
- break;
- }
- if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) {
- printk("STALLION: cd1400 not responding, "
- "brd=%d panel=%d chip=%d\n",
- panelp->brdnr, panelp->panelnr, i);
- continue;
- }
- chipmask |= (0x1 << i);
- outb((PPR + uartaddr), ioaddr);
- outb(PPR_SCALAR, (ioaddr + EREG_DATA));
- }
-
- BRDDISABLE(panelp->brdnr);
- return(chipmask);
-}
-
-/*****************************************************************************/
-
-/*
- * Initialize hardware specific port registers.
- */
-
-static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
-{
-#if DEBUG
- printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n",
- (int) brdp, (int) panelp, (int) portp);
-#endif
-
- if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
- (portp == (stlport_t *) NULL))
- return;
-
- portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) ||
- (portp->portnr < 8)) ? 0 : EREG_BANKSIZE);
- portp->uartaddr = (portp->portnr & 0x04) << 5;
- portp->pagenr = panelp->pagenr + (portp->portnr >> 3);
-
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- stl_cd1400setreg(portp, LIVR, (portp->portnr << 3));
- portp->hwid = stl_cd1400getreg(portp, GFRCR);
- BRDDISABLE(portp->brdnr);
-}
-
-/*****************************************************************************/
-
-/*
- * Wait for the command register to be ready. We will poll this,
- * since it won't usually take too long to be ready.
- */
-
-static void stl_cd1400ccrwait(stlport_t *portp)
-{
- int i;
-
- for (i = 0; (i < CCR_MAXWAIT); i++) {
- if (stl_cd1400getreg(portp, CCR) == 0) {
- return;
- }
- }
-
- printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n",
- portp->portnr, portp->panelnr, portp->brdnr);
-}
-
-/*****************************************************************************/
-
-/*
- * Set up the cd1400 registers for a port based on the termios port
- * settings.
- */
-
-static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
-{
- stlbrd_t *brdp;
- unsigned long flags;
- unsigned int clkdiv, baudrate;
- unsigned char cor1, cor2, cor3;
- unsigned char cor4, cor5, ccr;
- unsigned char srer, sreron, sreroff;
- unsigned char mcor1, mcor2, rtpr;
- unsigned char clk, div;
-
- cor1 = 0;
- cor2 = 0;
- cor3 = 0;
- cor4 = 0;
- cor5 = 0;
- ccr = 0;
- rtpr = 0;
- clk = 0;
- div = 0;
- mcor1 = 0;
- mcor2 = 0;
- sreron = 0;
- sreroff = 0;
-
- brdp = stl_brds[portp->brdnr];
- if (brdp == (stlbrd_t *) NULL)
- return;
-
-/*
- * Set up the RX char ignore mask with those RX error types we
- * can ignore. We can get the cd1400 to help us out a little here,
- * it will ignore parity errors and breaks for us.
- */
- portp->rxignoremsk = 0;
- if (tiosp->c_iflag & IGNPAR) {
- portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN);
- cor1 |= COR1_PARIGNORE;
- }
- if (tiosp->c_iflag & IGNBRK) {
- portp->rxignoremsk |= ST_BREAK;
- cor4 |= COR4_IGNBRK;
- }
-
- portp->rxmarkmsk = ST_OVERRUN;
- if (tiosp->c_iflag & (INPCK | PARMRK))
- portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING);
- if (tiosp->c_iflag & BRKINT)
- portp->rxmarkmsk |= ST_BREAK;
-
-/*
- * Go through the char size, parity and stop bits and set all the
- * option register appropriately.
- */
- switch (tiosp->c_cflag & CSIZE) {
- case CS5:
- cor1 |= COR1_CHL5;
- break;
- case CS6:
- cor1 |= COR1_CHL6;
- break;
- case CS7:
- cor1 |= COR1_CHL7;
- break;
- default:
- cor1 |= COR1_CHL8;
- break;
- }
-
- if (tiosp->c_cflag & CSTOPB)
- cor1 |= COR1_STOP2;
- else
- cor1 |= COR1_STOP1;
-
- if (tiosp->c_cflag & PARENB) {
- if (tiosp->c_cflag & PARODD)
- cor1 |= (COR1_PARENB | COR1_PARODD);
- else
- cor1 |= (COR1_PARENB | COR1_PAREVEN);
- } else {
- cor1 |= COR1_PARNONE;
- }
-
-/*
- * Set the RX FIFO threshold at 6 chars. This gives a bit of breathing
- * space for hardware flow control and the like. This should be set to
- * VMIN. Also here we will set the RX data timeout to 10ms - this should
- * really be based on VTIME.
- */
- cor3 |= FIFO_RXTHRESHOLD;
- rtpr = 2;
-
-/*
- * Calculate the baud rate timers. For now we will just assume that
- * the input and output baud are the same. Could have used a baud
- * table here, but this way we can generate virtually any baud rate
- * we like!
- */
- baudrate = tiosp->c_cflag & CBAUD;
- if (baudrate & CBAUDEX) {
- baudrate &= ~CBAUDEX;
- if ((baudrate < 1) || (baudrate > 4))
- tiosp->c_cflag &= ~CBAUDEX;
- else
- baudrate += 15;
- }
- baudrate = stl_baudrates[baudrate];
- if ((tiosp->c_cflag & CBAUD) == B38400) {
- if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- baudrate = 57600;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- baudrate = 115200;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- baudrate = 230400;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- baudrate = 460800;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
- baudrate = (portp->baud_base / portp->custom_divisor);
- }
- if (baudrate > STL_CD1400MAXBAUD)
- baudrate = STL_CD1400MAXBAUD;
-
- if (baudrate > 0) {
- for (clk = 0; (clk < CD1400_NUMCLKS); clk++) {
- clkdiv = ((portp->clk / stl_cd1400clkdivs[clk]) / baudrate);
- if (clkdiv < 0x100)
- break;
- }
- div = (unsigned char) clkdiv;
- }
-
-/*
- * Check what form of modem signaling is required and set it up.
- */
- if ((tiosp->c_cflag & CLOCAL) == 0) {
- mcor1 |= MCOR1_DCD;
- mcor2 |= MCOR2_DCD;
- sreron |= SRER_MODEM;
- portp->flags |= ASYNC_CHECK_CD;
- } else {
- portp->flags &= ~ASYNC_CHECK_CD;
- }
-
-/*
- * Setup cd1400 enhanced modes if we can. In particular we want to
- * handle as much of the flow control as possible automatically. As
- * well as saving a few CPU cycles it will also greatly improve flow
- * control reliability.
- */
- if (tiosp->c_iflag & IXON) {
- cor2 |= COR2_TXIBE;
- cor3 |= COR3_SCD12;
- if (tiosp->c_iflag & IXANY)
- cor2 |= COR2_IXM;
- }
-
- if (tiosp->c_cflag & CRTSCTS) {
- cor2 |= COR2_CTSAE;
- mcor1 |= FIFO_RTSTHRESHOLD;
- }
-
-/*
- * All cd1400 register values calculated so go through and set
- * them all up.
- */
-
-#if DEBUG
- printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
- portp->portnr, portp->panelnr, portp->brdnr);
- printk(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n",
- cor1, cor2, cor3, cor4, cor5);
- printk(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n",
- mcor1, mcor2, rtpr, sreron, sreroff);
- printk(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
- printk(" schr1=%x schr2=%x schr3=%x schr4=%x\n",
- tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
- tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
-#endif
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3));
- srer = stl_cd1400getreg(portp, SRER);
- stl_cd1400setreg(portp, SRER, 0);
- if (stl_cd1400updatereg(portp, COR1, cor1))
- ccr = 1;
- if (stl_cd1400updatereg(portp, COR2, cor2))
- ccr = 1;
- if (stl_cd1400updatereg(portp, COR3, cor3))
- ccr = 1;
- if (ccr) {
- stl_cd1400ccrwait(portp);
- stl_cd1400setreg(portp, CCR, CCR_CORCHANGE);
- }
- stl_cd1400setreg(portp, COR4, cor4);
- stl_cd1400setreg(portp, COR5, cor5);
- stl_cd1400setreg(portp, MCOR1, mcor1);
- stl_cd1400setreg(portp, MCOR2, mcor2);
- if (baudrate > 0) {
- stl_cd1400setreg(portp, TCOR, clk);
- stl_cd1400setreg(portp, TBPR, div);
- stl_cd1400setreg(portp, RCOR, clk);
- stl_cd1400setreg(portp, RBPR, div);
- }
- stl_cd1400setreg(portp, SCHR1, tiosp->c_cc[VSTART]);
- stl_cd1400setreg(portp, SCHR2, tiosp->c_cc[VSTOP]);
- stl_cd1400setreg(portp, SCHR3, tiosp->c_cc[VSTART]);
- stl_cd1400setreg(portp, SCHR4, tiosp->c_cc[VSTOP]);
- stl_cd1400setreg(portp, RTPR, rtpr);
- mcor1 = stl_cd1400getreg(portp, MSVR1);
- if (mcor1 & MSVR1_DCD)
- portp->sigs |= TIOCM_CD;
- else
- portp->sigs &= ~TIOCM_CD;
- stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron));
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Set the state of the DTR and RTS signals.
- */
-
-static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts)
-{
- unsigned char msvr1, msvr2;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400setsignals(portp=%x,dtr=%d,rts=%d)\n",
- (int) portp, dtr, rts);
-#endif
-
- msvr1 = 0;
- msvr2 = 0;
- if (dtr > 0)
- msvr1 = MSVR1_DTR;
- if (rts > 0)
- msvr2 = MSVR2_RTS;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- if (rts >= 0)
- stl_cd1400setreg(portp, MSVR2, msvr2);
- if (dtr >= 0)
- stl_cd1400setreg(portp, MSVR1, msvr1);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the state of the signals.
- */
-
-static int stl_cd1400getsignals(stlport_t *portp)
-{
- unsigned char msvr1, msvr2;
- unsigned long flags;
- int sigs;
-
-#if DEBUG
- printk("stl_cd1400getsignals(portp=%x)\n", (int) portp);
-#endif
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- msvr1 = stl_cd1400getreg(portp, MSVR1);
- msvr2 = stl_cd1400getreg(portp, MSVR2);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-
- sigs = 0;
- sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0;
- sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0;
- sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0;
- sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0;
-#if 0
- sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0;
- sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0;
-#else
- sigs |= TIOCM_DSR;
-#endif
- return(sigs);
-}
-
-/*****************************************************************************/
-
-/*
- * Enable/Disable the Transmitter and/or Receiver.
- */
-
-static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx)
-{
- unsigned char ccr;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400enablerxtx(portp=%x,rx=%d,tx=%d)\n",
- (int) portp, rx, tx);
-#endif
- ccr = 0;
-
- if (tx == 0)
- ccr |= CCR_TXDISABLE;
- else if (tx > 0)
- ccr |= CCR_TXENABLE;
- if (rx == 0)
- ccr |= CCR_RXDISABLE;
- else if (rx > 0)
- ccr |= CCR_RXENABLE;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- stl_cd1400ccrwait(portp);
- stl_cd1400setreg(portp, CCR, ccr);
- stl_cd1400ccrwait(portp);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Start/stop the Transmitter and/or Receiver.
- */
-
-static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx)
-{
- unsigned char sreron, sreroff;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400startrxtx(portp=%x,rx=%d,tx=%d)\n",
- (int) portp, rx, tx);
-#endif
-
- sreron = 0;
- sreroff = 0;
- if (tx == 0)
- sreroff |= (SRER_TXDATA | SRER_TXEMPTY);
- else if (tx == 1)
- sreron |= SRER_TXDATA;
- else if (tx >= 2)
- sreron |= SRER_TXEMPTY;
- if (rx == 0)
- sreroff |= SRER_RXDATA;
- else if (rx > 0)
- sreron |= SRER_RXDATA;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- stl_cd1400setreg(portp, SRER,
- ((stl_cd1400getreg(portp, SRER) & ~sreroff) | sreron));
- BRDDISABLE(portp->brdnr);
- if (tx > 0)
- set_bit(ASYI_TXBUSY, &portp->istate);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Disable all interrupts from this port.
- */
-
-static void stl_cd1400disableintrs(stlport_t *portp)
-{
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp);
-#endif
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- stl_cd1400setreg(portp, SRER, 0);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-static void stl_cd1400sendbreak(stlport_t *portp, int len)
-{
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len);
-#endif
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- stl_cd1400setreg(portp, SRER,
- ((stl_cd1400getreg(portp, SRER) & ~SRER_TXDATA) |
- SRER_TXEMPTY));
- BRDDISABLE(portp->brdnr);
- portp->brklen = len;
- if (len == 1)
- portp->stats.txbreaks++;
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Take flow control actions...
- */
-
-static void stl_cd1400flowctrl(stlport_t *portp, int state)
-{
- struct tty_struct *tty;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400flowctrl(portp=%x,state=%x)\n", (int) portp, state);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
- tty = portp->tty;
- if (tty == (struct tty_struct *) NULL)
- return;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
-
- if (state) {
- if (tty->termios->c_iflag & IXOFF) {
- stl_cd1400ccrwait(portp);
- stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
- portp->stats.rxxon++;
- stl_cd1400ccrwait(portp);
- }
-/*
- * Question: should we return RTS to what it was before? It may
- * have been set by an ioctl... Suppose not, since if you have
- * hardware flow control set then it is pretty silly to go and
- * set the RTS line by hand.
- */
- if (tty->termios->c_cflag & CRTSCTS) {
- stl_cd1400setreg(portp, MCOR1,
- (stl_cd1400getreg(portp, MCOR1) |
- FIFO_RTSTHRESHOLD));
- stl_cd1400setreg(portp, MSVR2, MSVR2_RTS);
- portp->stats.rxrtson++;
- }
- } else {
- if (tty->termios->c_iflag & IXOFF) {
- stl_cd1400ccrwait(portp);
- stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
- portp->stats.rxxoff++;
- stl_cd1400ccrwait(portp);
- }
- if (tty->termios->c_cflag & CRTSCTS) {
- stl_cd1400setreg(portp, MCOR1,
- (stl_cd1400getreg(portp, MCOR1) & 0xf0));
- stl_cd1400setreg(portp, MSVR2, 0);
- portp->stats.rxrtsoff++;
- }
- }
-
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Send a flow control character...
- */
-
-static void stl_cd1400sendflow(stlport_t *portp, int state)
-{
- struct tty_struct *tty;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400sendflow(portp=%x,state=%x)\n", (int) portp, state);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
- tty = portp->tty;
- if (tty == (struct tty_struct *) NULL)
- return;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- if (state) {
- stl_cd1400ccrwait(portp);
- stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
- portp->stats.rxxon++;
- stl_cd1400ccrwait(portp);
- } else {
- stl_cd1400ccrwait(portp);
- stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
- portp->stats.rxxoff++;
- stl_cd1400ccrwait(portp);
- }
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-static void stl_cd1400flush(stlport_t *portp)
-{
- unsigned long flags;
-
-#if DEBUG
- printk("stl_cd1400flush(portp=%x)\n", (int) portp);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
- stl_cd1400ccrwait(portp);
- stl_cd1400setreg(portp, CCR, CCR_TXFLUSHFIFO);
- stl_cd1400ccrwait(portp);
- portp->tx.tail = portp->tx.head;
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the current state of data flow on this port. This is only
- * really interresting when determining if data has fully completed
- * transmission or not... This is easy for the cd1400, it accurately
- * maintains the busy port flag.
- */
-
-static int stl_cd1400datastate(stlport_t *portp)
-{
-#if DEBUG
- printk("stl_cd1400datastate(portp=%x)\n", (int) portp);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return(0);
-
- return(test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0);
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for cd1400 EasyIO boards.
- */
-
-static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase)
-{
- unsigned char svrtype;
-
-#if DEBUG
- printk("stl_cd1400eiointr(panelp=%x,iobase=%x)\n",
- (int) panelp, iobase);
-#endif
-
- outb(SVRR, iobase);
- svrtype = inb(iobase + EREG_DATA);
- if (panelp->nrports > 4) {
- outb((SVRR + 0x80), iobase);
- svrtype |= inb(iobase + EREG_DATA);
- }
-
- if (svrtype & SVRR_RX)
- stl_cd1400rxisr(panelp, iobase);
- else if (svrtype & SVRR_TX)
- stl_cd1400txisr(panelp, iobase);
- else if (svrtype & SVRR_MDM)
- stl_cd1400mdmisr(panelp, iobase);
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for cd1400 panels.
- */
-
-static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase)
-{
- unsigned char svrtype;
-
-#if DEBUG
- printk("stl_cd1400echintr(panelp=%x,iobase=%x)\n", (int) panelp,
- iobase);
-#endif
-
- outb(SVRR, iobase);
- svrtype = inb(iobase + EREG_DATA);
- outb((SVRR + 0x80), iobase);
- svrtype |= inb(iobase + EREG_DATA);
- if (svrtype & SVRR_RX)
- stl_cd1400rxisr(panelp, iobase);
- else if (svrtype & SVRR_TX)
- stl_cd1400txisr(panelp, iobase);
- else if (svrtype & SVRR_MDM)
- stl_cd1400mdmisr(panelp, iobase);
-}
-
-
-/*****************************************************************************/
-
-/*
- * Unfortunately we need to handle breaks in the TX data stream, since
- * this is the only way to generate them on the cd1400.
- */
-
-static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr)
-{
- if (portp->brklen == 1) {
- outb((COR2 + portp->uartaddr), ioaddr);
- outb((inb(ioaddr + EREG_DATA) | COR2_ETC),
- (ioaddr + EREG_DATA));
- outb((TDR + portp->uartaddr), ioaddr);
- outb(ETC_CMD, (ioaddr + EREG_DATA));
- outb(ETC_STARTBREAK, (ioaddr + EREG_DATA));
- outb((SRER + portp->uartaddr), ioaddr);
- outb((inb(ioaddr + EREG_DATA) & ~(SRER_TXDATA | SRER_TXEMPTY)),
- (ioaddr + EREG_DATA));
- return(1);
- } else if (portp->brklen > 1) {
- outb((TDR + portp->uartaddr), ioaddr);
- outb(ETC_CMD, (ioaddr + EREG_DATA));
- outb(ETC_STOPBREAK, (ioaddr + EREG_DATA));
- portp->brklen = -1;
- return(1);
- } else {
- outb((COR2 + portp->uartaddr), ioaddr);
- outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC),
- (ioaddr + EREG_DATA));
- portp->brklen = 0;
- }
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Transmit interrupt handler. This has gotta be fast! Handling TX
- * chars is pretty simple, stuff as many as possible from the TX buffer
- * into the cd1400 FIFO. Must also handle TX breaks here, since they
- * are embedded as commands in the data stream. Oh no, had to use a goto!
- * This could be optimized more, will do when I get time...
- * In practice it is possible that interrupts are enabled but that the
- * port has been hung up. Need to handle not having any TX buffer here,
- * this is done by using the side effect that head and tail will also
- * be NULL if the buffer has been freed.
- */
-
-static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr)
-{
- stlport_t *portp;
- int len, stlen;
- char *head, *tail;
- unsigned char ioack, srer;
-
-#if DEBUG
- printk("stl_cd1400txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
-#endif
-
- ioack = inb(ioaddr + EREG_TXACK);
- if (((ioack & panelp->ackmask) != 0) ||
- ((ioack & ACK_TYPMASK) != ACK_TYPTX)) {
- printk("STALLION: bad TX interrupt ack value=%x\n", ioack);
- return;
- }
- portp = panelp->ports[(ioack >> 3)];
-
-/*
- * Unfortunately we need to handle breaks in the data stream, since
- * this is the only way to generate them on the cd1400. Do it now if
- * a break is to be sent.
- */
- if (portp->brklen != 0)
- if (stl_cd1400breakisr(portp, ioaddr))
- goto stl_txalldone;
-
- head = portp->tx.head;
- tail = portp->tx.tail;
- len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
- if ((len == 0) || ((len < STL_TXBUFLOW) &&
- (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
- set_bit(ASYI_TXLOW, &portp->istate);
- queue_task(&portp->tqueue, &tq_scheduler);
- }
-
- if (len == 0) {
- outb((SRER + portp->uartaddr), ioaddr);
- srer = inb(ioaddr + EREG_DATA);
- if (srer & SRER_TXDATA) {
- srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY;
- } else {
- srer &= ~(SRER_TXDATA | SRER_TXEMPTY);
- clear_bit(ASYI_TXBUSY, &portp->istate);
- }
- outb(srer, (ioaddr + EREG_DATA));
- } else {
- len = MIN(len, CD1400_TXFIFOSIZE);
- portp->stats.txtotal += len;
- stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
- outb((TDR + portp->uartaddr), ioaddr);
- outsb((ioaddr + EREG_DATA), tail, stlen);
- len -= stlen;
- tail += stlen;
- if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
- tail = portp->tx.buf;
- if (len > 0) {
- outsb((ioaddr + EREG_DATA), tail, len);
- tail += len;
- }
- portp->tx.tail = tail;
- }
-
-stl_txalldone:
- outb((EOSRR + portp->uartaddr), ioaddr);
- outb(0, (ioaddr + EREG_DATA));
-}
-
-/*****************************************************************************/
-
-/*
- * Receive character interrupt handler. Determine if we have good chars
- * or bad chars and then process appropriately. Good chars are easy
- * just shove the lot into the RX buffer and set all status byte to 0.
- * If a bad RX char then process as required. This routine needs to be
- * fast! In practice it is possible that we get an interrupt on a port
- * that is closed. This can happen on hangups - since they completely
- * shutdown a port not in user context. Need to handle this case.
- */
-
-static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
-{
- stlport_t *portp;
- struct tty_struct *tty;
- unsigned int ioack, len, buflen;
- unsigned char status;
- char ch;
-
-#if DEBUG
- printk("stl_cd1400rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
-#endif
-
- ioack = inb(ioaddr + EREG_RXACK);
- if ((ioack & panelp->ackmask) != 0) {
- printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
- return;
- }
- portp = panelp->ports[(ioack >> 3)];
- tty = portp->tty;
-
- if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
- outb((RDCR + portp->uartaddr), ioaddr);
- len = inb(ioaddr + EREG_DATA);
- if ((tty == (struct tty_struct *) NULL) ||
- (tty->flip.char_buf_ptr == (char *) NULL) ||
- ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
- len = MIN(len, sizeof(stl_unwanted));
- outb((RDSR + portp->uartaddr), ioaddr);
- insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
- portp->stats.rxlost += len;
- portp->stats.rxtotal += len;
- } else {
- len = MIN(len, buflen);
- if (len > 0) {
- outb((RDSR + portp->uartaddr), ioaddr);
- insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len);
- memset(tty->flip.flag_buf_ptr, 0, len);
- tty->flip.flag_buf_ptr += len;
- tty->flip.char_buf_ptr += len;
- tty->flip.count += len;
- tty_schedule_flip(tty);
- portp->stats.rxtotal += len;
- }
- }
- } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) {
- outb((RDSR + portp->uartaddr), ioaddr);
- status = inb(ioaddr + EREG_DATA);
- ch = inb(ioaddr + EREG_DATA);
- if (status & ST_PARITY)
- portp->stats.rxparity++;
- if (status & ST_FRAMING)
- portp->stats.rxframing++;
- if (status & ST_OVERRUN)
- portp->stats.rxoverrun++;
- if (status & ST_BREAK)
- portp->stats.rxbreaks++;
- if (status & ST_SCHARMASK) {
- if ((status & ST_SCHARMASK) == ST_SCHAR1)
- portp->stats.txxon++;
- if ((status & ST_SCHARMASK) == ST_SCHAR2)
- portp->stats.txxoff++;
- goto stl_rxalldone;
- }
- if ((tty != (struct tty_struct *) NULL) &&
- ((portp->rxignoremsk & status) == 0)) {
- if (portp->rxmarkmsk & status) {
- if (status & ST_BREAK) {
- status = TTY_BREAK;
- if (portp->flags & ASYNC_SAK) {
- do_SAK(tty);
- BRDENABLE(portp->brdnr, portp->pagenr);
- }
- } else if (status & ST_PARITY) {
- status = TTY_PARITY;
- } else if (status & ST_FRAMING) {
- status = TTY_FRAME;
- } else if(status & ST_OVERRUN) {
- status = TTY_OVERRUN;
- } else {
- status = 0;
- }
- } else {
- status = 0;
- }
- if (tty->flip.char_buf_ptr != (char *) NULL) {
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- *tty->flip.flag_buf_ptr++ = status;
- *tty->flip.char_buf_ptr++ = ch;
- tty->flip.count++;
- }
- tty_schedule_flip(tty);
- }
- }
- } else {
- printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
- return;
- }
-
-stl_rxalldone:
- outb((EOSRR + portp->uartaddr), ioaddr);
- outb(0, (ioaddr + EREG_DATA));
-}
-
-/*****************************************************************************/
-
-/*
- * Modem interrupt handler. The is called when the modem signal line
- * (DCD) has changed state. Leave most of the work to the off-level
- * processing routine.
- */
-
-static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr)
-{
- stlport_t *portp;
- unsigned int ioack;
- unsigned char misr;
-
-#if DEBUG
- printk("stl_cd1400mdmisr(panelp=%x)\n", (int) panelp);
-#endif
-
- ioack = inb(ioaddr + EREG_MDACK);
- if (((ioack & panelp->ackmask) != 0) ||
- ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) {
- printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack);
- return;
- }
- portp = panelp->ports[(ioack >> 3)];
-
- outb((MISR + portp->uartaddr), ioaddr);
- misr = inb(ioaddr + EREG_DATA);
- if (misr & MISR_DCD) {
- set_bit(ASYI_DCDCHANGE, &portp->istate);
- queue_task(&portp->tqueue, &tq_scheduler);
- portp->stats.modem++;
- }
-
- outb((EOSRR + portp->uartaddr), ioaddr);
- outb(0, (ioaddr + EREG_DATA));
-}
-
-/*****************************************************************************/
-/* SC26198 HARDWARE FUNCTIONS */
-/*****************************************************************************/
-
-/*
- * These functions get/set/update the registers of the sc26198 UARTs.
- * Access to the sc26198 registers is via an address/data io port pair.
- * (Maybe should make this inline...)
- */
-
-static int stl_sc26198getreg(stlport_t *portp, int regnr)
-{
- outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
- return(inb(portp->ioaddr + XP_DATA));
-}
-
-static void stl_sc26198setreg(stlport_t *portp, int regnr, int value)
-{
- outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
- outb(value, (portp->ioaddr + XP_DATA));
-}
-
-static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value)
-{
- outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
- if (inb(portp->ioaddr + XP_DATA) != value) {
- outb(value, (portp->ioaddr + XP_DATA));
- return(1);
- }
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
- * Functions to get and set the sc26198 global registers.
- */
-
-static int stl_sc26198getglobreg(stlport_t *portp, int regnr)
-{
- outb(regnr, (portp->ioaddr + XP_ADDR));
- return(inb(portp->ioaddr + XP_DATA));
-}
-
-#if 0
-static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value)
-{
- outb(regnr, (portp->ioaddr + XP_ADDR));
- outb(value, (portp->ioaddr + XP_DATA));
-}
-#endif
-
-/*****************************************************************************/
-
-/*
- * Inbitialize the UARTs in a panel. We don't care what sort of board
- * these ports are on - since the port io registers are almost
- * identical when dealing with ports.
- */
-
-static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
-{
- int chipmask, i;
- int nrchips, ioaddr;
-
-#if DEBUG
- printk("stl_sc26198panelinit(brdp=%x,panelp=%x)\n",
- (int) brdp, (int) panelp);
-#endif
-
- BRDENABLE(panelp->brdnr, panelp->pagenr);
-
-/*
- * Check that each chip is present and started up OK.
- */
- chipmask = 0;
- nrchips = (panelp->nrports + 4) / SC26198_PORTS;
- if (brdp->brdtype == BRD_ECHPCI)
- outb(panelp->pagenr, brdp->ioctrl);
-
- for (i = 0; (i < nrchips); i++) {
- ioaddr = panelp->iobase + (i * 4);
- outb(SCCR, (ioaddr + XP_ADDR));
- outb(CR_RESETALL, (ioaddr + XP_DATA));
- outb(TSTR, (ioaddr + XP_ADDR));
- if (inb(ioaddr + XP_DATA) != 0) {
- printk("STALLION: sc26198 not responding, "
- "brd=%d panel=%d chip=%d\n",
- panelp->brdnr, panelp->panelnr, i);
- continue;
- }
- chipmask |= (0x1 << i);
- outb(GCCR, (ioaddr + XP_ADDR));
- outb(GCCR_IVRTYPCHANACK, (ioaddr + XP_DATA));
- outb(WDTRCR, (ioaddr + XP_ADDR));
- outb(0xff, (ioaddr + XP_DATA));
- }
-
- BRDDISABLE(panelp->brdnr);
- return(chipmask);
-}
-
-/*****************************************************************************/
-
-/*
- * Initialize hardware specific port registers.
- */
-
-static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
-{
-#if DEBUG
- printk("stl_sc26198portinit(brdp=%x,panelp=%x,portp=%x)\n",
- (int) brdp, (int) panelp, (int) portp);
-#endif
-
- if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
- (portp == (stlport_t *) NULL))
- return;
-
- portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4);
- portp->uartaddr = (portp->portnr & 0x07) << 4;
- portp->pagenr = panelp->pagenr;
- portp->hwid = 0x1;
-
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_sc26198setreg(portp, IOPCR, IOPCR_SETSIGS);
- BRDDISABLE(portp->brdnr);
-}
-
-/*****************************************************************************/
-
-/*
- * Set up the sc26198 registers for a port based on the termios port
- * settings.
- */
-
-static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
-{
- stlbrd_t *brdp;
- unsigned long flags;
- unsigned int baudrate;
- unsigned char mr0, mr1, mr2, clk;
- unsigned char imron, imroff, iopr, ipr;
-
- mr0 = 0;
- mr1 = 0;
- mr2 = 0;
- clk = 0;
- iopr = 0;
- imron = 0;
- imroff = 0;
-
- brdp = stl_brds[portp->brdnr];
- if (brdp == (stlbrd_t *) NULL)
- return;
-
-/*
- * Set up the RX char ignore mask with those RX error types we
- * can ignore.
- */
- portp->rxignoremsk = 0;
- if (tiosp->c_iflag & IGNPAR)
- portp->rxignoremsk |= (SR_RXPARITY | SR_RXFRAMING |
- SR_RXOVERRUN);
- if (tiosp->c_iflag & IGNBRK)
- portp->rxignoremsk |= SR_RXBREAK;
-
- portp->rxmarkmsk = SR_RXOVERRUN;
- if (tiosp->c_iflag & (INPCK | PARMRK))
- portp->rxmarkmsk |= (SR_RXPARITY | SR_RXFRAMING);
- if (tiosp->c_iflag & BRKINT)
- portp->rxmarkmsk |= SR_RXBREAK;
-
-/*
- * Go through the char size, parity and stop bits and set all the
- * option register appropriately.
- */
- switch (tiosp->c_cflag & CSIZE) {
- case CS5:
- mr1 |= MR1_CS5;
- break;
- case CS6:
- mr1 |= MR1_CS6;
- break;
- case CS7:
- mr1 |= MR1_CS7;
- break;
- default:
- mr1 |= MR1_CS8;
- break;
- }
-
- if (tiosp->c_cflag & CSTOPB)
- mr2 |= MR2_STOP2;
- else
- mr2 |= MR2_STOP1;
-
- if (tiosp->c_cflag & PARENB) {
- if (tiosp->c_cflag & PARODD)
- mr1 |= (MR1_PARENB | MR1_PARODD);
- else
- mr1 |= (MR1_PARENB | MR1_PAREVEN);
- } else {
- mr1 |= MR1_PARNONE;
- }
-
- mr1 |= MR1_ERRBLOCK;
-
-/*
- * Set the RX FIFO threshold at 8 chars. This gives a bit of breathing
- * space for hardware flow control and the like. This should be set to
- * VMIN.
- */
- mr2 |= MR2_RXFIFOHALF;
-
-/*
- * Calculate the baud rate timers. For now we will just assume that
- * the input and output baud are the same. The sc26198 has a fixed
- * baud rate table, so only discrete baud rates possible.
- */
- baudrate = tiosp->c_cflag & CBAUD;
- if (baudrate & CBAUDEX) {
- baudrate &= ~CBAUDEX;
- if ((baudrate < 1) || (baudrate > 4))
- tiosp->c_cflag &= ~CBAUDEX;
- else
- baudrate += 15;
- }
- baudrate = stl_baudrates[baudrate];
- if ((tiosp->c_cflag & CBAUD) == B38400) {
- if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- baudrate = 57600;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- baudrate = 115200;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- baudrate = 230400;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- baudrate = 460800;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
- baudrate = (portp->baud_base / portp->custom_divisor);
- }
- if (baudrate > STL_SC26198MAXBAUD)
- baudrate = STL_SC26198MAXBAUD;
-
- if (baudrate > 0) {
- for (clk = 0; (clk < SC26198_NRBAUDS); clk++) {
- if (baudrate <= sc26198_baudtable[clk])
- break;
- }
- }
-
-/*
- * Check what form of modem signaling is required and set it up.
- */
- if (tiosp->c_cflag & CLOCAL) {
- portp->flags &= ~ASYNC_CHECK_CD;
- } else {
- iopr |= IOPR_DCDCOS;
- imron |= IR_IOPORT;
- portp->flags |= ASYNC_CHECK_CD;
- }
-
-/*
- * Setup sc26198 enhanced modes if we can. In particular we want to
- * handle as much of the flow control as possible automatically. As
- * well as saving a few CPU cycles it will also greatly improve flow
- * control reliability.
- */
- if (tiosp->c_iflag & IXON) {
- mr0 |= MR0_SWFTX | MR0_SWFT;
- imron |= IR_XONXOFF;
- } else {
- imroff |= IR_XONXOFF;
- }
- if (tiosp->c_iflag & IXOFF)
- mr0 |= MR0_SWFRX;
-
- if (tiosp->c_cflag & CRTSCTS) {
- mr2 |= MR2_AUTOCTS;
- mr1 |= MR1_AUTORTS;
- }
-
-/*
- * All sc26198 register values calculated so go through and set
- * them all up.
- */
-
-#if DEBUG
- printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
- portp->portnr, portp->panelnr, portp->brdnr);
- printk(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk);
- printk(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff);
- printk(" schr1=%x schr2=%x schr3=%x schr4=%x\n",
- tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
- tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
-#endif
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_sc26198setreg(portp, IMR, 0);
- stl_sc26198updatereg(portp, MR0, mr0);
- stl_sc26198updatereg(portp, MR1, mr1);
- stl_sc26198setreg(portp, SCCR, CR_RXERRBLOCK);
- stl_sc26198updatereg(portp, MR2, mr2);
- stl_sc26198updatereg(portp, IOPIOR,
- ((stl_sc26198getreg(portp, IOPIOR) & ~IPR_CHANGEMASK) | iopr));
-
- if (baudrate > 0) {
- stl_sc26198setreg(portp, TXCSR, clk);
- stl_sc26198setreg(portp, RXCSR, clk);
- }
-
- stl_sc26198setreg(portp, XONCR, tiosp->c_cc[VSTART]);
- stl_sc26198setreg(portp, XOFFCR, tiosp->c_cc[VSTOP]);
-
- ipr = stl_sc26198getreg(portp, IPR);
- if (ipr & IPR_DCD)
- portp->sigs &= ~TIOCM_CD;
- else
- portp->sigs |= TIOCM_CD;
-
- portp->imr = (portp->imr & ~imroff) | imron;
- stl_sc26198setreg(portp, IMR, portp->imr);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Set the state of the DTR and RTS signals.
- */
-
-static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts)
-{
- unsigned char iopioron, iopioroff;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_sc26198setsignals(portp=%x,dtr=%d,rts=%d)\n",
- (int) portp, dtr, rts);
-#endif
-
- iopioron = 0;
- iopioroff = 0;
- if (dtr == 0)
- iopioroff |= IPR_DTR;
- else if (dtr > 0)
- iopioron |= IPR_DTR;
- if (rts == 0)
- iopioroff |= IPR_RTS;
- else if (rts > 0)
- iopioron |= IPR_RTS;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_sc26198setreg(portp, IOPIOR,
- ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron));
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the state of the signals.
- */
-
-static int stl_sc26198getsignals(stlport_t *portp)
-{
- unsigned char ipr;
- unsigned long flags;
- int sigs;
-
-#if DEBUG
- printk("stl_sc26198getsignals(portp=%x)\n", (int) portp);
-#endif
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- ipr = stl_sc26198getreg(portp, IPR);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-
- sigs = 0;
- sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD;
- sigs |= (ipr & IPR_CTS) ? 0 : TIOCM_CTS;
- sigs |= (ipr & IPR_DTR) ? 0: TIOCM_DTR;
- sigs |= (ipr & IPR_RTS) ? 0: TIOCM_RTS;
- sigs |= TIOCM_DSR;
- return(sigs);
-}
-
-/*****************************************************************************/
-
-/*
- * Enable/Disable the Transmitter and/or Receiver.
- */
-
-static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx)
-{
- unsigned char ccr;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_sc26198enablerxtx(portp=%x,rx=%d,tx=%d)\n",
- (int) portp, rx, tx);
-#endif
-
- ccr = portp->crenable;
- if (tx == 0)
- ccr &= ~CR_TXENABLE;
- else if (tx > 0)
- ccr |= CR_TXENABLE;
- if (rx == 0)
- ccr &= ~CR_RXENABLE;
- else if (rx > 0)
- ccr |= CR_RXENABLE;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_sc26198setreg(portp, SCCR, ccr);
- BRDDISABLE(portp->brdnr);
- portp->crenable = ccr;
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Start/stop the Transmitter and/or Receiver.
- */
-
-static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx)
-{
- unsigned char imr;
- unsigned long flags;
-
-#if DEBUG
- printk("stl_sc26198startrxtx(portp=%x,rx=%d,tx=%d)\n",
- (int) portp, rx, tx);
-#endif
-
- imr = portp->imr;
- if (tx == 0)
- imr &= ~IR_TXRDY;
- else if (tx == 1)
- imr |= IR_TXRDY;
- if (rx == 0)
- imr &= ~(IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG);
- else if (rx > 0)
- imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_sc26198setreg(portp, IMR, imr);
- BRDDISABLE(portp->brdnr);
- portp->imr = imr;
- if (tx > 0)
- set_bit(ASYI_TXBUSY, &portp->istate);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Disable all interrupts from this port.
- */
-
-static void stl_sc26198disableintrs(stlport_t *portp)
-{
- unsigned long flags;
-
-#if DEBUG
- printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp);
-#endif
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- portp->imr = 0;
- stl_sc26198setreg(portp, IMR, 0);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-static void stl_sc26198sendbreak(stlport_t *portp, int len)
-{
- unsigned long flags;
-
-#if DEBUG
- printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len);
-#endif
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- if (len == 1) {
- stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK);
- portp->stats.txbreaks++;
- } else {
- stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK);
- }
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Take flow control actions...
- */
-
-static void stl_sc26198flowctrl(stlport_t *portp, int state)
-{
- struct tty_struct *tty;
- unsigned long flags;
- unsigned char mr0;
-
-#if DEBUG
- printk("stl_sc26198flowctrl(portp=%x,state=%x)\n", (int) portp, state);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
- tty = portp->tty;
- if (tty == (struct tty_struct *) NULL)
- return;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
-
- if (state) {
- if (tty->termios->c_iflag & IXOFF) {
- mr0 = stl_sc26198getreg(portp, MR0);
- stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
- stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
- mr0 |= MR0_SWFRX;
- portp->stats.rxxon++;
- stl_sc26198wait(portp);
- stl_sc26198setreg(portp, MR0, mr0);
- }
-/*
- * Question: should we return RTS to what it was before? It may
- * have been set by an ioctl... Suppose not, since if you have
- * hardware flow control set then it is pretty silly to go and
- * set the RTS line by hand.
- */
- if (tty->termios->c_cflag & CRTSCTS) {
- stl_sc26198setreg(portp, MR1,
- (stl_sc26198getreg(portp, MR1) | MR1_AUTORTS));
- stl_sc26198setreg(portp, IOPIOR,
- (stl_sc26198getreg(portp, IOPIOR) | IOPR_RTS));
- portp->stats.rxrtson++;
- }
- } else {
- if (tty->termios->c_iflag & IXOFF) {
- mr0 = stl_sc26198getreg(portp, MR0);
- stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
- stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
- mr0 &= ~MR0_SWFRX;
- portp->stats.rxxoff++;
- stl_sc26198wait(portp);
- stl_sc26198setreg(portp, MR0, mr0);
- }
- if (tty->termios->c_cflag & CRTSCTS) {
- stl_sc26198setreg(portp, MR1,
- (stl_sc26198getreg(portp, MR1) & ~MR1_AUTORTS));
- stl_sc26198setreg(portp, IOPIOR,
- (stl_sc26198getreg(portp, IOPIOR) & ~IOPR_RTS));
- portp->stats.rxrtsoff++;
- }
- }
-
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Send a flow control character.
- */
-
-static void stl_sc26198sendflow(stlport_t *portp, int state)
-{
- struct tty_struct *tty;
- unsigned long flags;
- unsigned char mr0;
-
-#if DEBUG
- printk("stl_sc26198sendflow(portp=%x,state=%x)\n", (int) portp, state);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
- tty = portp->tty;
- if (tty == (struct tty_struct *) NULL)
- return;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- if (state) {
- mr0 = stl_sc26198getreg(portp, MR0);
- stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
- stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
- mr0 |= MR0_SWFRX;
- portp->stats.rxxon++;
- stl_sc26198wait(portp);
- stl_sc26198setreg(portp, MR0, mr0);
- } else {
- mr0 = stl_sc26198getreg(portp, MR0);
- stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
- stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
- mr0 &= ~MR0_SWFRX;
- portp->stats.rxxoff++;
- stl_sc26198wait(portp);
- stl_sc26198setreg(portp, MR0, mr0);
- }
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-static void stl_sc26198flush(stlport_t *portp)
-{
- unsigned long flags;
-
-#if DEBUG
- printk("stl_sc26198flush(portp=%x)\n", (int) portp);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- stl_sc26198setreg(portp, SCCR, CR_TXRESET);
- stl_sc26198setreg(portp, SCCR, portp->crenable);
- BRDDISABLE(portp->brdnr);
- portp->tx.tail = portp->tx.head;
- restore_flags(flags);
-}
-
-/*****************************************************************************/
-
-/*
- * Return the current state of data flow on this port. This is only
- * really interresting when determining if data has fully completed
- * transmission or not... The sc26198 interrupt scheme cannot
- * determine when all data has actually drained, so we need to
- * check the port statusy register to be sure.
- */
-
-static int stl_sc26198datastate(stlport_t *portp)
-{
- unsigned long flags;
- unsigned char sr;
-
-#if DEBUG
- printk("stl_sc26198datastate(portp=%x)\n", (int) portp);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return(0);
- if (test_bit(ASYI_TXBUSY, &portp->istate))
- return(1);
-
- save_flags(flags);
- cli();
- BRDENABLE(portp->brdnr, portp->pagenr);
- sr = stl_sc26198getreg(portp, SR);
- BRDDISABLE(portp->brdnr);
- restore_flags(flags);
-
- return((sr & SR_TXEMPTY) ? 0 : 1);
-}
-
-/*****************************************************************************/
-
-/*
- * Delay for a small amount of time, to give the sc26198 a chance
- * to process a command...
- */
-
-static void stl_sc26198wait(stlport_t *portp)
-{
- int i;
-
-#if DEBUG
- printk("stl_sc26198wait(portp=%x)\n", (int) portp);
-#endif
-
- if (portp == (stlport_t *) NULL)
- return;
-
- for (i = 0; (i < 20); i++)
- stl_sc26198getglobreg(portp, TSTR);
-}
-
-/*****************************************************************************/
-
-/*
- * If we are TX flow controlled and in IXANY mode then we may
- * need to unflow control here. We gotta do this because of the
- * automatic flow control modes of the sc26198.
- */
-
-static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty)
-{
- unsigned char mr0;
-
- mr0 = stl_sc26198getreg(portp, MR0);
- stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
- stl_sc26198setreg(portp, SCCR, CR_HOSTXON);
- stl_sc26198wait(portp);
- stl_sc26198setreg(portp, MR0, mr0);
- clear_bit(ASYI_TXFLOWED, &portp->istate);
-}
-
-/*****************************************************************************/
-
-/*
- * Interrupt service routine for sc26198 panels.
- */
-
-static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase)
-{
- stlport_t *portp;
- unsigned int iack;
-
-/*
- * Work around bug in sc26198 chip... Cannot have A6 address
- * line of UART high, else iack will be returned as 0.
- */
- outb(0, (iobase + 1));
-
- iack = inb(iobase + XP_IACK);
- portp = panelp->ports[(iack & IVR_CHANMASK) + ((iobase & 0x4) << 1)];
-
- if (iack & IVR_RXDATA)
- stl_sc26198rxisr(portp, iack);
- else if (iack & IVR_TXDATA)
- stl_sc26198txisr(portp);
- else
- stl_sc26198otherisr(portp, iack);
-}
-
-/*****************************************************************************/
-
-/*
- * Transmit interrupt handler. This has gotta be fast! Handling TX
- * chars is pretty simple, stuff as many as possible from the TX buffer
- * into the sc26198 FIFO.
- * In practice it is possible that interrupts are enabled but that the
- * port has been hung up. Need to handle not having any TX buffer here,
- * this is done by using the side effect that head and tail will also
- * be NULL if the buffer has been freed.
- */
-
-static void stl_sc26198txisr(stlport_t *portp)
-{
- unsigned int ioaddr;
- unsigned char mr0;
- int len, stlen;
- char *head, *tail;
-
-#if DEBUG
- printk("stl_sc26198txisr(portp=%x)\n", (int) portp);
-#endif
-
- ioaddr = portp->ioaddr;
- head = portp->tx.head;
- tail = portp->tx.tail;
- len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
- if ((len == 0) || ((len < STL_TXBUFLOW) &&
- (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
- set_bit(ASYI_TXLOW, &portp->istate);
- queue_task(&portp->tqueue, &tq_scheduler);
- }
-
- if (len == 0) {
- outb((MR0 | portp->uartaddr), (ioaddr + XP_ADDR));
- mr0 = inb(ioaddr + XP_DATA);
- if ((mr0 & MR0_TXMASK) == MR0_TXEMPTY) {
- portp->imr &= ~IR_TXRDY;
- outb((IMR | portp->uartaddr), (ioaddr + XP_ADDR));
- outb(portp->imr, (ioaddr + XP_DATA));
- clear_bit(ASYI_TXBUSY, &portp->istate);
- } else {
- mr0 |= ((mr0 & ~MR0_TXMASK) | MR0_TXEMPTY);
- outb(mr0, (ioaddr + XP_DATA));
- }
- } else {
- len = MIN(len, SC26198_TXFIFOSIZE);
- portp->stats.txtotal += len;
- stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
- outb(GTXFIFO, (ioaddr + XP_ADDR));
- outsb((ioaddr + XP_DATA), tail, stlen);
- len -= stlen;
- tail += stlen;
- if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
- tail = portp->tx.buf;
- if (len > 0) {
- outsb((ioaddr + XP_DATA), tail, len);
- tail += len;
- }
- portp->tx.tail = tail;
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Receive character interrupt handler. Determine if we have good chars
- * or bad chars and then process appropriately. Good chars are easy
- * just shove the lot into the RX buffer and set all status byte to 0.
- * If a bad RX char then process as required. This routine needs to be
- * fast! In practice it is possible that we get an interrupt on a port
- * that is closed. This can happen on hangups - since they completely
- * shutdown a port not in user context. Need to handle this case.
- */
-
-static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
-{
- struct tty_struct *tty;
- unsigned int len, buflen, ioaddr;
-
-#if DEBUG
- printk("stl_sc26198rxisr(portp=%x,iack=%x)\n", (int) portp, iack);
-#endif
-
- tty = portp->tty;
- ioaddr = portp->ioaddr;
- outb(GIBCR, (ioaddr + XP_ADDR));
- len = inb(ioaddr + XP_DATA) + 1;
-
- if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
- if ((tty == (struct tty_struct *) NULL) ||
- (tty->flip.char_buf_ptr == (char *) NULL) ||
- ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
- len = MIN(len, sizeof(stl_unwanted));
- outb(GRXFIFO, (ioaddr + XP_ADDR));
- insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
- portp->stats.rxlost += len;
- portp->stats.rxtotal += len;
- } else {
- len = MIN(len, buflen);
- if (len > 0) {
- outb(GRXFIFO, (ioaddr + XP_ADDR));
- insb((ioaddr + XP_DATA), tty->flip.char_buf_ptr, len);
- memset(tty->flip.flag_buf_ptr, 0, len);
- tty->flip.flag_buf_ptr += len;
- tty->flip.char_buf_ptr += len;
- tty->flip.count += len;
- tty_schedule_flip(tty);
- portp->stats.rxtotal += len;
- }
- }
- } else {
- stl_sc26198rxbadchars(portp);
- }
-
-/*
- * If we are TX flow controlled and in IXANY mode then we may need
- * to unflow control here. We gotta do this because of the automatic
- * flow control modes of the sc26198.
- */
- if (test_bit(ASYI_TXFLOWED, &portp->istate)) {
- if ((tty != (struct tty_struct *) NULL) &&
- (tty->termios != (struct termios *) NULL) &&
- (tty->termios->c_iflag & IXANY)) {
- stl_sc26198txunflow(portp, tty);
- }
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Process an RX bad character.
- */
-
-static void inline stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch)
-{
- struct tty_struct *tty;
- unsigned int ioaddr;
-
- tty = portp->tty;
- ioaddr = portp->ioaddr;
-
- if (status & SR_RXPARITY)
- portp->stats.rxparity++;
- if (status & SR_RXFRAMING)
- portp->stats.rxframing++;
- if (status & SR_RXOVERRUN)
- portp->stats.rxoverrun++;
- if (status & SR_RXBREAK)
- portp->stats.rxbreaks++;
-
- if ((tty != (struct tty_struct *) NULL) &&
- ((portp->rxignoremsk & status) == 0)) {
- if (portp->rxmarkmsk & status) {
- if (status & SR_RXBREAK) {
- status = TTY_BREAK;
- if (portp->flags & ASYNC_SAK) {
- do_SAK(tty);
- BRDENABLE(portp->brdnr, portp->pagenr);
- }
- } else if (status & SR_RXPARITY) {
- status = TTY_PARITY;
- } else if (status & SR_RXFRAMING) {
- status = TTY_FRAME;
- } else if(status & SR_RXOVERRUN) {
- status = TTY_OVERRUN;
- } else {
- status = 0;
- }
- } else {
- status = 0;
- }
-
- if (tty->flip.char_buf_ptr != (char *) NULL) {
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- *tty->flip.flag_buf_ptr++ = status;
- *tty->flip.char_buf_ptr++ = ch;
- tty->flip.count++;
- }
- tty_schedule_flip(tty);
- }
-
- if (status == 0)
- portp->stats.rxtotal++;
- }
-}
-
-/*****************************************************************************/
-
-/*
- * Process all characters in the RX FIFO of the UART. Check all char
- * status bytes as well, and process as required. We need to check
- * all bytes in the FIFO, in case some more enter the FIFO while we
- * are here. To get the exact character error type we need to switch
- * into CHAR error mode (that is why we need to make sure we empty
- * the FIFO).
- */
-
-static void stl_sc26198rxbadchars(stlport_t *portp)
-{
- unsigned char status, mr1;
- char ch;
-
-/*
- * To get the precise error type for each character we must switch
- * back into CHAR error mode.
- */
- mr1 = stl_sc26198getreg(portp, MR1);
- stl_sc26198setreg(portp, MR1, (mr1 & ~MR1_ERRBLOCK));
-
- while ((status = stl_sc26198getreg(portp, SR)) & SR_RXRDY) {
- stl_sc26198setreg(portp, SCCR, CR_CLEARRXERR);
- ch = stl_sc26198getreg(portp, RXFIFO);
- stl_sc26198rxbadch(portp, status, ch);
- }
-
-/*
- * To get correct interrupt class we must switch back into BLOCK
- * error mode.
- */
- stl_sc26198setreg(portp, MR1, mr1);
-}
-
-/*****************************************************************************/
-
-/*
- * Other interrupt handler. This includes modem signals, flow
- * control actions, etc. Most stuff is left to off-level interrupt
- * processing time.
- */
-
-static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack)
-{
- unsigned char cir, ipr, xisr;
-
-#if DEBUG
- printk("stl_sc26198otherisr(portp=%x,iack=%x)\n", (int) portp, iack);
-#endif
-
- cir = stl_sc26198getglobreg(portp, CIR);
-
- switch (cir & CIR_SUBTYPEMASK) {
- case CIR_SUBCOS:
- ipr = stl_sc26198getreg(portp, IPR);
- if (ipr & IPR_DCDCHANGE) {
- set_bit(ASYI_DCDCHANGE, &portp->istate);
- queue_task(&portp->tqueue, &tq_scheduler);
- portp->stats.modem++;
- }
- break;
- case CIR_SUBXONXOFF:
- xisr = stl_sc26198getreg(portp, XISR);
- if (xisr & XISR_RXXONGOT) {
- set_bit(ASYI_TXFLOWED, &portp->istate);
- portp->stats.txxoff++;
- }
- if (xisr & XISR_RXXOFFGOT) {
- clear_bit(ASYI_TXFLOWED, &portp->istate);
- portp->stats.txxon++;
- }
- break;
- case CIR_SUBBREAK:
- stl_sc26198setreg(portp, SCCR, CR_BREAKRESET);
- stl_sc26198rxbadchars(portp);
- break;
- default:
- break;
- }
-}
-
-/*****************************************************************************/
diff --git a/drivers/char/stradis.c b/drivers/char/stradis.c
deleted file mode 100644
index 03ca27a25..000000000
--- a/drivers/char/stradis.c
+++ /dev/null
@@ -1,2287 +0,0 @@
-/*
- * stradis.c - stradis 4:2:2 mpeg decoder driver
- *
- * Stradis 4:2:2 MPEG-2 Decoder Driver
- * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
- *
- * 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 of the License, 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.
- */
-
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <linux/ioport.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <asm/segment.h>
-#include <asm/types.h>
-#include <linux/types.h>
-#include <linux/wrapper.h>
-#include <linux/interrupt.h>
-#include <asm/uaccess.h>
-#include <linux/vmalloc.h>
-#include <linux/videodev.h>
-#include <linux/i2c-old.h>
-
-#include "saa7146.h"
-#include "saa7146reg.h"
-#include "ibmmpeg2.h"
-#include "saa7121.h"
-#include "cs8420.h"
-
-#define DEBUG(x) /* debug driver */
-#undef IDEBUG(x) /* debug irq handler */
-#undef MDEBUG(x) /* debug memory management */
-
-#define SAA7146_MAX 6
-
-static struct saa7146 saa7146s[SAA7146_MAX];
-
-static int saa_num = 0; /* number of SAA7146s in use */
-
-#define nDebNormal 0x00480000
-#define nDebNoInc 0x00480000
-#define nDebVideo 0xd0480000
-#define nDebAudio 0xd0400000
-#define nDebDMA 0x02c80000
-
-#define oDebNormal 0x13c80000
-#define oDebNoInc 0x13c80000
-#define oDebVideo 0xd1080000
-#define oDebAudio 0xd1080000
-#define oDebDMA 0x03080000
-
-#define NewCard (saa->boardcfg[3])
-#define ChipControl (saa->boardcfg[1])
-#define NTSCFirstActive (saa->boardcfg[4])
-#define PALFirstActive (saa->boardcfg[5])
-#define NTSCLastActive (saa->boardcfg[54])
-#define PALLastActive (saa->boardcfg[55])
-#define Have2MB (saa->boardcfg[18] & 0x40)
-#define HaveCS8420 (saa->boardcfg[18] & 0x04)
-#define IBMMPEGCD20 (saa->boardcfg[18] & 0x20)
-#define HaveCS3310 (saa->boardcfg[18] & 0x01)
-#define CS3310MaxLvl ((saa->boardcfg[30] << 8) | saa->boardcfg[31])
-#define HaveCS4341 (saa->boardcfg[40] == 2)
-#define SDIType (saa->boardcfg[27])
-#define CurrentMode (saa->boardcfg[2])
-
-#define debNormal (NewCard ? nDebNormal : oDebNormal)
-#define debNoInc (NewCard ? nDebNoInc : oDebNoInc)
-#define debVideo (NewCard ? nDebVideo : oDebVideo)
-#define debAudio (NewCard ? nDebAudio : oDebAudio)
-#define debDMA (NewCard ? nDebDMA : oDebDMA)
-
-#ifdef DEBUG
-int stradis_driver(void) /* for the benefit of ksymoops */
-{
- return 1;
-}
-#endif
-
-#ifdef USE_RESCUE_EEPROM_SDM275
-static unsigned char rescue_eeprom[64] = {
-0x00,0x01,0x04,0x13,0x26,0x0f,0x10,0x00,0x00,0x00,0x43,0x63,0x22,0x01,0x29,0x15,0x73,0x00,0x1f, 'd', 'e', 'c', 'x', 'l', 'd', 'v', 'a',0x02,0x00,0x01,0x00,0xcc,0xa4,0x63,0x09,0xe2,0x10,0x00,0x0a,0x00,0x02,0x02, 'd', 'e', 'c', 'x', 'l', 'a',0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-#endif
-
-/* ----------------------------------------------------------------------- */
-/* Hardware I2C functions */
-static void I2CWipe(struct saa7146 *saa)
-{
- int i;
- /* set i2c to ~=100kHz, abort transfer, clear busy */
- saawrite(0x600 | SAA7146_I2C_ABORT, SAA7146_I2C_STATUS);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- saawrite(0x600, SAA7146_I2C_STATUS);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- saawrite(0x600, SAA7146_I2C_STATUS);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
-}
-/* read I2C */
-static int I2CRead(struct i2c_bus *bus, unsigned char addr,
- unsigned char subaddr, int dosub)
-{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
- int i;
-
-
- if (saaread(SAA7146_I2C_STATUS) & 0x3c)
- I2CWipe(saa);
- for (i = 0; i < 1000 &&
- (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
- schedule();
- if (i == 1000)
- I2CWipe(saa);
- if (dosub)
- saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 8) |
- ((subaddr & 0xff) << 16) | 0xed, SAA7146_I2C_TRANSFER);
- else
- saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 16) |
- 0xf1, SAA7146_I2C_TRANSFER);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- /* wait for valid data */
- for (i = 0; i < 1000 &&
- (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
- schedule();
- if (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_ERR)
- return -1;
- if (i == 1000)
- printk("i2c setup read timeout\n");
- saawrite(0x41, SAA7146_I2C_TRANSFER);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) |
- SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
- /* wait for i2c registers to be programmed */
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
- schedule();
- /* wait for valid data */
- for (i = 0; i < 1000 &&
- (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_BUSY); i++)
- schedule();
- if (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_ERR)
- return -1;
- if (i == 1000)
- printk("i2c read timeout\n");
- return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff);
-}
-static int I2CReadOld(struct i2c_bus *bus, unsigned char addr)
-{
- return I2CRead(bus, addr, 0, 0);
-}
-
-/* set both to write both bytes, reset it to write only b1 */
-
-static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
- unsigned char b2, int both)
-{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
- int i;
- u32 data;
-
- if (saaread(SAA7146_I2C_STATUS) & 0x3c)
- I2CWipe(saa);
- for (i = 0; i < 1000 &&
- (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
- schedule();
- if (i == 1000)
- I2CWipe(saa);
- data = ((addr & 0xfe) << 24) | ((b1 & 0xff) << 16);
- if (both)
- data |= ((b2 & 0xff) << 8) | 0xe5;
- else
- data |= 0xd1;
- saawrite(data, SAA7146_I2C_TRANSFER);
- saawrite((SAA7146_MC2_UPLD_I2C << 16) | SAA7146_MC2_UPLD_I2C,
- SAA7146_MC2);
- return 0;
-}
-
-static void attach_inform(struct i2c_bus *bus, int id)
-{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
- int i;
-
- DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr, id));
- if (id == 0xa0) { /* we have rev2 or later board, fill in info */
- for (i = 0; i < 64; i++)
- saa->boardcfg[i] = I2CRead(bus, 0xa0, i, 1);
-#ifdef USE_RESCUE_EEPROM_SDM275
- if (saa->boardcfg[0] != 0) {
- printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE BEEN IGNORED\n", saa->nr);
- for (i = 0; i < 64; i++)
- saa->boardcfg[i] = rescue_eeprom[i];
- }
-#endif
- printk("stradis%d: config =", saa->nr);
- for (i = 0; i < 51; i++) {
- printk(" %02x",saa->boardcfg[i]);
- }
- printk("\n");
- }
-}
-
-static void detach_inform(struct i2c_bus *bus, int id)
-{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
- int i;
- i = saa->nr;
-}
-
-static void I2CBusScan(struct i2c_bus *bus)
-{
- int i;
- for (i = 0; i < 0xff; i += 2)
- if ((I2CRead(bus, i, 0, 0)) >= 0)
- attach_inform(bus, i);
-}
-
-static struct i2c_bus saa7146_i2c_bus_template =
-{
- "saa7146",
- I2C_BUSID_BT848,
- NULL,
- SPIN_LOCK_UNLOCKED,
- attach_inform,
- detach_inform,
- NULL,
- NULL,
- I2CReadOld,
- I2CWrite,
-};
-
-static int debiwait_maxwait = 0;
-
-static int wait_for_debi_done(struct saa7146 *saa)
-{
- int i;
-
- /* wait for registers to be programmed */
- for (i = 0; i < 100000 &&
- !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_DEBI); i++)
- saaread(SAA7146_MC2);
- /* wait for transfer to complete */
- for (i = 0; i < 500000 &&
- (saaread(SAA7146_PSR) & SAA7146_PSR_DEBI_S); i++)
- saaread(SAA7146_MC2);
- if (i > debiwait_maxwait)
- printk("wait-for-debi-done maxwait: %d\n",
- debiwait_maxwait = i);
-
- if (i == 500000)
- return -1;
- return 0;
-}
-
-static int debiwrite(struct saa7146 *saa, u32 config, int addr,
- u32 val, int count)
-{
- u32 cmd;
- if (count <= 0 || count > 32764)
- return -1;
- if (wait_for_debi_done(saa) < 0)
- return -1;
- saawrite(config, SAA7146_DEBI_CONFIG);
- if (count <= 4) /* immediate transfer */
- saawrite(val, SAA7146_DEBI_AD);
- else /* block transfer */
- saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
- saawrite((cmd = (count << 17) | (addr & 0xffff)), SAA7146_DEBI_COMMAND);
- saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
- SAA7146_MC2);
- return 0;
-}
-
-static u32 debiread(struct saa7146 *saa, u32 config, int addr, int count)
-{
- u32 result = 0;
-
- if (count > 32764 || count <= 0)
- return 0;
- if (wait_for_debi_done(saa) < 0)
- return 0;
- saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
- saawrite((count << 17) | 0x10000 | (addr & 0xffff),
- SAA7146_DEBI_COMMAND);
- saawrite(config, SAA7146_DEBI_CONFIG);
- saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
- SAA7146_MC2);
- if (count > 4) /* not an immediate transfer */
- return count;
- wait_for_debi_done(saa);
- result = saaread(SAA7146_DEBI_AD);
- if (count == 1)
- result &= 0xff;
- if (count == 2)
- result &= 0xffff;
- if (count == 3)
- result &= 0xffffff;
- return result;
-}
-
-#if 0 /* unused */
-/* MUST be a multiple of 8 bytes and 8-byte aligned and < 32768 bytes */
-/* data copied into saa->dmadebi buffer, caller must re-enable interrupts */
-static void ibm_block_dram_read(struct saa7146 *saa, int address, int bytes)
-{
- int i, j;
- u32 *buf;
- buf = (u32 *) saa->dmadebi;
- if (bytes > 0x7000)
- bytes = 0x7000;
- saawrite(0, SAA7146_IER); /* disable interrupts */
- for (i=0; i < 10000 &&
- (debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)
- & 0x8000); i++)
- saaread(SAA7146_MC2);
- if (i == 10000)
- printk(KERN_ERR "stradis%d: dram_busy never cleared\n",
- saa->nr);
- debiwrite(saa, debNormal, IBM_MP2_SRC_ADDR, (address<<16) |
- (address>>16), 4);
- debiwrite(saa, debNormal, IBM_MP2_BLOCK_SIZE, bytes, 2);
- debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 0x8a10, 2);
- for (j = 0; j < bytes/4; j++) {
- for (i = 0; i < 10000 &&
- (!(debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)
- & 0x4000)); i++)
- saaread(SAA7146_MC2);
- if (i == 10000)
- printk(KERN_ERR "stradis%d: dram_ready never set\n",
- saa->nr);
- buf[j] = debiread(saa, debNormal, IBM_MP2_DRAM_DATA, 4);
- }
-}
-#endif /* unused */
-
-static void do_irq_send_data(struct saa7146 *saa)
-{
- int split, audbytes, vidbytes;
-
- saawrite(SAA7146_PSR_PIN1, SAA7146_IER);
- /* if special feature mode in effect, disable audio sending */
- if (saa->playmode != VID_PLAY_NORMAL)
- saa->audtail = saa->audhead = 0;
- if (saa->audhead <= saa->audtail)
- audbytes = saa->audtail - saa->audhead;
- else
- audbytes = 65536 - (saa->audhead - saa->audtail);
- if (saa->vidhead <= saa->vidtail)
- vidbytes = saa->vidtail - saa->vidhead;
- else
- vidbytes = 524288 - (saa->vidhead - saa->vidtail);
- if (audbytes == 0 && vidbytes == 0 && saa->osdtail == saa->osdhead) {
- saawrite(0, SAA7146_IER);
- return;
- }
- /* if at least 1 block audio waiting and audio fifo isn't full */
- if (audbytes >= 2048 && (debiread(saa, debNormal,
- IBM_MP2_AUD_FIFO, 2) & 0xff) < 60) {
- if (saa->audhead > saa->audtail)
- split = 65536 - saa->audhead;
- else
- split = 0;
- audbytes = 2048;
- if (split > 0 && split < 2048) {
- memcpy(saa->dmadebi, saa->audbuf + saa->audhead,
- split);
- saa->audhead = 0;
- audbytes -= split;
- } else
- split = 0;
- memcpy(saa->dmadebi + split, saa->audbuf + saa->audhead,
- audbytes);
- saa->audhead += audbytes;
- saa->audhead &= 0xffff;
- debiwrite(saa, debAudio, (NewCard? IBM_MP2_AUD_FIFO :
- IBM_MP2_AUD_FIFOW), 0, 2048);
- wake_up_interruptible(&saa->audq);
- /* if at least 1 block video waiting and video fifo isn't full */
- } else if (vidbytes >= 30720 && (debiread(saa, debNormal,
- IBM_MP2_FIFO, 2)) < 16384) {
- if (saa->vidhead > saa->vidtail)
- split = 524288 - saa->vidhead;
- else
- split = 0;
- vidbytes = 30720;
- if (split > 0 && split < 30720) {
- memcpy(saa->dmadebi, saa->vidbuf + saa->vidhead,
- split);
- saa->vidhead = 0;
- vidbytes -= split;
- } else
- split = 0;
- memcpy(saa->dmadebi + split, saa->vidbuf + saa->vidhead,
- vidbytes);
- saa->vidhead += vidbytes;
- saa->vidhead &= 0x7ffff;
- debiwrite(saa, debVideo, (NewCard ? IBM_MP2_FIFO :
- IBM_MP2_FIFOW), 0, 30720);
- wake_up_interruptible(&saa->vidq);
- }
- saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER);
-}
-
-static void send_osd_data(struct saa7146 *saa)
-{
- int size = saa->osdtail - saa->osdhead;
- if (size > 30720)
- size = 30720;
- /* ensure some multiple of 8 bytes is transferred */
- size = 8 * ((size + 8)>>3);
- if (size) {
- debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR,
- (saa->osdhead>>3), 2);
- memcpy(saa->dmadebi, &saa->osdbuf[saa->osdhead], size);
- saa->osdhead += size;
- /* block transfer of next 8 bytes to ~32k bytes */
- debiwrite(saa, debNormal, IBM_MP2_OSD_DATA, 0, size);
- }
- if (saa->osdhead >= saa->osdtail) {
- saa->osdhead = saa->osdtail = 0;
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
- }
-}
-
-static void saa7146_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct saa7146 *saa = (struct saa7146 *) dev_id;
- u32 stat, astat;
- int count;
-
- count = 0;
- while (1) {
- /* get/clear interrupt status bits */
- stat = saaread(SAA7146_ISR);
- astat = stat & saaread(SAA7146_IER);
- if (!astat)
- return;
- saawrite(astat, SAA7146_ISR);
- if (astat & SAA7146_PSR_DEBI_S) {
- do_irq_send_data(saa);
- }
- if (astat & SAA7146_PSR_PIN1) {
- int istat;
- /* the following read will trigger DEBI_S */
- istat = debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
- if (istat & 1) {
- saawrite(0, SAA7146_IER);
- send_osd_data(saa);
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- }
- if (istat & 0x20) { /* Video Start */
- saa->vidinfo.frame_count++;
- }
- if (istat & 0x400) { /* Picture Start */
- /* update temporal reference */
- }
- if (istat & 0x200) { /* Picture Resolution Change */
- /* read new resolution */
- }
- if (istat & 0x100) { /* New User Data found */
- /* read new user data */
- }
- if (istat & 0x1000) { /* new GOP/SMPTE */
- /* read new SMPTE */
- }
- if (istat & 0x8000) { /* Sequence Start Code */
- /* reset frame counter, load sizes */
- saa->vidinfo.frame_count = 0;
- saa->vidinfo.h_size = 704;
- saa->vidinfo.v_size = 480;
-#if 0
- if (saa->endmarkhead != saa->endmarktail) {
- saa->audhead =
- saa->endmark[saa->endmarkhead];
- saa->endmarkhead++;
- if (saa->endmarkhead >= MAX_MARKS)
- saa->endmarkhead = 0;
- }
-#endif
- }
- if (istat & 0x4000) { /* Sequence Error Code */
- if (saa->endmarkhead != saa->endmarktail) {
- saa->audhead =
- saa->endmark[saa->endmarkhead];
- saa->endmarkhead++;
- if (saa->endmarkhead >= MAX_MARKS)
- saa->endmarkhead = 0;
- }
- }
- }
-#ifdef IDEBUG
- if (astat & SAA7146_PSR_PPEF) {
- IDEBUG(printk("stradis%d irq: PPEF\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PABO) {
- IDEBUG(printk("stradis%d irq: PABO\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PPED) {
- IDEBUG(printk("stradis%d irq: PPED\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_I1) {
- IDEBUG(printk("stradis%d irq: RPS_I1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_I0) {
- IDEBUG(printk("stradis%d irq: RPS_I0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_LATE1) {
- IDEBUG(printk("stradis%d irq: RPS_LATE1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_LATE0) {
- IDEBUG(printk("stradis%d irq: RPS_LATE0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_E1) {
- IDEBUG(printk("stradis%d irq: RPS_E1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_E0) {
- IDEBUG(printk("stradis%d irq: RPS_E0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_TO1) {
- IDEBUG(printk("stradis%d irq: RPS_TO1\n", saa->nr));
- }
- if (astat & SAA7146_PSR_RPS_TO0) {
- IDEBUG(printk("stradis%d irq: RPS_TO0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_UPLD) {
- IDEBUG(printk("stradis%d irq: UPLD\n", saa->nr));
- }
- if (astat & SAA7146_PSR_DEBI_E) {
- IDEBUG(printk("stradis%d irq: DEBI_E\n", saa->nr));
- }
- if (astat & SAA7146_PSR_I2C_S) {
- IDEBUG(printk("stradis%d irq: I2C_S\n", saa->nr));
- }
- if (astat & SAA7146_PSR_I2C_E) {
- IDEBUG(printk("stradis%d irq: I2C_E\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A2_IN) {
- IDEBUG(printk("stradis%d irq: A2_IN\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A2_OUT) {
- IDEBUG(printk("stradis%d irq: A2_OUT\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A1_IN) {
- IDEBUG(printk("stradis%d irq: A1_IN\n", saa->nr));
- }
- if (astat & SAA7146_PSR_A1_OUT) {
- IDEBUG(printk("stradis%d irq: A1_OUT\n", saa->nr));
- }
- if (astat & SAA7146_PSR_AFOU) {
- IDEBUG(printk("stradis%d irq: AFOU\n", saa->nr));
- }
- if (astat & SAA7146_PSR_V_PE) {
- IDEBUG(printk("stradis%d irq: V_PE\n", saa->nr));
- }
- if (astat & SAA7146_PSR_VFOU) {
- IDEBUG(printk("stradis%d irq: VFOU\n", saa->nr));
- }
- if (astat & SAA7146_PSR_FIDA) {
- IDEBUG(printk("stradis%d irq: FIDA\n", saa->nr));
- }
- if (astat & SAA7146_PSR_FIDB) {
- IDEBUG(printk("stradis%d irq: FIDB\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PIN3) {
- IDEBUG(printk("stradis%d irq: PIN3\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PIN2) {
- IDEBUG(printk("stradis%d irq: PIN2\n", saa->nr));
- }
- if (astat & SAA7146_PSR_PIN0) {
- IDEBUG(printk("stradis%d irq: PIN0\n", saa->nr));
- }
- if (astat & SAA7146_PSR_ECS) {
- IDEBUG(printk("stradis%d irq: ECS\n", saa->nr));
- }
- if (astat & SAA7146_PSR_EC3S) {
- IDEBUG(printk("stradis%d irq: EC3S\n", saa->nr));
- }
- if (astat & SAA7146_PSR_EC0S) {
- IDEBUG(printk("stradis%d irq: EC0S\n", saa->nr));
- }
-#endif
- count++;
- if (count > 15)
- printk(KERN_WARNING "stradis%d: irq loop %d\n",
- saa->nr, count);
- if (count > 20) {
- saawrite(0, SAA7146_IER);
- printk(KERN_ERR
- "stradis%d: IRQ loop cleared\n", saa->nr);
- }
- }
-}
-
-static int ibm_send_command(struct saa7146 *saa,
- int command, int data, int chain)
-{
- int i;
-
- if (chain)
- debiwrite(saa, debNormal, IBM_MP2_COMMAND, (command << 1) | 1, 2);
- else
- debiwrite(saa, debNormal, IBM_MP2_COMMAND, command << 1, 2);
- debiwrite(saa, debNormal, IBM_MP2_CMD_DATA, data, 2);
- debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 1, 2);
- for (i = 0; i < 100 &&
- (debiread(saa, debNormal, IBM_MP2_CMD_STAT, 2) & 1); i++)
- schedule();
- if (i == 100)
- return -1;
- return 0;
-}
-
-static void cs4341_setlevel(struct saa7146 *saa, int left, int right)
-{
- I2CWrite(&(saa->i2c), 0x22, 0x03,
- left > 94 ? 94 : left, 2);
- I2CWrite(&(saa->i2c), 0x22, 0x04,
- right > 94 ? 94 : right, 2);
-}
-
-static void initialize_cs4341(struct saa7146 *saa)
-{
- int i;
- for (i = 0; i < 200; i++) {
- /* auto mute off, power on, no de-emphasis */
- /* I2S data up to 24-bit 64xFs internal SCLK */
- I2CWrite(&(saa->i2c), 0x22, 0x01, 0x11, 2);
- /* ATAPI mixer setings */
- I2CWrite(&(saa->i2c), 0x22, 0x02, 0x49, 2);
- /* attenuation left 3db */
- I2CWrite(&(saa->i2c), 0x22, 0x03, 0x00, 2);
- /* attenuation right 3db */
- I2CWrite(&(saa->i2c), 0x22, 0x04, 0x00, 2);
- I2CWrite(&(saa->i2c), 0x22, 0x01, 0x10, 2);
- if (I2CRead(&(saa->i2c), 0x22, 0x02, 1) == 0x49)
- break;
- schedule();
- }
- printk("stradis%d: CS4341 initialized (%d)\n", saa->nr, i);
- return;
-}
-
-static void initialize_cs8420(struct saa7146 *saa, int pro)
-{
- int i;
- u8 *sequence;
- if (pro)
- sequence = mode8420pro;
- else
- sequence = mode8420con;
- for (i = 0; i < INIT8420LEN; i++)
- I2CWrite(&(saa->i2c), 0x20, init8420[i * 2],
- init8420[i * 2 + 1], 2);
- for (i = 0; i < MODE8420LEN; i++)
- I2CWrite(&(saa->i2c), 0x20, sequence[i * 2],
- sequence[i * 2 + 1], 2);
- printk("stradis%d: CS8420 initialized\n", saa->nr);
-}
-
-static void initialize_saa7121(struct saa7146 *saa, int dopal)
-{
- int i, mod;
- u8 *sequence;
- if (dopal)
- sequence = init7121pal;
- else
- sequence = init7121ntsc;
- mod = saaread(SAA7146_PSR) & 0x08;
- /* initialize PAL/NTSC video encoder */
- for (i = 0; i < INIT7121LEN; i++) {
- if (NewCard) { /* handle new card encoder differences */
- if (sequence[i*2] == 0x3a)
- I2CWrite(&(saa->i2c), 0x88, 0x3a, 0x13, 2);
- else if (sequence[i*2] == 0x6b)
- I2CWrite(&(saa->i2c), 0x88, 0x6b, 0x20, 2);
- else if (sequence[i*2] == 0x6c)
- I2CWrite(&(saa->i2c), 0x88, 0x6c,
- dopal ? 0x09 : 0xf5, 2);
- else if (sequence[i*2] == 0x6d)
- I2CWrite(&(saa->i2c), 0x88, 0x6d,
- dopal ? 0x20 : 0x00, 2);
- else if (sequence[i*2] == 0x7a)
- I2CWrite(&(saa->i2c), 0x88, 0x7a,
- dopal ? (PALFirstActive - 1) :
- (NTSCFirstActive - 4), 2);
- else if (sequence[i*2] == 0x7b)
- I2CWrite(&(saa->i2c), 0x88, 0x7b,
- dopal ? PALLastActive :
- NTSCLastActive, 2);
- else I2CWrite(&(saa->i2c), 0x88, sequence[i * 2],
- sequence[i * 2 + 1], 2);
- } else {
- if (sequence[i*2] == 0x6b && mod)
- I2CWrite(&(saa->i2c), 0x88, 0x6b,
- (sequence[i * 2 + 1] ^ 0x09), 2);
- else if (sequence[i*2] == 0x7a)
- I2CWrite(&(saa->i2c), 0x88, 0x7a,
- dopal ? (PALFirstActive - 1) :
- (NTSCFirstActive - 4), 2);
- else if (sequence[i*2] == 0x7b)
- I2CWrite(&(saa->i2c), 0x88, 0x7b,
- dopal ? PALLastActive :
- NTSCLastActive, 2);
- else
- I2CWrite(&(saa->i2c), 0x88, sequence[i * 2],
- sequence[i * 2 + 1], 2);
- }
- }
-}
-
-static void set_genlock_offset(struct saa7146 *saa, int noffset)
-{
- int nCode;
- int PixelsPerLine = 858;
- if (CurrentMode == VIDEO_MODE_PAL)
- PixelsPerLine = 864;
- if (noffset > 500)
- noffset = 500;
- else if (noffset < -500)
- noffset = -500;
- nCode = noffset + 0x100;
- if (nCode == 1)
- nCode = 0x401;
- else if (nCode < 1) nCode = 0x400 + PixelsPerLine + nCode;
- debiwrite(saa, debNormal, XILINX_GLDELAY, nCode, 2);
-}
-
-static void set_out_format(struct saa7146 *saa, int mode)
-{
- initialize_saa7121(saa, (mode == VIDEO_MODE_NTSC ? 0 : 1));
- saa->boardcfg[2] = mode;
- /* do not adjust analog video parameters here, use saa7121 init */
- /* you will affect the SDI output on the new card */
- if (mode == VIDEO_MODE_PAL) { /* PAL */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x0808, 2);
- mdelay(50);
- saawrite(0x012002c0, SAA7146_NUM_LINE_BYTE1);
- if (NewCard) {
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
- 0xe100, 2);
- mdelay(50);
- }
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
- NewCard ? 0xe500: 0x6500, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
- (1 << 8) |
- (NewCard ? PALFirstActive : PALFirstActive-6), 2);
- } else { /* NTSC */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x0800, 2);
- mdelay(50);
- saawrite(0x00f002c0, SAA7146_NUM_LINE_BYTE1);
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
- NewCard ? 0xe100: 0x6100, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
- (1 << 8) |
- (NewCard ? NTSCFirstActive : NTSCFirstActive-6), 2);
- }
-}
-
-
-/* Intialize bitmangler to map from a byte value to the mangled word that
- * must be output to program the Xilinx part through the DEBI port.
- * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0
- * transfer FPGA code, init IBM chip, transfer IBM microcode
- * rev2 card mangles: 0->7 1->6 2->5 3->4 4->3 5->2 6->1 7->0
- */
-static u16 bitmangler[256];
-
-static int initialize_fpga(struct video_code *bitdata)
-{
- int i, num, startindex, failure = 0, loadtwo, loadfile = 0;
- u16 *dmabuf;
- u8 *newdma;
- struct saa7146 *saa;
-
- /* verify fpga code */
- for (startindex = 0; startindex < bitdata->datasize; startindex++)
- if (bitdata->data[startindex] == 255)
- break;
- if (startindex == bitdata->datasize) {
- printk(KERN_INFO "stradis: bad fpga code\n");
- return -1;
- }
- /* initialize all detected cards */
- for (num = 0; num < saa_num; num++) {
- saa = &saa7146s[num];
- if (saa->boardcfg[0] > 20)
- continue; /* card was programmed */
- loadtwo = (saa->boardcfg[18] & 0x10);
- if (!NewCard) /* we have an old board */
- for (i = 0; i < 256; i++)
- bitmangler[i] = ((i & 0x01) << 15) |
- ((i & 0x02) << 6) | ((i & 0x04) << 4) |
- ((i & 0x08) << 9) | ((i & 0x10) << 7) |
- ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
- ((i & 0x80) >> 7);
- else /* else we have a new board */
- for (i = 0; i < 256; i++)
- bitmangler[i] = ((i & 0x01) << 7) |
- ((i & 0x02) << 5) | ((i & 0x04) << 3) |
- ((i & 0x08) << 1) | ((i & 0x10) >> 1) |
- ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
- ((i & 0x80) >> 7);
-
- dmabuf = (u16 *) saa->dmadebi;
- newdma = (u8 *) saa->dmadebi;
- if (NewCard) { /* SDM2xxx */
- if (!strncmp(bitdata->loadwhat, "decoder2", 8))
- continue; /* fpga not for this card */
- if (!strncmp(&saa->boardcfg[42],
- bitdata->loadwhat, 8)) {
- loadfile = 1;
- } else if (loadtwo && !strncmp(&saa->boardcfg[19],
- bitdata->loadwhat, 8)) {
- loadfile = 2;
- } else if (!saa->boardcfg[42] && /* special */
- !strncmp("decxl", bitdata->loadwhat, 8)) {
- loadfile = 1;
- } else
- continue; /* fpga not for this card */
- if (loadfile != 1 && loadfile != 2) {
- continue; /* skip to next card */
- }
- if (saa->boardcfg[0] && loadfile == 1 )
- continue; /* skip to next card */
- if (saa->boardcfg[0] != 1 && loadfile == 2)
- continue; /* skip to next card */
- saa->boardcfg[0]++; /* mark fpga handled */
- printk("stradis%d: loading %s\n", saa->nr,
- bitdata->loadwhat);
- if (loadtwo && loadfile == 2)
- goto send_fpga_stuff;
- /* turn on the Audio interface to set PROG low */
- saawrite(0x00400040, SAA7146_GPIO_CTRL);
- saaread(SAA7146_PSR); /* ensure posted write */
- /* wait for everyone to reset */
- mdelay(10);
- saawrite(0x00400000, SAA7146_GPIO_CTRL);
- } else { /* original card */
- if (strncmp(bitdata->loadwhat, "decoder2", 8))
- continue; /* fpga not for this card */
- /* Pull the Xilinx PROG signal WS3 low */
- saawrite(0x02000200, SAA7146_MC1);
- /* Turn on the Audio interface so can set PROG low */
- saawrite(0x000000c0, SAA7146_ACON1);
- /* Pull the Xilinx INIT signal (GPIO2) low */
- saawrite(0x00400000, SAA7146_GPIO_CTRL);
- /* Make sure everybody resets */
- saaread(SAA7146_PSR); /* ensure posted write */
- mdelay(10);
- /* Release the Xilinx PROG signal */
- saawrite(0x00000000, SAA7146_ACON1);
- /* Turn off the Audio interface */
- saawrite(0x02000000, SAA7146_MC1);
- }
- /* Release Xilinx INIT signal (WS2) */
- saawrite(0x00000000, SAA7146_GPIO_CTRL);
- /* Wait for the INIT to go High */
- for (i = 0; i < 10000 &&
- !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++)
- schedule();
- if (i == 1000) {
- printk(KERN_INFO "stradis%d: no fpga INIT\n", saa->nr);
- return -1;
- }
-send_fpga_stuff:
- if (NewCard) {
- for (i = startindex; i < bitdata->datasize; i++)
- newdma[i - startindex] =
- bitmangler[bitdata->data[i]];
- debiwrite(saa, 0x01420000, 0, 0,
- ((bitdata->datasize - startindex) + 5));
- if (loadtwo) {
- if (loadfile == 1) {
- printk("stradis%d: "
- "awaiting 2nd FPGA bitfile\n",
- saa->nr);
- continue; /* skip to next card */
- }
-
- }
- } else {
- for (i = startindex; i < bitdata->datasize; i++)
- dmabuf[i - startindex] =
- bitmangler[bitdata->data[i]];
- debiwrite(saa, 0x014a0000, 0, 0,
- ((bitdata->datasize - startindex) + 5) * 2);
- }
- for (i = 0; i < 1000 &&
- !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++)
- schedule();
- if (i == 1000) {
- printk(KERN_INFO "stradis%d: FPGA load failed\n",
- saa->nr);
- failure++;
- continue;
- }
- if (!NewCard) {
- /* Pull the Xilinx INIT signal (GPIO2) low */
- saawrite(0x00400000, SAA7146_GPIO_CTRL);
- saaread(SAA7146_PSR); /* ensure posted write */
- mdelay(2);
- saawrite(0x00000000, SAA7146_GPIO_CTRL);
- mdelay(2);
- }
- printk(KERN_INFO "stradis%d: FPGA Loaded\n", saa->nr);
- saa->boardcfg[0] = 26; /* mark fpga programmed */
- /* set VXCO to its lowest frequency */
- debiwrite(saa, debNormal, XILINX_PWM, 0, 2);
- if (NewCard) {
- /* mute CS3310 */
- if (HaveCS3310)
- debiwrite(saa, debNormal, XILINX_CS3310_CMPLT,
- 0, 2);
- /* set VXCO to PWM mode, release reset, blank on */
- debiwrite(saa, debNormal, XILINX_CTL0, 0xffc4, 2);
- mdelay(10);
- /* unmute CS3310 */
- if (HaveCS3310)
- debiwrite(saa, debNormal, XILINX_CTL0,
- 0x2020, 2);
- }
- /* set source Black */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
- saa->boardcfg[4] = 22; /* set NTSC First Active Line */
- saa->boardcfg[5] = 23; /* set PAL First Active Line */
- saa->boardcfg[54] = 2; /* set NTSC Last Active Line - 256 */
- saa->boardcfg[55] = 54; /* set PAL Last Active Line - 256 */
- set_out_format(saa, VIDEO_MODE_NTSC);
- mdelay(50);
- /* begin IBM chip init */
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
- saaread(SAA7146_PSR); /* wait for reset */
- mdelay(5);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
- debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0x10, 2);
- debiwrite(saa, debNormal, IBM_MP2_CMD_ADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
- if (NewCard) {
- mdelay(5);
- /* set i2s rate converter to 48KHz */
- debiwrite(saa, debNormal, 0x80c0, 6, 2);
- /* we must init CS8420 first since rev b pulls i2s */
- /* master clock low and CS4341 needs i2s master to */
- /* run the i2c port. */
- if (HaveCS8420) {
- /* 0=consumer, 1=pro */
- initialize_cs8420(saa, 0);
- }
- mdelay(5);
- if (HaveCS4341)
- initialize_cs4341(saa);
- }
- debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
- debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
- if (NewCard)
- set_genlock_offset(saa, 0);
- debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
-#if 0
- /* enable genlock */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x8000, 2);
-#else
- /* disable genlock */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x8080, 2);
-#endif
- }
- return failure;
-}
-
-static int do_ibm_reset(struct saa7146 *saa)
-{
- /* failure if decoder not previously programmed */
- if (saa->boardcfg[0] < 37)
- return -EIO;
- /* mute CS3310 */
- if (HaveCS3310)
- debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2);
- /* disable interrupts */
- saawrite(0, SAA7146_IER);
- saa->audhead = saa->audtail = 0;
- saa->vidhead = saa->vidtail = 0;
- /* tristate debi bus, disable debi transfers */
- saawrite(0x00880000, SAA7146_MC1);
- /* ensure posted write */
- saaread(SAA7146_MC1);
- mdelay(50);
- /* re-enable debi transfers */
- saawrite(0x00880088, SAA7146_MC1);
- /* set source Black */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
- /* begin IBM chip init */
- set_out_format(saa, CurrentMode);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
- saaread(SAA7146_PSR); /* wait for reset */
- mdelay(5);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
- debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
- if (NewCard) {
- mdelay(5);
- /* set i2s rate converter to 48KHz */
- debiwrite(saa, debNormal, 0x80c0, 6, 2);
- /* we must init CS8420 first since rev b pulls i2s */
- /* master clock low and CS4341 needs i2s master to */
- /* run the i2c port. */
- if (HaveCS8420) {
- /* 0=consumer, 1=pro */
- initialize_cs8420(saa, 1);
- }
- mdelay(5);
- if (HaveCS4341)
- initialize_cs4341(saa);
- }
- debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
- debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
- if (NewCard)
- set_genlock_offset(saa, 0);
- debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
- if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
- (ChipControl == 0x43 ? 0xe800 : 0xe000), 1)) {
- printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr);
- }
- if (HaveCS3310) {
- int i = CS3310MaxLvl;
- debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i<<8)|i), 2);
- }
- /* start video decoder */
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
- /* 256k vid, 3520 bytes aud */
- debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
- ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
- /* enable buffer threshold irq */
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
- /* clear pending interrupts */
- debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
- return 0;
-}
-
-/* load the decoder microcode */
-static int initialize_ibmmpeg2(struct video_code *microcode)
-{
- int i, num;
- struct saa7146 *saa;
-
- for (num = 0; num < saa_num; num++) {
- saa = &saa7146s[num];
- /* check that FPGA is loaded */
- debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0xa55a, 2);
- if ((i = debiread(saa, debNormal, IBM_MP2_OSD_SIZE, 2)) !=
- 0xa55a) {
- printk(KERN_INFO "stradis%d: %04x != 0xa55a\n",
- saa->nr, i);
-#if 0
- return -1;
-#endif
- }
- if (!strncmp(microcode->loadwhat, "decoder.vid", 11)) {
- if (saa->boardcfg[0] > 27)
- continue; /* skip to next card */
- /* load video control store */
- saa->boardcfg[1] = 0x13; /* no-sync default */
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
- debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
- for (i = 0; i < microcode->datasize / 2; i++)
- debiwrite(saa, debNormal, IBM_MP2_PROC_IDATA,
- (microcode->data[i * 2] << 8) |
- microcode->data[i * 2 + 1], 2);
- debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- saa->boardcfg[0] = 28;
- }
- if (!strncmp(microcode->loadwhat, "decoder.aud", 11)) {
- if (saa->boardcfg[0] > 35)
- continue; /* skip to next card */
- /* load audio control store */
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
- for (i = 0; i < microcode->datasize; i++)
- debiwrite(saa, debNormal, IBM_MP2_AUD_IDATA,
- microcode->data[i], 1);
- debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
- if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
- 0xe000, 1)) {
- printk(KERN_ERR
- "stradis%d: IBM config failed\n",
- saa->nr);
- return -1;
- }
- /* set PWM to center value */
- if (NewCard) {
- debiwrite(saa, debNormal, XILINX_PWM,
- saa->boardcfg[14] +
- (saa->boardcfg[13]<<8), 2);
- } else
- debiwrite(saa, debNormal, XILINX_PWM,
- 0x46, 2);
- if (HaveCS3310) {
- i = CS3310MaxLvl;
- debiwrite(saa, debNormal,
- XILINX_CS3310_CMPLT, ((i<<8)|i), 2);
- }
- printk(KERN_INFO
- "stradis%d: IBM MPEGCD%d Initialized\n",
- saa->nr, 18 + (debiread(saa, debNormal,
- IBM_MP2_CHIP_CONTROL, 2) >> 12));
- /* start video decoder */
- debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD,
- 0x4037, 2); /* 256k vid, 3520 bytes aud */
- debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
- ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
- /* enable buffer threshold irq */
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
- debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
- /* enable gpio irq */
- saawrite(0x00002000, SAA7146_GPIO_CTRL);
- /* enable decoder output to HPS */
- debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
- saa->boardcfg[0] = 37;
- }
- }
- return 0;
-}
-
-static u32 palette2fmt[] =
-{ /* some of these YUV translations are wrong */
- 0xffffffff, 0x86000000, 0x87000000, 0x80000000, 0x8100000, 0x82000000,
- 0x83000000, 0x00000000, 0x03000000, 0x03000000, 0x0a00000, 0x03000000,
- 0x06000000, 0x00000000, 0x03000000, 0x0a000000, 0x0300000
-};
-static int bpp2fmt[4] =
-{
- VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB24,
- VIDEO_PALETTE_RGB32
-};
-
-/* I wish I could find a formula to calculate these... */
-static u32 h_prescale[64] =
-{
- 0x10000000, 0x18040202, 0x18080000, 0x380c0606, 0x38100204, 0x38140808,
- 0x38180000, 0x381c0000, 0x3820161c, 0x38242a3b, 0x38281230, 0x382c4460,
- 0x38301040, 0x38340080, 0x38380000, 0x383c0000, 0x3840fefe, 0x3844ee9f,
- 0x3848ee9f, 0x384cee9f, 0x3850ee9f, 0x38542a3b, 0x38581230, 0x385c0000,
- 0x38600000, 0x38640000, 0x38680000, 0x386c0000, 0x38700000, 0x38740000,
- 0x38780000, 0x387c0000, 0x30800000, 0x38840000, 0x38880000, 0x388c0000,
- 0x38900000, 0x38940000, 0x38980000, 0x389c0000, 0x38a00000, 0x38a40000,
- 0x38a80000, 0x38ac0000, 0x38b00000, 0x38b40000, 0x38b80000, 0x38bc0000,
- 0x38c00000, 0x38c40000, 0x38c80000, 0x38cc0000, 0x38d00000, 0x38d40000,
- 0x38d80000, 0x38dc0000, 0x38e00000, 0x38e40000, 0x38e80000, 0x38ec0000,
- 0x38f00000, 0x38f40000, 0x38f80000, 0x38fc0000,
-};
-static u32 v_gain[64] =
-{
- 0x016000ff, 0x016100ff, 0x016100ff, 0x016200ff, 0x016200ff, 0x016200ff,
- 0x016200ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff,
- 0x016300ff, 0x016300ff, 0x016300ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
- 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
-};
-
-
-static void saa7146_set_winsize(struct saa7146 *saa)
-{
- u32 format;
- int offset, yacl, ysci;
- saa->win.color_fmt = format =
- (saa->win.depth == 15) ? palette2fmt[VIDEO_PALETTE_RGB555] :
- palette2fmt[bpp2fmt[(saa->win.bpp - 1) & 3]];
- offset = saa->win.x * saa->win.bpp + saa->win.y * saa->win.bpl;
- saawrite(saa->win.vidadr + offset, SAA7146_BASE_EVEN1);
- saawrite(saa->win.vidadr + offset + saa->win.bpl, SAA7146_BASE_ODD1);
- saawrite(saa->win.bpl * 2, SAA7146_PITCH1);
- saawrite(saa->win.vidadr + saa->win.bpl * saa->win.sheight,
- SAA7146_PROT_ADDR1);
- saawrite(0, SAA7146_PAGE1);
- saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL);
- offset = (704 / (saa->win.width - 1)) & 0x3f;
- saawrite(h_prescale[offset], SAA7146_HPS_H_PRESCALE);
- offset = (720896 / saa->win.width) / (offset + 1);
- saawrite((offset<<12)|0x0c, SAA7146_HPS_H_SCALE);
- if (CurrentMode == VIDEO_MODE_NTSC) {
- yacl = /*(480 / saa->win.height - 1) & 0x3f*/ 0;
- ysci = 1024 - (saa->win.height * 1024 / 480);
- } else {
- yacl = /*(576 / saa->win.height - 1) & 0x3f*/ 0;
- ysci = 1024 - (saa->win.height * 1024 / 576);
- }
- saawrite((1<<31)|(ysci<<21)|(yacl<<15), SAA7146_HPS_V_SCALE);
- saawrite(v_gain[yacl], SAA7146_HPS_V_GAIN);
- saawrite(((SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V |
- SAA7146_MC2_UPLD_HPS_H) << 16) | (SAA7146_MC2_UPLD_DMA1 |
- SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H),
- SAA7146_MC2);
-}
-
-/* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area
- * bitmap is fixed width, 128 bytes (1024 pixels represented)
- * arranged most-sigificant-bit-left in 32-bit words
- * based on saa7146 clipping hardware, it swaps bytes if LE
- * much of this makes up for egcs brain damage -- so if you
- * are wondering "why did he do this?" it is because the C
- * was adjusted to generate the optimal asm output without
- * writing non-portable __asm__ directives.
- */
-
-static void clip_draw_rectangle(u32 *clipmap, int x, int y, int w, int h)
-{
- register int startword, endword;
- register u32 bitsleft, bitsright;
- u32 *temp;
- if (x < 0) {
- w += x;
- x = 0;
- }
- if (y < 0) {
- h += y;
- y = 0;
- }
- if (w <= 0 || h <= 0 || x > 1023 || y > 639)
- return; /* throw away bad clips */
- if (x + w > 1024)
- w = 1024 - x;
- if (y + h > 640)
- h = 640 - y;
- startword = (x >> 5);
- endword = ((x + w) >> 5);
- bitsleft = (0xffffffff >> (x & 31));
- bitsright = (0xffffffff << (~((x + w) - (endword<<5))));
- temp = &clipmap[(y<<5) + startword];
- w = endword - startword;
- if (!w) {
- bitsleft |= bitsright;
- for (y = 0; y < h; y++) {
- *temp |= bitsleft;
- temp += 32;
- }
- } else {
- for (y = 0; y < h; y++) {
- *temp++ |= bitsleft;
- for (x = 1; x < w; x++)
- *temp++ = 0xffffffff;
- *temp |= bitsright;
- temp += (32 - w);
- }
- }
-}
-
-static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr)
-{
- int i, width, height;
- u32 *clipmap;
-
- clipmap = saa->dmavid2;
- if((width=saa->win.width)>1023)
- width = 1023; /* sanity check */
- if((height=saa->win.height)>640)
- height = 639; /* sanity check */
- if (ncr > 0) { /* rectangles pased */
- /* convert rectangular clips to a bitmap */
- memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */
- for (i = 0; i < ncr; i++)
- clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,
- cr[i].width, cr[i].height);
- }
- /* clip against viewing window AND screen
- so we do not have to rely on the user program
- */
- clip_draw_rectangle(clipmap,(saa->win.x+width>saa->win.swidth) ?
- (saa->win.swidth-saa->win.x) : width, 0, 1024, 768);
- clip_draw_rectangle(clipmap,0,(saa->win.y+height>saa->win.sheight) ?
- (saa->win.sheight-saa->win.y) : height,1024,768);
- if (saa->win.x<0)
- clip_draw_rectangle(clipmap, 0, 0, -(saa->win.x), 768);
- if (saa->win.y<0)
- clip_draw_rectangle(clipmap, 0, 0, 1024, -(saa->win.y));
-}
-
-static int saa_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct saa7146 *saa = (struct saa7146 *) dev;
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability b;
- strcpy(b.name, saa->video_dev.name);
- b.type = VID_TYPE_CAPTURE |
- VID_TYPE_OVERLAY |
- VID_TYPE_CLIPPING |
- VID_TYPE_FRAMERAM |
- VID_TYPE_SCALES;
- b.channels = 1;
- b.audios = 1;
- b.maxwidth = 768;
- b.maxheight = 576;
- b.minwidth = 32;
- b.minheight = 32;
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture p = saa->picture;
- if (saa->win.depth == 8)
- p.palette = VIDEO_PALETTE_HI240;
- if (saa->win.depth == 15)
- p.palette = VIDEO_PALETTE_RGB555;
- if (saa->win.depth == 16)
- p.palette = VIDEO_PALETTE_RGB565;
- if (saa->win.depth == 24)
- p.palette = VIDEO_PALETTE_RGB24;
- if (saa->win.depth == 32)
- p.palette = VIDEO_PALETTE_RGB32;
- if (copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture p;
- u32 format;
- if (copy_from_user(&p, arg, sizeof(p)))
- return -EFAULT;
- if (p.palette < sizeof(palette2fmt) / sizeof(u32)) {
- format = palette2fmt[p.palette];
- saa->win.color_fmt = format;
- saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL);
- }
- saawrite(((p.brightness & 0xff00) << 16) |
- ((p.contrast & 0xfe00) << 7) |
- ((p.colour & 0xfe00) >> 9), SAA7146_BCS_CTRL);
- saa->picture = p;
- /* upload changed registers */
- saawrite(((SAA7146_MC2_UPLD_HPS_H |
- SAA7146_MC2_UPLD_HPS_V) << 16) |
- SAA7146_MC2_UPLD_HPS_H | SAA7146_MC2_UPLD_HPS_V,
- SAA7146_MC2);
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- struct video_clip *vcp = NULL;
-
- if (copy_from_user(&vw, arg, sizeof(vw)))
- return -EFAULT;
-
- if (vw.flags || vw.width < 16 || vw.height < 16) { /* stop capture */
- saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
- return -EINVAL;
- }
- if (saa->win.bpp < 4) { /* 32-bit align start and adjust width */
- int i = vw.x;
- vw.x = (vw.x + 3) & ~3;
- i = vw.x - i;
- vw.width -= i;
- }
- saa->win.x = vw.x;
- saa->win.y = vw.y;
- saa->win.width = vw.width;
- if (saa->win.width > 768)
- saa->win.width = 768;
- saa->win.height = vw.height;
- if (CurrentMode == VIDEO_MODE_NTSC) {
- if (saa->win.height > 480)
- saa->win.height = 480;
- } else {
- if (saa->win.height > 576)
- saa->win.height = 576;
- }
-
- /* stop capture */
- saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
- saa7146_set_winsize(saa);
-
- /*
- * Do any clips.
- */
- if (vw.clipcount < 0) {
- if (copy_from_user(saa->dmavid2, vw.clips,
- VIDEO_CLIPMAP_SIZE))
- return -EFAULT;
- } else if (vw.clipcount > 0) {
- if ((vcp = vmalloc(sizeof(struct video_clip) *
- (vw.clipcount))) == NULL)
- return -ENOMEM;
- if (copy_from_user(vcp, vw.clips,
- sizeof(struct video_clip) *
- vw.clipcount)) {
- vfree(vcp);
- return -EFAULT;
- }
- } else /* nothing clipped */
- memset(saa->dmavid2, 0, VIDEO_CLIPMAP_SIZE);
- make_clip_tab(saa, vcp, vw.clipcount);
- if (vw.clipcount > 0)
- vfree(vcp);
-
- /* start capture & clip dma if we have an address */
- if ((saa->cap & 3) && saa->win.vidadr != 0)
- saawrite(((SAA7146_MC1_TR_E_1 |
- SAA7146_MC1_TR_E_2) << 16) | 0xffff,
- SAA7146_MC1);
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
- vw.x = saa->win.x;
- vw.y = saa->win.y;
- vw.width = saa->win.width;
- vw.height = saa->win.height;
- vw.chromakey = 0;
- vw.flags = 0;
- if (copy_to_user(arg, &vw, sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- {
- int v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v == 0) {
- saa->cap &= ~1;
- saawrite((SAA7146_MC1_TR_E_1 << 16),
- SAA7146_MC1);
- } else {
- if (saa->win.vidadr == 0 || saa->win.width == 0
- || saa->win.height == 0)
- return -EINVAL;
- saa->cap |= 1;
- saawrite((SAA7146_MC1_TR_E_1 << 16) | 0xffff,
- SAA7146_MC1);
- }
- return 0;
- }
- case VIDIOCGFBUF:
- {
- struct video_buffer v;
- v.base = (void *) saa->win.vidadr;
- v.height = saa->win.sheight;
- v.width = saa->win.swidth;
- v.depth = saa->win.depth;
- v.bytesperline = saa->win.bpl;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
-
- }
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if (v.depth != 8 && v.depth != 15 && v.depth != 16 &&
- v.depth != 24 && v.depth != 32 && v.width > 16 &&
- v.height > 16 && v.bytesperline > 16)
- return -EINVAL;
- if (v.base)
- saa->win.vidadr = (unsigned long) v.base;
- saa->win.sheight = v.height;
- saa->win.swidth = v.width;
- saa->win.bpp = ((v.depth + 7) & 0x38) / 8;
- saa->win.depth = v.depth;
- saa->win.bpl = v.bytesperline;
-
- DEBUG(printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n",
- v.base, v.width, v.height, saa->win.bpp, saa->win.bpl));
- saa7146_set_winsize(saa);
- return 0;
- }
- case VIDIOCKEY:
- {
- /* Will be handled higher up .. */
- return 0;
- }
-
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- v = saa->audio_dev;
- v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
- v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
- strcpy(v.name, "MPEG");
- v.mode = VIDEO_SOUND_STEREO;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- int i;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- i = (~(v.volume>>8))&0xff;
- if (!HaveCS4341) {
- if (v.flags & VIDEO_AUDIO_MUTE) {
- debiwrite(saa, debNormal,
- IBM_MP2_FRNT_ATTEN,
- 0xffff, 2);
- }
- if (!(v.flags & VIDEO_AUDIO_MUTE))
- debiwrite(saa, debNormal,
- IBM_MP2_FRNT_ATTEN,
- 0x0000, 2);
- if (v.flags & VIDEO_AUDIO_VOLUME)
- debiwrite(saa, debNormal,
- IBM_MP2_FRNT_ATTEN,
- (i<<8)|i, 2);
- } else {
- if (v.flags & VIDEO_AUDIO_MUTE)
- cs4341_setlevel(saa, 0xff, 0xff);
- if (!(v.flags & VIDEO_AUDIO_MUTE))
- cs4341_setlevel(saa, 0, 0);
- if (v.flags & VIDEO_AUDIO_VOLUME)
- cs4341_setlevel(saa, i, i);
- }
- saa->audio_dev = v;
- return 0;
- }
-
- case VIDIOCGUNIT:
- {
- struct video_unit vu;
- vu.video = saa->video_dev.minor;
- vu.vbi = VIDEO_NO_UNIT;
- vu.radio = VIDEO_NO_UNIT;
- vu.audio = VIDEO_NO_UNIT;
- vu.teletext = VIDEO_NO_UNIT;
- if (copy_to_user((void *) arg, (void *) &vu, sizeof(vu)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPLAYMODE:
- {
- struct video_play_mode pmode;
- if (copy_from_user((void *) &pmode, arg,
- sizeof(struct video_play_mode)))
- return -EFAULT;
- switch (pmode.mode) {
- case VID_PLAY_VID_OUT_MODE:
- if (pmode.p1 != VIDEO_MODE_NTSC &&
- pmode.p1 != VIDEO_MODE_PAL)
- return -EINVAL;
- set_out_format(saa, pmode.p1);
- return 0;
- case VID_PLAY_GENLOCK:
- debiwrite(saa, debNormal,
- XILINX_CTL0,
- (pmode.p1 ? 0x8000 : 0x8080),
- 2);
- if (NewCard)
- set_genlock_offset(saa,
- pmode.p2);
- return 0;
- case VID_PLAY_NORMAL:
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- ibm_send_command(saa,
- IBM_MP2_PLAY, 0, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_PAUSE:
- /* IBM removed the PAUSE command */
- /* they say use SINGLE_FRAME now */
- case VID_PLAY_SINGLE_FRAME:
- ibm_send_command(saa,
- IBM_MP2_SINGLE_FRAME,
- 0, 0);
- if (saa->playmode == pmode.mode) {
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- }
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_FAST_FORWARD:
- ibm_send_command(saa,
- IBM_MP2_FAST_FORWARD, 0, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_SLOW_MOTION:
- ibm_send_command(saa,
- IBM_MP2_SLOW_MOTION,
- pmode.p1, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_IMMEDIATE_NORMAL:
- /* ensure transfers resume */
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- ibm_send_command(saa,
- IBM_MP2_IMED_NORM_PLAY, 0, 0);
- saa->playmode = VID_PLAY_NORMAL;
- return 0;
- case VID_PLAY_SWITCH_CHANNELS:
- saa->audhead = saa->audtail = 0;
- saa->vidhead = saa->vidtail = 0;
- ibm_send_command(saa,
- IBM_MP2_FREEZE_FRAME, 0, 1);
- ibm_send_command(saa,
- IBM_MP2_RESET_AUD_RATE, 0, 1);
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL, 0, 2);
- ibm_send_command(saa,
- IBM_MP2_CHANNEL_SWITCH, 0, 1);
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- ibm_send_command(saa,
- IBM_MP2_PLAY, 0, 0);
- saa->playmode = VID_PLAY_NORMAL;
- return 0;
- case VID_PLAY_FREEZE_FRAME:
- ibm_send_command(saa,
- IBM_MP2_FREEZE_FRAME, 0, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_STILL_MODE:
- ibm_send_command(saa,
- IBM_MP2_SET_STILL_MODE, 0, 0);
- saa->playmode = pmode.mode;
- return 0;
- case VID_PLAY_MASTER_MODE:
- if (pmode.p1 == VID_PLAY_MASTER_NONE)
- saa->boardcfg[1] = 0x13;
- else if (pmode.p1 ==
- VID_PLAY_MASTER_VIDEO)
- saa->boardcfg[1] = 0x23;
- else if (pmode.p1 ==
- VID_PLAY_MASTER_AUDIO)
- saa->boardcfg[1] = 0x43;
- else
- return -EINVAL;
- debiwrite(saa, debNormal,
- IBM_MP2_CHIP_CONTROL,
- ChipControl, 2);
- return 0;
- case VID_PLAY_ACTIVE_SCANLINES:
- if (CurrentMode == VIDEO_MODE_PAL) {
- if (pmode.p1 < 1 ||
- pmode.p2 > 625)
- return -EINVAL;
- saa->boardcfg[5] = pmode.p1;
- saa->boardcfg[55] = (pmode.p1 +
- (pmode.p2/2) - 1) &
- 0xff;
- } else {
- if (pmode.p1 < 4 ||
- pmode.p2 > 525)
- return -EINVAL;
- saa->boardcfg[4] = pmode.p1;
- saa->boardcfg[54] = (pmode.p1 +
- (pmode.p2/2) - 4) &
- 0xff;
- }
- set_out_format(saa, CurrentMode);
- case VID_PLAY_RESET:
- return do_ibm_reset(saa);
- case VID_PLAY_END_MARK:
- if (saa->endmarktail <
- saa->endmarkhead) {
- if (saa->endmarkhead -
- saa->endmarktail < 2)
- return -ENOSPC;
- } else if (saa->endmarkhead <=
- saa->endmarktail) {
- if (saa->endmarktail -
- saa->endmarkhead >
- (MAX_MARKS - 2))
- return -ENOSPC;
- } else
- return -ENOSPC;
- saa->endmark[saa->endmarktail] =
- saa->audtail;
- saa->endmarktail++;
- if (saa->endmarktail >= MAX_MARKS)
- saa->endmarktail = 0;
- }
- return -EINVAL;
- }
- case VIDIOCSWRITEMODE:
- {
- int mode;
- if (copy_from_user((void *) &mode, arg, sizeof(int)))
- return -EFAULT;
- if (mode == VID_WRITE_MPEG_AUD ||
- mode == VID_WRITE_MPEG_VID ||
- mode == VID_WRITE_CC ||
- mode == VID_WRITE_TTX ||
- mode == VID_WRITE_OSD) {
- saa->writemode = mode;
- return 0;
- }
- return -EINVAL;
- }
- case VIDIOCSMICROCODE:
- {
- struct video_code ucode;
- __u8 *udata;
- int i;
- if (copy_from_user((void *) &ucode, arg,
- sizeof(ucode)))
- return -EFAULT;
- if (ucode.datasize > 65536 || ucode.datasize < 1024 ||
- strncmp(ucode.loadwhat, "dec", 3))
- return -EINVAL;
- if ((udata = vmalloc(ucode.datasize)) == NULL)
- return -ENOMEM;
- if (copy_from_user((void *) udata, ucode.data,
- ucode.datasize)) {
- vfree(udata);
- return -EFAULT;
- }
- ucode.data = udata;
- if (!strncmp(ucode.loadwhat, "decoder.aud", 11)
- || !strncmp(ucode.loadwhat, "decoder.vid", 11))
- i = initialize_ibmmpeg2(&ucode);
- else
- i = initialize_fpga(&ucode);
- vfree(udata);
- if (i)
- return -EINVAL;
- return 0;
-
- }
- case VIDIOCGCHAN: /* this makes xawtv happy */
- {
- struct video_channel v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- v.flags = VIDEO_VC_AUDIO;
- v.tuners = 0;
- v.type = VID_TYPE_MPEG_DECODER;
- v.norm = CurrentMode;
- strcpy(v.name, "MPEG2");
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSCHAN: /* this makes xawtv happy */
- {
- struct video_channel v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- /* do nothing */
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static int saa_init_done(struct video_device *dev)
-{
- return 0;
-}
-
-static int saa_mmap(struct video_device *dev, const char *adr,
- unsigned long size)
-{
- struct saa7146 *saa = (struct saa7146 *) dev;
- printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr);
- return -EINVAL;
-}
-
-static long saa_read(struct video_device *dev, char *buf,
- unsigned long count, int nonblock)
-{
- return -EINVAL;
-}
-
-static long saa_write(struct video_device *dev, const char *buf,
- unsigned long count, int nonblock)
-{
- struct saa7146 *saa = (struct saa7146 *) dev;
- unsigned long todo = count;
- int blocksize, split;
- unsigned long flags;
-
- while (todo > 0) {
- if (saa->writemode == VID_WRITE_MPEG_AUD) {
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->audhead <= saa->audtail)
- blocksize = 65536-(saa->audtail - saa->audhead);
- else
- blocksize = saa->audhead - saa->audtail;
- spin_unlock_irqrestore(&saa->lock, flags);
- if (blocksize < 16384) {
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
- /* wait for buffer space to open */
- interruptible_sleep_on(&saa->audq);
- }
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->audhead <= saa->audtail) {
- blocksize = 65536-(saa->audtail - saa->audhead);
- split = 65536 - saa->audtail;
- } else {
- blocksize = saa->audhead - saa->audtail;
- split = 65536;
- }
- spin_unlock_irqrestore(&saa->lock, flags);
- blocksize--;
- if (blocksize > todo)
- blocksize = todo;
- /* double check that we really have space */
- if (!blocksize)
- return -ENOSPC;
- if (split < blocksize) {
- if (copy_from_user(saa->audbuf +
- saa->audtail, buf, split))
- return -EFAULT;
- buf += split;
- todo -= split;
- blocksize -= split;
- saa->audtail = 0;
- }
- if (copy_from_user(saa->audbuf + saa->audtail, buf,
- blocksize))
- return -EFAULT;
- saa->audtail += blocksize;
- todo -= blocksize;
- buf += blocksize;
- saa->audtail &= 0xffff;
- } else if (saa->writemode == VID_WRITE_MPEG_VID) {
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->vidhead <= saa->vidtail)
- blocksize=524288-(saa->vidtail - saa->vidhead);
- else
- blocksize = saa->vidhead - saa->vidtail;
- spin_unlock_irqrestore(&saa->lock, flags);
- if (blocksize < 65536) {
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
- /* wait for buffer space to open */
- interruptible_sleep_on(&saa->vidq);
- }
- spin_lock_irqsave(&saa->lock, flags);
- if (saa->vidhead <= saa->vidtail) {
- blocksize=524288-(saa->vidtail - saa->vidhead);
- split = 524288 - saa->vidtail;
- } else {
- blocksize = saa->vidhead - saa->vidtail;
- split = 524288;
- }
- spin_unlock_irqrestore(&saa->lock, flags);
- blocksize--;
- if (blocksize > todo)
- blocksize = todo;
- /* double check that we really have space */
- if (!blocksize)
- return -ENOSPC;
- if (split < blocksize) {
- if (copy_from_user(saa->vidbuf +
- saa->vidtail, buf, split))
- return -EFAULT;
- buf += split;
- todo -= split;
- blocksize -= split;
- saa->vidtail = 0;
- }
- if (copy_from_user(saa->vidbuf + saa->vidtail, buf,
- blocksize))
- return -EFAULT;
- saa->vidtail += blocksize;
- todo -= blocksize;
- buf += blocksize;
- saa->vidtail &= 0x7ffff;
- } else if (saa->writemode == VID_WRITE_OSD) {
- if (count > 131072)
- return -ENOSPC;
- if (copy_from_user(saa->osdbuf, buf, count))
- return -EFAULT;
- buf += count;
- saa->osdhead = 0;
- saa->osdtail = count;
- debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2);
- debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2);
- debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
- debiread(saa, debNormal,
- IBM_MP2_DISP_MODE, 2) | 1, 2);
- /* trigger osd data transfer */
- saawrite(SAA7146_PSR_DEBI_S |
- SAA7146_PSR_PIN1, SAA7146_IER);
- saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
- }
- }
- return count;
-}
-
-static int saa_open(struct video_device *dev, int flags)
-{
- struct saa7146 *saa = (struct saa7146 *) dev;
-
- saa->video_dev.busy = 0;
- saa->user++;
- if (saa->user > 1)
- return 0; /* device open already, don't reset */
- saa->writemode = VID_WRITE_MPEG_VID; /* default to video */
- return 0;
-}
-
-static void saa_close(struct video_device *dev)
-{
- struct saa7146 *saa = (struct saa7146 *) dev;
- saa->user--;
- saa->video_dev.busy = 0;
- if (saa->user > 0) /* still someone using device */
- return;
- saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */
-}
-
-/* template for video_device-structure */
-static struct video_device saa_template =
-{
- "SAA7146A",
- VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
- VID_HARDWARE_SAA7146,
- saa_open,
- saa_close,
- saa_read,
- saa_write,
- NULL, /* poll */
- saa_ioctl,
- saa_mmap,
- saa_init_done,
- NULL,
- 0,
- 0
-};
-
-static int configure_saa7146(struct pci_dev *dev, int num)
-{
- int result;
- struct saa7146 *saa;
-
- saa = &saa7146s[num];
-
- saa->endmarkhead = saa->endmarktail = 0;
- saa->win.x = saa->win.y = 0;
- saa->win.width = saa->win.cropwidth = 720;
- saa->win.height = saa->win.cropheight = 480;
- saa->win.cropx = saa->win.cropy = 0;
- saa->win.bpp = 2;
- saa->win.depth = 16;
- saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565];
- saa->win.bpl = 1024 * saa->win.bpp;
- saa->win.swidth = 1024;
- saa->win.sheight = 768;
- saa->picture.brightness = 32768;
- saa->picture.contrast = 38768;
- saa->picture.colour = 32768;
- saa->cap = 0;
- saa->dev = dev;
- saa->nr = num;
- saa->playmode = VID_PLAY_NORMAL;
- memset(saa->boardcfg, 0, 64); /* clear board config area */
- saa->saa7146_mem = NULL;
- saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in =
- saa->dmaa1out = saa->dmaa2in = saa->dmaa2out =
- saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in =
- saa->pagea1out = saa->pagea2in = saa->pagea2out =
- saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 =
- saa->pageRPS2 = NULL;
- saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL;
- saa->audhead = saa->vidtail = 0;
-
- init_waitqueue_head(&saa->i2cq);
- init_waitqueue_head(&saa->audq);
- init_waitqueue_head(&saa->debiq);
- init_waitqueue_head(&saa->vidq);
- spin_lock_init(&saa->lock);
-
- if (pci_enable_device(dev))
- return -EIO;
-
- saa->id = dev->device;
- saa->irq = dev->irq;
- saa->video_dev.minor = -1;
- saa->saa7146_adr = pci_resource_start(dev, 0);
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision);
-
- saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);
- if (!saa->saa7146_mem)
- return -EIO;
-
- memcpy(&(saa->i2c), &saa7146_i2c_bus_template, sizeof(struct i2c_bus));
- memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));
- sprintf(saa->i2c.name, "stradis%d", num);
- saa->i2c.data = saa;
- saawrite(0, SAA7146_IER); /* turn off all interrupts */
- result = request_irq(saa->irq, saa7146_irq,
- SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa);
- if (result == -EINVAL)
- printk(KERN_ERR "stradis%d: Bad irq number or handler\n",
- num);
- if (result == -EBUSY)
- printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP"
- " config in BIOS\n", num, saa->irq);
- if (result < 0)
- return result;
- pci_set_master(dev);
- if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER) < 0)
- return -1;
-#if 0
- /* i2c generic interface is currently BROKEN */
- i2c_register_bus(&saa->i2c);
-#endif
- return 0;
-}
-
-static int init_saa7146(int i)
-{
- struct saa7146 *saa = &saa7146s[i];
-
- saa->user = 0;
- /* reset the saa7146 */
- saawrite(0xffff0000, SAA7146_MC1);
- mdelay(5);
- /* enable debi and i2c transfers and pins */
- saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C |
- SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1);
- /* ensure proper state of chip */
- saawrite(0x00000000, SAA7146_PAGE1);
- saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1);
- saawrite(0x00000000, SAA7146_PAGE2);
- saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2);
- saawrite(0x00000000, SAA7146_DD1_INIT);
- saawrite(0x00000000, SAA7146_DD1_STREAM_B);
- saawrite(0x00000000, SAA7146_DD1_STREAM_A);
- saawrite(0x00000000, SAA7146_BRS_CTRL);
- saawrite(0x80400040, SAA7146_BCS_CTRL);
- saawrite(0x0000e000 /*| (1<<29)*/, SAA7146_HPS_CTRL);
- saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL);
- saawrite(0x00000000, SAA7146_ACON1);
- saawrite(0x00000000, SAA7146_ACON2);
- saawrite(0x00000600, SAA7146_I2C_STATUS);
- saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A |
- SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H |
- SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 |
- SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff,
- SAA7146_MC2);
- /* setup arbitration control registers */
- saawrite(0x1412121a, SAA7146_PCI_BT_V1);
-
- /* allocate 32k dma buffer + 4k for page table */
- if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "stradis%d: debi kmalloc failed\n", i);
- return -1;
- }
-#if 0
- saa->pagedebi = saa->dmadebi + 32768; /* top 4k is for mmu */
- saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE);
- for (i = 0; i < 12; i++) /* setup mmu page table */
- saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096));
-#endif
- saa->audhead = saa->vidhead = saa->osdhead = 0;
- saa->audtail = saa->vidtail = saa->osdtail = 0;
- if (saa->vidbuf == NULL)
- if ((saa->vidbuf = vmalloc(524288)) == NULL) {
- printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
- return -ENOMEM;
- }
- if (saa->audbuf == NULL)
- if ((saa->audbuf = vmalloc(65536)) == NULL) {
- printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
- vfree(saa->vidbuf);
- saa->vidbuf = NULL;
- return -ENOMEM;
- }
- if (saa->osdbuf == NULL)
- if ((saa->osdbuf = vmalloc(131072)) == NULL) {
- printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
- vfree(saa->vidbuf);
- vfree(saa->audbuf);
- saa->vidbuf = saa->audbuf = NULL;
- return -ENOMEM;
- }
- /* allocate 81920 byte buffer for clipping */
- if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "stradis%d: clip kmalloc failed\n", saa->nr);
- vfree(saa->vidbuf);
- vfree(saa->audbuf);
- vfree(saa->osdbuf);
- saa->vidbuf = saa->audbuf = saa->osdbuf = NULL;
- saa->dmavid2 = NULL;
- return -1;
- }
- memset(saa->dmavid2, 0x00, VIDEO_CLIPMAP_SIZE); /* clip everything */
- /* setup clipping registers */
- saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
- saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2);
- saawrite(virt_to_bus(saa->dmavid2) + VIDEO_CLIPMAP_SIZE,
- SAA7146_PROT_ADDR2);
- saawrite(256, SAA7146_PITCH2);
- saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */
- saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2,
- SAA7146_MC2);
- I2CBusScan(&(saa->i2c));
- return 0;
-}
-
-static void release_saa(void)
-{
- u8 command;
- int i;
- struct saa7146 *saa;
-
- for (i = 0; i < saa_num; i++) {
- saa = &saa7146s[i];
-
- /* turn off all capturing, DMA and IRQs */
- saawrite(0xffff0000, SAA7146_MC1); /* reset chip */
- saawrite(0, SAA7146_MC2);
- saawrite(0, SAA7146_IER);
- saawrite(0xffffffffUL, SAA7146_ISR);
-#if 0
- /* unregister i2c_bus */
- i2c_unregister_bus((&saa->i2c));
-#endif
-
- /* disable PCI bus-mastering */
- pci_read_config_byte(saa->dev, PCI_COMMAND, &command);
- /* Should this be &=~ ?? */
- command &= ~PCI_COMMAND_MASTER;
- pci_write_config_byte(saa->dev, PCI_COMMAND, command);
- /* unmap and free memory */
- saa->audhead = saa->audtail = saa->osdhead = 0;
- saa->vidhead = saa->vidtail = saa->osdtail = 0;
- if (saa->vidbuf)
- vfree(saa->vidbuf);
- if (saa->audbuf)
- vfree(saa->audbuf);
- if (saa->osdbuf)
- vfree(saa->osdbuf);
- if (saa->dmavid2)
- kfree((void *) saa->dmavid2);
- saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
- saa->dmavid2 = NULL;
- if (saa->dmadebi)
- kfree((void *) saa->dmadebi);
- if (saa->dmavid1)
- kfree((void *) saa->dmavid1);
- if (saa->dmavid2)
- kfree((void *) saa->dmavid2);
- if (saa->dmavid3)
- kfree((void *) saa->dmavid3);
- if (saa->dmaa1in)
- kfree((void *) saa->dmaa1in);
- if (saa->dmaa1out)
- kfree((void *) saa->dmaa1out);
- if (saa->dmaa2in)
- kfree((void *) saa->dmaa2in);
- if (saa->dmaa2out)
- kfree((void *) saa->dmaa2out);
- if (saa->dmaRPS1)
- kfree((void *) saa->dmaRPS1);
- if (saa->dmaRPS2)
- kfree((void *) saa->dmaRPS2);
- free_irq(saa->irq, saa);
- if (saa->saa7146_mem)
- iounmap(saa->saa7146_mem);
- if (saa->video_dev.minor != -1)
- video_unregister_device(&saa->video_dev);
- }
-}
-
-
-static int __init stradis_init (void)
-{
- struct pci_dev *dev = NULL;
- int result = 0, i;
-
- saa_num = 0;
-
- while ((dev = pci_find_device(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, dev))) {
- if (!dev->subsystem_vendor)
- printk(KERN_INFO "stradis%d: rev1 decoder\n", saa_num);
- else
- printk(KERN_INFO "stradis%d: SDM2xx found\n", saa_num);
- result = configure_saa7146(dev, saa_num++);
- if (result)
- return result;
- }
- if (saa_num)
- printk(KERN_INFO "stradis: %d card(s) found.\n", saa_num);
- else
- return -EINVAL;
- for (i = 0; i < saa_num; i++)
- if (init_saa7146(i) < 0) {
- release_saa();
- return -EIO;
- }
- return 0;
-}
-
-
-static void __exit stradis_exit (void)
-{
- release_saa();
- printk(KERN_INFO "stradis: module cleanup complete\n");
-}
-
-
-module_init(stradis_init);
-module_exit(stradis_exit);
-
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 82e3cae1e..e6336fc03 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1518,9 +1518,14 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
exit minicom. I expect an "oops". -- REW */
static void sx_hungup (void *ptr)
{
+ /*
struct sx_port *port = ptr;
+ */
func_enter ();
+ /* Don't force the SX card to close. mgetty doesn't like it !!!!!! -- pvdl */
+ /* For some reson we added this code. Don't know why anymore ;-( -- pvdl */
+ /*
sx_setsignals (port, 0, 0);
sx_reconfigure_port(port);
sx_send_command (port, HS_CLOSE, 0, 0);
@@ -1532,7 +1537,7 @@ static void sx_hungup (void *ptr)
} else
sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");
}
-
+ */
MOD_DEC_USE_COUNT;
func_exit ();
}
@@ -2368,7 +2373,7 @@ static int sx_init_portstructs (int nboards, int nports)
return 0;
}
-
+#ifdef MODULE
static void sx_release_drivers(void)
{
func_enter();
@@ -2376,6 +2381,7 @@ static void sx_release_drivers(void)
tty_unregister_driver(&sx_callout_driver);
func_exit();
}
+#endif
#ifdef TWO_ZERO
#define PDEV unsigned char pci_bus, unsigned pci_fun
diff --git a/drivers/char/tda7432.c b/drivers/char/tda7432.c
deleted file mode 100644
index 488091310..000000000
--- a/drivers/char/tda7432.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * For the STS-Thompson TDA7432 audio processor chip
- *
- * Handles audio functions: volume, balance, tone, loudness
- * This driver will not complain if used with any
- * other i2c device with the same address.
- *
- * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com>
- * This code is placed under the terms of the GNU General Public License
- * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
- * Which was based on tda8425.c by Greg Alexander (c) 1998
- *
- * OPTIONS:
- * debug - set to 1 if you'd like to see debug messages
- * set to 2 if you'd like to be inundated with debug messages
- *
- * loudness - set between 0 and 15 for varying degrees of loudness effect
- *
- * TODO:
- * Implement tone controls
- *
- * Revision: 0.3 - Fixed silly reversed volume controls. :)
- * Revision: 0.2 - Cleaned up #defines
- * fixed volume control
- * Added I2C_DRIVERID_TDA7432
- * added loudness insmod control
- * Revision: 0.1 - initial version
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/videodev.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "bttv.h"
-#include "audiochip.h"
-
-/* This driver ID is brand new, so define it if it's not in i2c-id.h yet */
-#ifndef I2C_DRIVERID_TDA7432
- #define I2C_DRIVERID_TDA7432 27
-#endif
-
-
-MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>");
-MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
-
-MODULE_PARM(debug,"i");
-MODULE_PARM(loudness,"i");
-static int loudness = 0; /* disable loudness by default */
-static int debug = 0; /* insmod parameter */
-
-
-/* Address to scan (I2C address of this chip) */
-static unsigned short normal_i2c[] = {
- I2C_TDA7432 >> 1,
- I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-/* Structure of address and subaddresses for the tda7432 */
-
-struct tda7432 {
- int addr;
- int input;
- int volume;
- int tone;
- int lf, lr, rf, rr;
- int loud;
-};
-
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
-#define dprintk if (debug) printk
-#define d2printk if (debug > 1) printk
-
-/* The TDA7432 is made by STS-Thompson
- * http://www.st.com
- * http://us.st.com/stonline/books/pdf/docs/4056.pdf
- *
- * TDA7432: I2C-bus controlled basic audio processor
- *
- * The TDA7432 controls basic audio functions like volume, balance,
- * and tone control (including loudness). It also has four channel
- * output (for front and rear). Since most vidcap cards probably
- * don't have 4 channel output, this driver will set front & rear
- * together (no independent control).
- */
-
- /* Subaddresses for TDA7432 */
-
-#define TDA7432_IN 0x00 /* Input select */
-#define TDA7432_VL 0x01 /* Volume */
-#define TDA7432_TN 0x02 /* Bass, Treble (Tone) */
-#define TDA7432_LF 0x03 /* Attenuation LF (Left Front) */
-#define TDA7432_LR 0x04 /* Attenuation LR (Left Rear) */
-#define TDA7432_RF 0x05 /* Attenuation RF (Right Front) */
-#define TDA7432_RR 0x06 /* Attenuation RR (Right Rear) */
-#define TDA7432_LD 0x07 /* Loudness */
-
-
- /* Masks for bits in TDA7432 subaddresses */
-
-/* Many of these not used - just for documentation */
-
-/* Subaddress 0x00 - Input selection and bass control */
-
-/* Bits 0,1,2 control input:
- * 0x00 - Stereo input
- * 0x02 - Mono input
- * 0x03 - Mute
- * Mono probably isn't used - I'm guessing only the stereo
- * input is connected on most cards, so we'll set it to stereo.
- *
- * Bit 3 controls bass cut: 0/1 is non-symmetric/symmetric bass cut
- * Bit 4 controls bass range: 0/1 is extended/standard bass range
- *
- * Highest 3 bits not used
- */
-
-#define TDA7432_STEREO_IN 0
-#define TDA7432_MONO_IN 2 /* Probably won't be used */
-#define TDA7432_MUTE 3 /* Probably won't be used */
-#define TDA7432_BASS_SYM 1 << 3
-#define TDA7432_BASS_NORM 1 << 4
-
-/* Subaddress 0x01 - Volume */
-
-/* Lower 7 bits control volume from -79dB to +32dB in 1dB steps
- * Recommended maximum is +20 dB
- *
- * +32dB: 0x00
- * +20dB: 0x0c
- * 0dB: 0x20
- * -79dB: 0x6f
- *
- * MSB (bit 7) controls loudness: 1/0 is loudness on/off
- */
-
-#define TDA7432_VOL_0DB 0x20
-#define TDA7432_LD_ON 1 << 7
-
-
-/* Subaddress 0x02 - Tone control */
-
-/* Bits 0,1,2 control absolute treble gain from 0dB to 14dB
- * 0x0 is 14dB, 0x7 is 0dB
- *
- * Bit 3 controls treble attenuation/gain (sign)
- * 1 = gain (+)
- * 0 = attenuation (-)
- *
- * Bits 4,5,6 control absolute bass gain from 0dB to 14dB
- * (This is only true for normal base range, set in 0x00)
- * 0x0 << 4 is 14dB, 0x7 is 0dB
- *
- * Bit 7 controls bass attenuation/gain (sign)
- * 1 << 7 = gain (+)
- * 0 << 7 = attenuation (-)
- *
- * Example:
- * 1 1 0 1 0 1 0 1 is +4dB bass, -4dB treble
- */
-
-#define TDA7432_TREBLE_0DB 0xf
-#define TDA7432_TREBLE 7
-#define TDA7432_TREBLE_GAIN 1 << 3
-#define TDA7432_BASS_0DB 0xf << 4
-#define TDA7432_BASS 7 << 4
-#define TDA7432_BASS_GAIN 1 << 7
-
-
-/* Subaddress 0x03 - Left Front attenuation */
-/* Subaddress 0x04 - Left Rear attenuation */
-/* Subaddress 0x05 - Right Front attenuation */
-/* Subaddress 0x06 - Right Rear attenuation */
-
-/* Bits 0,1,2,3,4 control attenuation from 0dB to -37.5dB
- * in 1.5dB steps.
- *
- * 0x00 is 0dB
- * 0x1f is -37.5dB
- *
- * Bit 5 mutes that channel when set (1 = mute, 0 = unmute)
- * We'll use the mute on the input, though (above)
- * Bits 6,7 unused
- */
-
-#define TDA7432_ATTEN_0DB 0x00
-
-
-/* Subaddress 0x07 - Loudness Control */
-
-/* Bits 0,1,2,3 control loudness from 0dB to -15dB in 1dB steps
- * when bit 4 is NOT set
- *
- * 0x0 is 0dB
- * 0xf is -15dB
- *
- * If bit 4 is set, then there is a flat attenuation according to
- * the lower 4 bits, as above.
- *
- * Bits 5,6,7 unused
- */
-
-
-
-/* Begin code */
-
-static int tda7432_write(struct i2c_client *client, int subaddr, int val)
-{
- unsigned char buffer[2];
- d2printk("tda7432: In tda7432_write\n");
- dprintk("tda7432: Writing %d 0x%x\n", subaddr, val);
- buffer[0] = subaddr;
- buffer[1] = val;
- if (2 != i2c_master_send(client,buffer,2)) {
- printk(KERN_WARNING "tda7432: I/O error, trying (write %d 0x%x)\n",
- subaddr, val);
- return -1;
- }
- return 0;
-}
-
-/* I don't think we ever actually _read_ the chip... */
-#if 0
-static int tda7432_read(struct i2c_client *client)
-{
- unsigned char buffer;
- d2printk("tda7432: In tda7432_read\n");
- if (1 != i2c_master_recv(client,&buffer,1)) {
- printk(KERN_WARNING "tda7432: I/O error, trying (read)\n");
- return -1;
- }
- dprintk("tda7432: Read 0x%02x\n", buffer);
- return buffer;
-}
-#endif
-
-static int tda7432_set(struct i2c_client *client)
-{
- struct tda7432 *t = client->data;
- unsigned char buf[16];
- d2printk("tda7432: In tda7432_set\n");
-
- dprintk(KERN_INFO
- "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
- t->input,t->volume,t->tone,t->lf,t->lr,t->rf,t->rr,t->loud);
- buf[0] = TDA7432_IN;
- buf[1] = t->input;
- buf[2] = t->volume;
- buf[3] = t->tone;
- buf[4] = t->lf;
- buf[5] = t->lr;
- buf[6] = t->rf;
- buf[7] = t->rr;
- buf[8] = t->loud;
- if (9 != i2c_master_send(client,buf,9)) {
- printk(KERN_WARNING "tda7432: I/O error, trying tda7432_set\n");
- return -1;
- }
-
- return 0;
-}
-
-static void do_tda7432_init(struct i2c_client *client)
-{
- struct tda7432 *t = client->data;
- d2printk("tda7432: In tda7432_init\n");
-
- t->input = TDA7432_STEREO_IN | /* Main (stereo) input */
- TDA7432_BASS_SYM | /* Symmetric bass cut */
- TDA7432_BASS_NORM; /* Normal bass range */
- t->volume = TDA7432_VOL_0DB; /* 0dB Volume */
- if (loudness) /* Turn loudness on? */
- t->volume |= TDA7432_LD_ON;
- t->tone = TDA7432_TREBLE_0DB | /* 0dB Treble */
- TDA7432_BASS_0DB; /* 0dB Bass */
- t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->lr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->rf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->loud = loudness; /* insmod parameter */
-
- tda7432_set(client);
-}
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tda7432_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- struct tda7432 *t;
- struct i2c_client *client;
- d2printk("tda7432: In tda7432_attach\n");
- client = kmalloc(sizeof *client,GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
-
- client->data = t = kmalloc(sizeof *t,GFP_KERNEL);
- if (!t)
- return -ENOMEM;
- memset(t,0,sizeof *t);
- do_tda7432_init(client);
- MOD_INC_USE_COUNT;
- strcpy(client->name,"TDA7432");
- printk(KERN_INFO "tda7432: init\n");
-
- i2c_attach_client(client);
- return 0;
-}
-
-static int tda7432_probe(struct i2c_adapter *adap)
-{
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, tda7432_attach);
- return 0;
-}
-
-static int tda7432_detach(struct i2c_client *client)
-{
- struct tda7432 *t = client->data;
-
- do_tda7432_init(client);
- i2c_detach_client(client);
-
- kfree(t);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int tda7432_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
-{
- struct tda7432 *t = client->data;
- d2printk("tda7432: In tda7432_command\n");
-#if 0
- __u16 *sarg = arg;
-#endif
-
- switch (cmd) {
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
-
- /* Query card - scale from TDA7432 settings to V4L settings */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
- dprintk("tda7432: VIDIOCGAUDIO\n");
-
- va->flags |= VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
-
- /* Master volume control
- * V4L volume is min 0, max 65535
- * TDA7432 Volume:
- * Min (-79dB) is 0x6f
- * Max (+20dB) is 0x07
- * (Mask out bit 7 of vol - it's for the loudness setting)
- */
-
- va->volume = ( 0x6f - (t->volume & 0x7F) ) * 630;
-
- /* Balance depends on L,R attenuation
- * V4L balance is 0 to 65535, middle is 32768
- * TDA7432 attenuation: min (0dB) is 0, max (-37.5dB) is 0x1f
- * to scale up to V4L numbers, mult by 1057
- * attenuation exists for lf, lr, rf, rr
- * we use only lf and rf (front channels)
- */
-
- if ( (t->lf) < (t->rf) )
- /* right is attenuated, balance shifted left */
- va->balance = (32768 - 1057*(t->rf));
- else
- /* left is attenuated, balance shifted right */
- va->balance = (32768 + 1057*(t->lf));
-
- /* Bass/treble */
- va->bass = 32768; /* brain hurts... set to middle for now */
- va->treble = 32768; /* brain hurts... set to middle for now */
-
- break; /* VIDIOCGAUDIO case */
- }
-
- /* Set card - scale from V4L settings to TDA7432 settings */
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
- dprintk("tda7432: VIDEOCSAUDIO\n");
-
- t->volume = 0x6f - ( (va->volume)/630 );
-
- if (loudness) /* Turn on the loudness bit */
- t->volume |= TDA7432_LD_ON;
-
- if (va->balance < 32768) {
- /* shifted to left, attenuate right */
- t->rr = (32768 - va->balance)/1057;
- t->rf = t->rr;
- }
- else {
- /* shifted to right, attenuate left */
- t->lf = (va->balance - 32768)/1057;
- t->lr = t->lf;
- }
-
- /* t->tone = 0xff; */ /* Brain hurts - no tone control for now... */
-
- tda7432_write(client,TDA7432_VL, t->volume);
- /* tda7432_write(client,TDA7432_TN, t->tone); */
- tda7432_write(client,TDA7432_LF, t->lf);
- tda7432_write(client,TDA7432_LR, t->lr);
- tda7432_write(client,TDA7432_RF, t->rf);
- tda7432_write(client,TDA7432_RR, t->rr);
-
- break;
-
- } /* end of VIDEOCSAUDIO case */
-
- default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
-
- /* nothing */
- d2printk("tda7432: Default\n");
-
- } /* end of (cmd) switch */
-
- return 0;
-}
-
-
-static struct i2c_driver driver = {
- "i2c tda7432 driver",
- I2C_DRIVERID_TDA7432,
- I2C_DF_NOTIFY,
- tda7432_probe,
- tda7432_detach,
- tda7432_command,
-};
-
-static struct i2c_client client_template =
-{
- "(unset)", /* name */
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int tda7432_init(void)
-#endif
-{
-
- if ( (loudness < 0) || (loudness > 15) )
- {
- printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n");
- return -EINVAL;
- }
-
-
- i2c_add_driver(&driver);
- return 0;
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/tda8425.c b/drivers/char/tda8425.c
deleted file mode 100644
index a1dec22eb..000000000
--- a/drivers/char/tda8425.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * for the TDA8425 chip (I don't know which cards have this)
- * WARNING: THIS DRIVER WILL LOAD WITHOUT COMPLAINTS EVEN IF A DIFFERENT
- * CHIP IS AT ADDRESS 0x82 (it relies on i2c to make sure that there is a
- * device acknowledging that address)
- *
- * Copyright (c) 1998 Greg Alexander <galexand@acm.org>
- * This code is placed under the terms of the GNU General Public License
- * Code liberally copied from msp3400.c, which is by Gerd Knorr
- *
- * All of this should work, though it would be nice to eventually support
- * balance (different left,right values). Also, the chip seems (?) to have
- * two stereo inputs, so if someone has this card, could they tell me if the
- * second one can be used for anything (i.e., does it have an external input
- * that you can't hear even if you set input to composite?)
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/videodev.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "bttv.h"
-#include "audiochip.h"
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {
- I2C_TDA8425 >> 1,
- I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-MODULE_PARM(debug,"i");
-static int debug = 0; /* insmod parameter */
-#define dprintk if (debug) printk
-
-
-struct tda8425 {
- int mode; /* set to AUDIO_{OFF,TUNER,RADIO,EXTERN} */
- int stereo;
- __u16 left,right;
- __u16 bass,treble;
-};
-
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
-
-#define TDA8425_VL 0x00 /* volume left */
-#define TDA8425_VR 0x01 /* volume right */
-#define TDA8425_BA 0x02 /* bass */
-#define TDA8425_TR 0x03 /* treble */
-#define TDA8425_S1 0x08 /* switch functions */
- /* values for those registers: */
-#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
-#define TDA8425_S1_ON 0xCE /* audio on (mute off) - "linear stereo" mode */
-
-
-/* ******************************** *
- * functions for talking to TDA8425 *
- * ******************************** */
-
-static int tda8425_write(struct i2c_client *client, int addr, int val)
-{
- unsigned char buffer[2];
-
- buffer[0] = addr;
- buffer[1] = val;
- if (2 != i2c_master_send(client,buffer,2)) {
- printk(KERN_WARNING "tda8425: I/O error, trying (write %d 0x%x)\n",
- addr, val);
- return -1;
- }
- return 0;
-}
-
-static void tda8425_set(struct i2c_client *client)
-{
- struct tda8425 *tda = client->data;
-
- /* mode is ignored today */
- dprintk(KERN_DEBUG "tda8425_set(%04x,%04x,%04x,%04x)\n",tda->left>>10,tda->right>>10,tda->bass>>12,tda->treble>>12);
- tda8425_write(client, TDA8425_VL, tda->left>>10 |0xC0);
- tda8425_write(client, TDA8425_VR, tda->right>>10 |0xC0);
- tda8425_write(client, TDA8425_BA, tda->bass>>12 |0xF0);
- tda8425_write(client, TDA8425_TR, tda->treble>>12|0xF0);
-}
-
-static void do_tda8425_init(struct i2c_client *client)
-{
- struct tda8425 *tda = client->data;
-
- tda->left=tda->right =61440; /* 0dB */
- tda->bass=tda->treble=24576; /* 0dB */
- tda->mode=AUDIO_OFF;
- tda->stereo=1;
- /* left=right=0x27<<10, bass=treble=0x07<<12 */
- tda8425_write(client, TDA8425_S1, TDA8425_S1_OFF); /* mute */
- tda8425_set(client);
-}
-
-static void tda8425_audio(struct i2c_client *client, int mode)
-{
- struct tda8425 *tda = client->data;
-
- /* valid for AUDIO_TUNER, RADIO, EXTERN, OFF */
- dprintk(KERN_DEBUG "tda8425_audio:%d (T,R,E,I,O)\n",mode);
- tda->mode=mode;
- tda8425_write(client, TDA8425_S1,
- (mode==AUDIO_OFF)?TDA8425_S1_OFF:TDA8425_S1_ON);
- /* this is the function we'll need to change if it turns out the
- * input-selecting capabilities should be used. */
-}
-
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tda8425_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- struct tda8425 *tda;
- struct i2c_client *client;
-
- client = kmalloc(sizeof *client,GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
-
- client->data = tda = kmalloc(sizeof *tda,GFP_KERNEL);
- if (!tda)
- return -ENOMEM;
- memset(tda,0,sizeof *tda);
- do_tda8425_init(client);
- MOD_INC_USE_COUNT;
- strcpy(client->name,"TDA8425");
- printk(KERN_INFO "tda8425: init\n");
-
- i2c_attach_client(client);
- return 0;
-}
-
-static int tda8425_probe(struct i2c_adapter *adap)
-{
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, tda8425_attach);
- return 0;
-}
-
-
-static int tda8425_detach(struct i2c_client *client)
-{
- struct tda8425 *tda = client->data;
-
- do_tda8425_init(client);
- i2c_detach_client(client);
-
- kfree(tda);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int tda8425_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
-{
- struct tda8425 *tda = client->data;
- __u16 *sarg = arg;
-
- switch (cmd) {
- case AUDC_SET_RADIO:
- tda8425_audio(client,AUDIO_RADIO);
- break;
- case AUDC_SET_INPUT:
- tda8425_audio(client,*sarg);
- break;
-
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- va->flags |= VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
- va->volume=MAX(tda->left,tda->right);
- va->balance=(32768*MIN(tda->left,tda->right))/
- (va->volume ? va->volume : 1);
- va->balance=(tda->left<tda->right)?
- (65535-va->balance) : va->balance;
- va->bass = tda->bass;
- va->treble = tda->treble;
- break;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
-
- tda->left = (MIN(65536 - va->balance,32768) *
- va->volume) / 32768;
- tda->right = (MIN(va->balance,32768) *
- va->volume) / 32768;
- tda->bass = va->bass;
- tda->treble = va->treble;
- tda8425_set(client);
- break;
- }
-
-#if 0
- /* --- old, obsolete interface --- */
- case AUDC_GET_VOLUME_LEFT:
- *sarg = tda->left;
- break;
- case AUDC_GET_VOLUME_RIGHT:
- *sarg = tda->right;
- break;
- case AUDC_SET_VOLUME_LEFT:
- tda->left = *sarg;
- tda8425_set(client);
- break;
- case AUDC_SET_VOLUME_RIGHT:
- tda->right = *sarg;
- tda8425_set(client);
- break;
-
- case AUDC_GET_BASS:
- *sarg = tda->bass;
- break;
- case AUDC_SET_BASS:
- tda->bass = *sarg;
- tda8425_set(client);
- break;
-
- case AUDC_GET_TREBLE:
- *sarg = tda->treble;
- break;
- case AUDC_SET_TREBLE:
- tda->treble = *sarg;
- tda8425_set(client);
- break;
-
- case AUDC_GET_STEREO:
- *sarg = tda->stereo?VIDEO_SOUND_STEREO:VIDEO_SOUND_MONO;
- break;
- case AUDC_SET_STEREO:
- tda->stereo=(*sarg==VIDEO_SOUND_MONO)?0:1;
- /* TODO: make this write to the TDA9850? */
- break;
-
-/* case AUDC_SWITCH_MUTE: someday, maybe -- not a lot of point to
- case AUDC_NEWCHANNEL: it and it would require preserving state
- case AUDC_GET_DC: huh?? (not used by bttv.c)
-*/
-#endif
- default:
- /* nothing */
- }
- return 0;
-}
-
-
-static struct i2c_driver driver = {
- "i2c tda8424 driver",
- I2C_DRIVERID_TDA8425,
- I2C_DF_NOTIFY,
- tda8425_probe,
- tda8425_detach,
- tda8425_command,
-};
-
-static struct i2c_client client_template =
-{
- "(unset)", /* name */
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int tda8425_init(void)
-#endif
-{
- i2c_add_driver(&driver);
- return 0;
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/tda985x.c b/drivers/char/tda985x.c
deleted file mode 100644
index 73fb9bd52..000000000
--- a/drivers/char/tda985x.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * For the TDA9850 and TDA9855 chips
- * (The TDA9855 is used on the Diamond DTV2000 and the TDA9850 is used
- * on STB cards. Other cards probably use these chips as well.)
- * This driver will not complain if used with any
- * other i2c device with the same address.
- *
- * Copyright (c) 1999 Gerd Knorr
- * TDA9850 code and TDA9855.c merger by Eric Sandeen (eric_sandeen@bigfoot.com)
- * This code is placed under the terms of the GNU General Public License
- * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
- * Which was based on tda8425.c by Greg Alexander (c) 1998
- *
- * OPTIONS:
- * debug - set to 1 if you'd like to see debug messages
- * - set to 2 if you'd like to be flooded with debug messages
- * chip - set to 9850 or 9855 to select your chip (default 9855)
- *
- * TODO:
- * Fix channel change bug - sound goes out when changeing channels, mute
- * and unmote to fix. - Is this still here?
- * Fine tune sound
- * Get rest of capabilities into video_audio struct...
- *
- * Revision 0.5 - cleaned up debugging messages, added debug level=2
- * Revision: 0.4 - check for correct chip= insmod value
- * also cleaned up comments a bit
- * Revision: 0.3 - took out extraneous tda985x_write in tda985x_command
- * Revision: 0.2 - added insmod option chip=
- * Revision: 0.1 - original version
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/videodev.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "bttv.h"
-#include "audiochip.h"
-
-MODULE_PARM(debug,"i");
-MODULE_PARM(chip,"i");
-MODULE_PARM_DESC(chip, "Type of chip to handle: 9850 or 9855");
-
-static int debug = 0; /* insmod parameter */
-static int chip = 9855; /* insmod parameter */
-
-/* Addresses to scan */
-#define I2C_TDA985x_L 0xb4
-#define I2C_TDA985x_H 0xb6
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {
- I2C_TDA985x_L >> 1,
- I2C_TDA985x_H >> 1,
- I2C_CLIENT_END
-};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-/* This is a superset of the TDA9850 and TDA9855 members */
-
-struct tda985x {
- int addr;
- int rvol, lvol;
- int bass, treble, sub;
- int c4, c5, c6, c7;
- int a1, a2, a3;
-};
-
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
-#define dprintk if (debug) printk
-#define d2printk if (debug == 2) printk
-
-/* The TDA9850 and TDA9855 are both made by Philips Semiconductor
- * http://www.semiconductors.philips.com
- * TDA9850: I2C-bus controlled BTSC stereo/SAP decoder
- * TDA9855: I2C-bus controlled BTSC stereo/SAP decoder and audio processor
- *
- * The TDA9850 has more or less a subset of the functions that the TDA9855
- * has. As a result, we can re-use many of these defines. Anything with
- * TDA9855 is specific to that chip, anything with TDA9850 is specific
- * to that chip, and anything with TDA985x is valid for either.
- *
- * To complicate things further, the TDA9850 uses labels C1 through C4
- * for subaddresses 0x04 through 0x07, while the TDA9855 uses
- * C1 through C3 for subadresses 0x05 through 0x07 - quite confusing.
- * To help keep things straight, I have renamed the various C[1,4] labels
- * to C[4,7] so that the numerical label matches the hex value of the
- * subaddress for both chips. At least the A[1,3] labels line up. :)
- */
-
- /* subaddresses for TDA9855 */
-#define TDA9855_VR 0x00 /* Volume, right */
-#define TDA9855_VL 0x01 /* Volume, left */
-#define TDA9855_BA 0x02 /* Bass */
-#define TDA9855_TR 0x03 /* Treble */
-#define TDA9855_SW 0x04 /* Subwoofer - not connected on DTV2000 */
-
- /* subaddresses for TDA9850 */
-#define TDA9850_C4 0x04 /* Control 1 for TDA9850 */
-
- /* subaddesses for both chips */
-#define TDA985x_C5 0x05 /* Control 2 for TDA9850, Control 1 for TDA9855 */
-#define TDA985x_C6 0x06 /* Control 3 for TDA9850, Control 2 for TDA9855 */
-#define TDA985x_C7 0x07 /* Control 4 for TDA9850, Control 3 for TDA9855 */
-#define TDA985x_A1 0x08 /* Alignment 1 for both chips */
-#define TDA985x_A2 0x09 /* Alignment 2 for both chips */
-#define TDA985x_A3 0x0a /* Alignment 3 for both chips */
-
- /* Masks for bits in TDA9855 subaddresses */
-/* 0x00 - VR in TDA9855 */
-/* 0x01 - VL in TDA9855 */
-/* lower 7 bits control gain from -71dB (0x28) to 16dB (0x7f)
- * in 1dB steps - mute is 0x27 */
-
-
-/* 0x02 - BA in TDA9855 */
-/* lower 5 bits control bass gain from -12dB (0x06) to 16.5dB (0x19)
- * in .5dB steps - 0 is 0x0E */
-
-
-/* 0x03 - TR in TDA9855 */
-/* 4 bits << 1 control treble gain from -12dB (0x3) to 12dB (0xb)
- * in 3dB steps - 0 is 0x7 */
-
- /* Masks for bits in both chips' subaddresses */
-/* 0x04 - SW in TDA9855, C4/Control 1 in TDA9850 */
-/* Unique to TDA9855: */
-/* 4 bits << 2 control subwoofer/surround gain from -14db (0x1) to 14db (0xf)
- * in 3dB steps - mute is 0x0 */
-
-/* Unique to TDA9850: */
-/* lower 4 bits control stereo noise threshold, over which stereo turns off
- * set to values of 0x00 through 0x0f for Ster1 through Ster16 */
-
-
-/* 0x05 - C5 - Control 1 in TDA9855 , Control 2 in TDA9850*/
-/* Unique to TDA9855: */
-#define TDA9855_MUTE 1<<7 /* GMU, Mute at outputs */
-#define TDA9855_AVL 1<<6 /* AVL, Automatic Volume Level */
-#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
-#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
- /* Bits 0 to 3 select various combinations
- * of line in and line out, only the
- * interesting ones are defined */
-#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
-#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
-
-/* Unique to TDA9850: */
-/* lower 4 bits contol SAP noise threshold, over which SAP turns off
- * set to values of 0x00 through 0x0f for SAP1 through SAP16 */
-
-
-/* 0x06 - C6 - Control 2 in TDA9855, Control 3 in TDA9850 */
-/* Common to TDA9855 and TDA9850: */
-#define TDA985x_SAP 3<<6 /* Selects SAP output, mute if not received */
-#define TDA985x_STEREO 1<<6 /* Selects Stereo ouput, mono if not received */
-#define TDA985x_MONO 0 /* Forces Mono output */
-#define TDA985x_LMU 1<<3 /* Mute (LOR/LOL for 9855, OUTL/OUTR for 9850) */
-
-/* Unique to TDA9855: */
-#define TDA9855_TZCM 1<<5 /* If set, don't mute till zero crossing */
-#define TDA9855_VZCM 1<<4 /* If set, don't change volume till zero crossing*/
-#define TDA9855_LINEAR 0 /* Linear Stereo */
-#define TDA9855_PSEUDO 1 /* Pseudo Stereo */
-#define TDA9855_SPAT_30 2 /* Spatial Stereo, 30% anti-phase crosstalk */
-#define TDA9855_SPAT_50 3 /* Spatial Stereo, 52% anti-phase crosstalk */
-#define TDA9855_E_MONO 7 /* Forced mono - mono select elseware, so useless*/
-
-
-/* 0x07 - C7 - Control 3 in TDA9855, Control 4 in TDA9850 */
-/* Common to both TDA9855 and TDA9850: */
-/* lower 4 bits control input gain from -3.5dB (0x0) to 4dB (0xF)
- * in .5dB steps - 0dB is 0x7 */
-
-
-/* 0x08, 0x09 - A1 and A2 (read/write) */
-/* Common to both TDA9855 and TDA9850: */
-/* lower 5 bites are wideband and spectral expander alignment
- * from 0x00 to 0x1f - nominal at 0x0f and 0x10 (read/write) */
-#define TDA985x_STP 1<<5 /* Stereo Pilot/detect (read-only) */
-#define TDA985x_SAPP 1<<6 /* SAP Pilot/detect (read-only) */
-#define TDA985x_STS 1<<7 /* Stereo trigger 1= <35mV 0= <30mV (write-only)*/
-
-
-/* 0x0a - A3 */
-/* Common to both TDA9855 and TDA9850: */
-/* lower 3 bits control timing current for alignment: -30% (0x0), -20% (0x1),
- * -10% (0x2), nominal (0x3), +10% (0x6), +20% (0x5), +30% (0x4) */
-#define TDA985x_ADJ 1<<7 /* Stereo adjust on/off (wideband and spectral */
-
-/* Unique to TDA9855: */
-/* 2 bits << 5 control AVL attack time: 420ohm (0x0), 730ohm (0x2),
- * 1200ohm (0x1), 2100ohm (0x3) */
-
-
-/* Begin code */
-
-static int tda985x_write(struct i2c_client *client, int subaddr, int val)
-{
- unsigned char buffer[2];
- d2printk("tda985x: In tda985x_write\n");
- dprintk("tda985x: Writing %d 0x%x\n", subaddr, val);
- buffer[0] = subaddr;
- buffer[1] = val;
- if (2 != i2c_master_send(client,buffer,2)) {
- printk(KERN_WARNING "tda985x: I/O error, trying (write %d 0x%x)\n",
- subaddr, val);
- return -1;
- }
- return 0;
-}
-
-static int tda985x_read(struct i2c_client *client)
-{
- unsigned char buffer;
- d2printk("tda985x: In tda985x_read\n");
- if (1 != i2c_master_recv(client,&buffer,1)) {
- printk(KERN_WARNING "tda985x: I/O error, trying (read)\n");
- return -1;
- }
- dprintk("tda985x: Read 0x%02x\n", buffer);
- return buffer;
-}
-
-static int tda985x_set(struct i2c_client *client)
-{
- struct tda985x *t = client->data;
- unsigned char buf[16];
- d2printk("tda985x: In tda985x_set\n");
-
- if (chip == 9855)
- {
- dprintk(KERN_INFO
- "tda985x: tda985x_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
- t->rvol,t->lvol,t->bass,t->treble,t->sub,
- t->c5,t->c6,t->c7,t->a1,t->a2,t->a3);
- buf[0] = TDA9855_VR;
- buf[1] = t->rvol;
- buf[2] = t->lvol;
- buf[3] = t->bass;
- buf[4] = t->treble;
- buf[5] = t->sub;
- buf[6] = t->c5;
- buf[7] = t->c6;
- buf[8] = t->c7;
- buf[9] = t->a1;
- buf[10] = t->a2;
- buf[11] = t->a3;
- if (12 != i2c_master_send(client,buf,12)) {
- printk(KERN_WARNING "tda985x: I/O error, trying tda985x_set\n");
- return -1;
- }
- }
-
- else if (chip == 9850)
- {
- dprintk(KERN_INFO
- "tda986x: tda985x_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
- t->c4,t->c5,t->c6,t->c7,t->a1,t->a2,t->a3);
- buf[0] = TDA9850_C4;
- buf[1] = t->c4;
- buf[2] = t->c5;
- buf[3] = t->c6;
- buf[4] = t->c7;
- buf[5] = t->a1;
- buf[6] = t->a2;
- buf[7] = t->a3;
- if (8 != i2c_master_send(client,buf,8)) {
- printk(KERN_WARNING "tda985x: I/O error, trying tda985x_set\n");
- return -1;
- }
- }
-
- return 0;
-}
-
-static void do_tda985x_init(struct i2c_client *client)
-{
- struct tda985x *t = client->data;
- d2printk("tda985x: In tda985x_init\n");
-
- if (chip == 9855)
- {
- printk("tda985x: Using tda9855 options\n");
- t->rvol = 0x6f; /* 0dB */
- t->lvol = 0x6f; /* 0dB */
- t->bass = 0x0e; /* 0dB */
- t->treble = (0x07 << 1); /* 0dB */
- t->sub = 0x8 << 2; /* 0dB */
- t->c5 = TDA9855_MUTE | TDA9855_AVL |
- TDA9855_LOUD | TDA9855_INT;
- /* Set Mute, AVL, Loudness off, Internal sound */
- t->c6 = TDA985x_STEREO | TDA9855_LINEAR |
- TDA9855_TZCM | TDA9855_VZCM;
- /* Stereo linear mode, also wait til zero crossings */
- t->c7 = 0x07; /* 0dB input gain */
- }
-
- else if (chip == 9850)
- {
- printk("tda985x: Using tda9850 options\n");
- t->c4 = 0x08; /* Set stereo noise thresh to nominal */
- t->c5 = 0x08; /* Set SAP noise threshold to nominal */
- t->c6 = TDA985x_STEREO; /* Select Stereo mode for decoder */
- t->c7 = 0x07; /* 0dB input gain */
- }
-
- /* The following is valid for both chip types */
- t->a1 = 0x10; /* Select nominal wideband expander */
- t->a2 = 0x10; /* Select nominal spectral expander and 30mV trigger */
- t->a3 = 0x3; /* Set: nominal timing current, 420ohm AVL attack */
-
- tda985x_set(client);
-}
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tda985x_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- struct tda985x *t;
- struct i2c_client *client;
- d2printk("tda985x: In tda985x_attach\n");
- client = kmalloc(sizeof *client,GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
-
- client->data = t = kmalloc(sizeof *t,GFP_KERNEL);
- if (!t)
- return -ENOMEM;
- memset(t,0,sizeof *t);
- do_tda985x_init(client);
- MOD_INC_USE_COUNT;
- strcpy(client->name,"TDA985x");
- printk(KERN_INFO "tda985x: init\n");
-
- i2c_attach_client(client);
- return 0;
-}
-
-static int tda985x_probe(struct i2c_adapter *adap)
-{
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, tda985x_attach);
- return 0;
-}
-
-static int tda985x_detach(struct i2c_client *client)
-{
- struct tda985x *t = client->data;
-
- do_tda985x_init(client);
- i2c_detach_client(client);
-
- kfree(t);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int tda985x_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
-{
- struct tda985x *t = client->data;
- d2printk("tda985x: In tda985x_command\n");
-#if 0
- __u16 *sarg = arg;
-#endif
-
- switch (cmd) {
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
- dprintk("tda985x: VIDIOCGAUDIO\n");
- if (chip == 9855)
- {
- int left,right;
-
- va->flags |= VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
-
- /* min is 0x27 max is 0x7f, vstep is 2e8 */
- left = (t->lvol-0x27)*0x2e8;
- right = (t->rvol-0x27)*0x2e8;
- va->volume=MAX(left,right);
- va->balance=(32768*MIN(left,right))/
- (va->volume ? va->volume : 1);
- va->balance=(left<right)?
- (65535-va->balance) : va->balance;
- va->bass = (t->bass-0x6)*0xccc; /* min 0x6 max 0x19 */
- va->treble = ((t->treble>>1)-0x3)*0x1c71;
- }
-
- /* Valid for both chips: */
- {
- va->mode = ((TDA985x_STP | TDA985x_SAPP) &
- tda985x_read(client)) >> 4;
- /* Add mono mode regardless of SAP and stereo */
- /* Allows forced mono */
- va->mode |= VIDEO_SOUND_MONO;
- }
-
- break; /* VIDIOCGAUDIO case */
- }
-
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
- dprintk("tda985x: VIDEOCSAUDIO\n");
- if (chip == 9855)
- {
- int left,right;
-
- left = (MIN(65536 - va->balance,32768) *
- va->volume) / 32768;
- right = (MIN(va->balance,32768) *
- va->volume) / 32768;
- t->lvol = left/0x2e8+0x27;
- t->rvol = right/0x2e8+0x27;
- t->bass = va->bass/0xccc+0x6;
- t->treble = (va->treble/0x1c71+0x3)<<1;
- tda985x_write(client,TDA9855_VL,t->lvol);
- tda985x_write(client,TDA9855_VR,t->rvol);
- tda985x_write(client,TDA9855_BA, t->bass);
- tda985x_write(client,TDA9855_TR,t->treble);
- }
-
- /* The following is valid for both chips */
-
- switch (va->mode) {
- case VIDEO_SOUND_MONO:
- dprintk("tda985x: VIDEO_SOUND_MONO\n");
- t->c6= TDA985x_MONO | (t->c6 & 0x3f);
- tda985x_write(client,TDA985x_C6,t->c6);
- break;
- case VIDEO_SOUND_STEREO:
- dprintk("tda985x: VIDEO_SOUND_STEREO\n");
- t->c6= TDA985x_STEREO | (t->c6 & 0x3f);
- tda985x_write(client,TDA985x_C6,t->c6);
- break;
- case VIDEO_SOUND_LANG1:
- dprintk("tda985x: VIDEO_SOUND_LANG1\n");
- t->c6= TDA985x_SAP | (t->c6 & 0x3f);
- tda985x_write(client,TDA985x_C6,t->c6);
- break;
- } /* End of (va->mode) switch */
-
- break;
-
- } /* end of VIDEOCSAUDIO case */
-
- default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
-
- /* nothing */
- d2printk("tda985x: Default\n");
-
- } /* end of (cmd) switch */
-
- return 0;
-}
-
-
-static struct i2c_driver driver = {
- "i2c tda985x driver",
- I2C_DRIVERID_TDA9855, /* Get new one for TDA985x? */
- I2C_DF_NOTIFY,
- tda985x_probe,
- tda985x_detach,
- tda985x_command,
-};
-
-static struct i2c_client client_template =
-{
- "(unset)", /* name */
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int tda985x_init(void)
-#endif
-{
- if ( (chip != 9850) && (chip != 9855) )
- {
- printk(KERN_ERR "tda985x: chip parameter must be 9850 or 9855\n");
- return -EINVAL;
- }
- i2c_add_driver(&driver);
- return 0;
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/tda9875.c b/drivers/char/tda9875.c
deleted file mode 100644
index 9f6ecd332..000000000
--- a/drivers/char/tda9875.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * For the TDA9875 chip
- * (The TDA9875 is used on the Diamond DTV2000 french version
- * Other cards probably use these chips as well.)
- * This driver will not complain if used with any
- * other i2c device with the same address.
- *
- * Copyright (c) 2000 Guillaume Delvit based on Gerd Knorr source and
- * Eric Sandeen
- * This code is placed under the terms of the GNU General Public License
- * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
- * Which was based on tda8425.c by Greg Alexander (c) 1998
- *
- * OPTIONS:
- * debug - set to 1 if you'd like to see debug messages
- *
- * Revision: 0.1 - original version
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/videodev.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "bttv.h"
-#include "audiochip.h"
-
-/* This driver ID is brand new, so define it if it's not in i2c-id.h yet */
-#ifndef I2C_DRIVERID_TDA9875
- #define I2C_DRIVERID_TDA9875 28
-#endif
-
-
-MODULE_PARM(debug,"i");
-
-static int debug = 0; /* insmod parameter */
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {
- I2C_TDA9875 >> 1,
- I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-/* This is a superset of the TDA9875 */
-struct tda9875 {
- int mode;
- int rvol, lvol;
- int bass, treble;
-};
-
-
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
-#define dprintk if (debug) printk
-
-/* The TDA9875 is made by Philips Semiconductor
- * http://www.semiconductors.philips.com
- * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
- *
- */
-
- /* subaddresses for TDA9875 */
-#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/
-#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */
-#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/
-#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/
-
-#define TDA9875_CH1V 0x0c /*Chanel 1 volume (mute)*/
-#define TDA9875_CH2V 0x0d /*Chanel 2 volume (mute)*/
-#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/
-#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/
-
-#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/
-#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/
-#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/
-#define TDA9875_MVL 0x1a /* Main volume gauche */
-#define TDA9875_MVR 0x1b /* Main volume droite */
-#define TDA9875_MBA 0x1d /* Main Basse */
-#define TDA9875_MTR 0x1e /* Main treble */
-#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/
-#define TDA9875_AVL 0x20 /* Auxilary volume gauche */
-#define TDA9875_AVR 0x21 /* Auxilary volume droite */
-#define TDA9875_ABA 0x22 /* Auxilary Basse */
-#define TDA9875_ATR 0x23 /* Auxilary treble */
-
-#define TDA9875_MSR 0x02 /* Monitor select register */
-#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */
-#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */
-#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */
-#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */
-#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */
-#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */
-#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/
-#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/
-#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/
-
-/* values */
-#define TDA9875_MUTE_ON 0xff /* general mute */
-#define TDA9875_MUTE_OFF 0xcc /* general no mute */
-
-
-
-/* Begin code */
-
-static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char val)
-{
- unsigned char buffer[2];
- dprintk("In tda9875_write\n");
- dprintk("Writing %d 0x%x\n", subaddr, val);
- buffer[0] = subaddr;
- buffer[1] = val;
- if (2 != i2c_master_send(client,buffer,2)) {
- printk(KERN_WARNING "tda9875: I/O error, trying (write %d 0x%x)\n",
- subaddr, val);
- return -1;
- }
- return 0;
-}
-
-#if 0
-static int tda9875_read(struct i2c_client *client)
-{
- unsigned char buffer;
- dprintk("In tda9875_read\n");
- if (1 != i2c_master_recv(client,&buffer,1)) {
- printk(KERN_WARNING "tda9875: I/O error, trying (read)\n");
- return -1;
- }
- dprintk("Read 0x%02x\n", buffer);
- return buffer;
-}
-#endif
-
-static void tda9875_set(struct i2c_client *client)
-{
- struct tda9875 *tda = client->data;
- unsigned char a;
-
- dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n",tda->lvol,tda->rvol,tda->bass,tda->treble);
-
-
- a = tda->lvol & 0xff;
- tda9875_write(client, TDA9875_MVL, a);
- a =tda->rvol & 0xff;
- tda9875_write(client, TDA9875_MVR, a);
- a =tda->bass & 0xff;
- tda9875_write(client, TDA9875_MBA, a);
- a =tda->treble & 0xff;
- tda9875_write(client, TDA9875_MTR, a);
-}
-
-static void do_tda9875_init(struct i2c_client *client)
-{
- struct tda9875 *t = client->data;
- dprintk("In tda9875_init\n");
- tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/
- tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/
- tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/
- tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/
- tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/
- tda9875_write(client, TDA9875_C2MSB, 0x00 ); /*Car2(NICAM) MSB XMHz*/
- tda9875_write(client, TDA9875_C2MIB, 0x00 ); /*Car2(NICAM) MIB XMHz*/
- tda9875_write(client, TDA9875_C2LSB, 0x00 ); /*Car2(NICAM) LSB XMHz*/
- tda9875_write(client, TDA9875_DCR, 0x00 ); /*Demod config 0x00*/
- tda9875_write(client, TDA9875_DEEM, 0x44 ); /*DE-Emph 0b0100 0100*/
- tda9875_write(client, TDA9875_FMAT, 0x00 ); /*FM Matrix reg 0x00*/
- tda9875_write(client, TDA9875_SC1, 0x00 ); /* SCART 1 (SC1)*/
- tda9875_write(client, TDA9875_SC2, 0x01 ); /* SCART 2 (sc2)*/
-
- tda9875_write(client, TDA9875_CH1V, 0x10 ); /* Chanel volume 1 mute*/
- tda9875_write(client, TDA9875_CH2V, 0x10 ); /* Chanel volume 2 mute */
- tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
- tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
- tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
- tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
- tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
- tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
- tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
- tda9875_write(client, TDA9875_MBA, 0x00 ); /* Main Bass Main 0dB*/
- tda9875_write(client, TDA9875_MTR, 0x00 ); /* Main Treble Main 0dB*/
- tda9875_write(client, TDA9875_ACS, 0x44 ); /* Aux chan select (dac)*/
- tda9875_write(client, TDA9875_AVL, 0x00 ); /* Vol Aux left 0dB*/
- tda9875_write(client, TDA9875_AVR, 0x00 ); /* Vol Aux right 0dB*/
- tda9875_write(client, TDA9875_ABA, 0x00 ); /* Aux Bass Main 0dB*/
- tda9875_write(client, TDA9875_ATR, 0x00 ); /* Aux Aigus Main 0dB*/
-
- tda9875_write(client, TDA9875_MUT, 0xcc ); /* General mute */
-
- t->mode=AUDIO_UNMUTE;
- t->lvol=t->rvol =0; /* 0dB */
- t->bass=0; /* 0dB */
- t->treble=0; /* 0dB */
- tda9875_set(client);
-
-}
-
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tda9875_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- struct tda9875 *t;
- struct i2c_client *client;
- dprintk("In tda9875_attach\n");
- client = kmalloc(sizeof *client,GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
-
- client->data = t = kmalloc(sizeof *t,GFP_KERNEL);
- if (!t)
- return -ENOMEM;
- memset(t,0,sizeof *t);
- do_tda9875_init(client);
- MOD_INC_USE_COUNT;
- strcpy(client->name,"TDA9875");
- printk(KERN_INFO "tda9875: init\n");
-
- i2c_attach_client(client);
- return 0;
-}
-
-static int tda9875_probe(struct i2c_adapter *adap)
-{
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, tda9875_attach);
- return 0;
-}
-
-static int tda9875_detach(struct i2c_client *client)
-{
- struct tda9875 *t = client->data;
-
- do_tda9875_init(client);
- i2c_detach_client(client);
-
- kfree(t);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int tda9875_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
-{
- struct tda9875 *t = client->data;
-
- dprintk("In tda9875_command...\n");
-
- switch (cmd) {
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
- int left,right;
-
- dprintk("VIDIOCGAUDIO\n");
-
- va->flags |= VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
-
- /* min is -84 max is 24 */
- left = (t->lvol+84)*606;
- right = (t->rvol+84)*606;
- va->volume=MAX(left,right);
- va->balance=(32768*MIN(left,right))/
- (va->volume ? va->volume : 1);
- va->balance=(left<right)?
- (65535-va->balance) : va->balance;
- va->bass = (t->bass+12)*2427; /* min -12 max +15 */
- va->treble = (t->treble+12)*2730;/* min -12 max +12 */
-
- va->mode |= VIDEO_SOUND_MONO;
-
-
- break; /* VIDIOCGAUDIO case */
- }
-
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
- int left,right;
-
- dprintk("VIDEOCSAUDIO...\n");
- left = (MIN(65536 - va->balance,32768) *
- va->volume) / 32768;
- right = (MIN(va->balance,32768) *
- va->volume) / 32768;
- t->lvol = ((left/606)-84) & 0xff;
- if (t->lvol > 24)
- t->lvol = 24;
- if (t->lvol < -84)
- t->lvol = -84 & 0xff;
-
- t->rvol = ((right/606)-84) & 0xff;
- if (t->rvol > 24)
- t->rvol = 24;
- if (t->rvol < -84)
- t->rvol = -84 & 0xff;
-
- t->bass = ((va->bass/2400)-12) & 0xff;
- if (t->bass > 15)
- t->bass = 15;
- if (t->bass < -12)
- t->bass = -12 & 0xff;
-
- t->treble = ((va->treble/2700)-12) & 0xff;
- if (t->treble > 12)
- t->treble = 12;
- if (t->treble < -12)
- t->treble = -12 & 0xff;
-
-
-
-//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
-
-
- tda9875_set(client);
-
- break;
-
- } /* end of VIDEOCSAUDIO case */
-
- default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
-
- /* nothing */
- dprintk("Default\n");
-
- } /* end of (cmd) switch */
-
- return 0;
-}
-
-
-static struct i2c_driver driver = {
- "i2c tda9875 driver",
- I2C_DRIVERID_TDA9875, /* Get new one for TDA9875 */
- I2C_DF_NOTIFY,
- tda9875_probe,
- tda9875_detach,
- tda9875_command,
-};
-
-static struct i2c_client client_template =
-{
- "(unset)", /* name */
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int tda9875_init(void)
-#endif
-{
- i2c_add_driver(&driver);
- return 0;
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/char/tea6300.c b/drivers/char/tea6300.c
deleted file mode 100644
index f5949c94f..000000000
--- a/drivers/char/tea6300.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * for the TEA6300 chip (only found on Gateway STB TV/FM cards tho the best
- * of my knowledge)
- * WARNING: THIS DRIVER WILL LOAD WITHOUT COMPLAINTS EVEN IF THE WRONG
- * CHIP (i.e., an MSP3400) IS ON I2C ADDRESS 0x80 (it relies on i2c to
- * make sure that there is a device acknowledging that address). This
- * is a potential problem because the MSP3400 is very popular and does
- * use this address! You have been warned!
- *
- * Copyright (c) 1998 Greg Alexander <galexand@acm.org>
- * This code is placed under the terms of the GNU General Public License
- * Code liberally copied from msp3400.c, which is by Gerd Knorr
- *
- * All of this should work, though it would be nice to eventually support
- * balance (different left,right values) and, if someone ever finds a card
- * with the support (or if you're careful with a soldering iron), fade
- * (front/back).
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/videodev.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "bttv.h"
-#include "audiochip.h"
-
-
-/* Addresses to scan */
-#define I2C_TEA6300 0x80
-static unsigned short normal_i2c[] = {
- I2C_TEA6300 >> 1,
- I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-
-MODULE_PARM(debug,"i");
-static int debug = 0; /* insmod parameter */
-
-#define dprintk if (debug) printk
-
-
-struct tea6300 {
- int mode; /* set to AUDIO_{OFF,TUNER,RADIO,EXTERN} */
- int stereo;
- __u16 left,right;
- __u16 bass,treble;
-};
-
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
-#define TEA6300_VL 0x00 /* volume left */
-#define TEA6300_VR 0x01 /* volume right */
-#define TEA6300_BA 0x02 /* bass */
-#define TEA6300_TR 0x03 /* treble */
-#define TEA6300_FA 0x04 /* fader control */
-#define TEA6300_S 0x05 /* switch register */
- /* values for those registers: */
-#define TEA6300_S_SA 0x01 /* stereo A input */
-#define TEA6300_S_SB 0x02 /* stereo B */
-#define TEA6300_S_SC 0x04 /* stereo C */
-#define TEA6300_S_GMU 0x80 /* general mute */
-
-
-/* ******************************** *
- * functions for talking to TEA6300 *
- * ******************************** */
-
-static int tea6300_write(struct i2c_client *client, int addr, int val)
-{
- unsigned char buffer[2];
-
- buffer[0] = addr;
- buffer[1] = val;
- if (2 != i2c_master_send(client,buffer,2)) {
- printk(KERN_WARNING "tea6300: I/O error, trying (write %d 0x%x)\n",
- addr, val);
- return -1;
- }
- return 0;
-}
-
-static void tea6300_set(struct i2c_client *client)
-{
- struct tea6300 *tea = client->data;
-
- /* mode is ignored today */
- dprintk(KERN_DEBUG "tea6300_set(%04x,%04x,%04x,%04x)\n",tea->left>>10,tea->right>>10,tea->bass>>12,tea->treble>>12);
- tea6300_write(client, TEA6300_VL, tea->left>>10 );
- tea6300_write(client, TEA6300_VR, tea->right>>10 );
- tea6300_write(client, TEA6300_BA, tea->bass>>12 );
- tea6300_write(client, TEA6300_TR, tea->treble>>12);
-}
-
-static void do_tea6300_init(struct i2c_client *client)
-{
- struct tea6300 *tea = client->data;
-
- tea->left=tea->right =49152; /* -10dB (loud enough, but not beyond
- normal line levels - so as to avoid
- clipping */
- tea->bass=tea->treble=28672; /* 0dB */
- tea->mode=AUDIO_OFF;
- tea->stereo=1;
- /* left=right=0x27<<10, bass=treble=0x07<<12 */
- tea6300_write(client, TEA6300_FA, 0x3f ); /* fader off */
- tea6300_write(client, TEA6300_S , TEA6300_S_GMU); /* mute */
- tea6300_set(client);
-}
-
-static void tea6300_audio(struct i2c_client *client, int mode)
-{
- struct tea6300 *tea = client->data;
-
- /* valid for AUDIO_TUNER, RADIO, EXTERN, OFF */
- dprintk(KERN_DEBUG "tea6300_audio:%d (T,R,E,I,O)\n",mode);
- tea->mode=mode;
- if (mode==AUDIO_OFF) { /* just mute it */
- tea6300_write(client, TEA6300_S, TEA6300_S_GMU);
- return;
- }
- switch(mode) {
- case AUDIO_TUNER:
- tea6300_write(client, TEA6300_S, TEA6300_S_SA);
- break;
- case AUDIO_RADIO:
- tea6300_write(client, TEA6300_S, TEA6300_S_SB);
- break;
- case AUDIO_EXTERN:
- tea6300_write(client, TEA6300_S, TEA6300_S_SC);
- break;
- }
-}
-
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tea6300_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- struct tea6300 *tea;
- struct i2c_client *client;
-
- client = kmalloc(sizeof *client,GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
-
- client->data = tea = kmalloc(sizeof *tea,GFP_KERNEL);
- if (!tea)
- return -ENOMEM;
- memset(tea,0,sizeof *tea);
- do_tea6300_init(client);
-
- MOD_INC_USE_COUNT;
- strcpy(client->name,"TEA6300T");
- printk(KERN_INFO "tea6300: initialized\n");
-
- i2c_attach_client(client);
- return 0;
-}
-
-static int tea6300_probe(struct i2c_adapter *adap)
-{
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, tea6300_attach);
- return 0;
-}
-
-static int tea6300_detach(struct i2c_client *client)
-{
- struct tea6300 *tea = client->data;
-
- do_tea6300_init(client);
- i2c_detach_client(client);
-
- kfree(tea);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int
-tea6300_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- struct tea6300 *tea = client->data;
- __u16 *sarg = arg;
-
- switch (cmd) {
- case AUDC_SET_RADIO:
- tea6300_audio(client,AUDIO_RADIO);
- break;
- case AUDC_SET_INPUT:
- tea6300_audio(client,*sarg);
- break;
-
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- va->flags |= VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
- va->volume=MAX(tea->left,tea->right);
- va->balance=(32768*MIN(tea->left,tea->right))/
- (va->volume ? va->volume : 1);
- va->balance=(tea->left<tea->right)?
- (65535-va->balance) : va->balance;
- va->bass = tea->bass;
- va->treble = tea->treble;
- break;
- }
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
-
- tea->left = (MIN(65536 - va->balance,32768) *
- va->volume) / 32768;
- tea->right = (MIN(va->balance,32768) *
- va->volume) / 32768;
- tea->bass = va->bass;
- tea->treble = va->treble;
- tea6300_set(client);
- break;
- }
-#if 0
- /* --- old, obsolete interface --- */
- case AUDC_GET_VOLUME_LEFT:
- *sarg = tea->left;
- break;
- case AUDC_GET_VOLUME_RIGHT:
- *sarg = tea->right;
- break;
- case AUDC_SET_VOLUME_LEFT:
- tea->left = *sarg;
- tea6300_set(client);
- break;
- case AUDC_SET_VOLUME_RIGHT:
- tea->right = *sarg;
- tea6300_set(client);
- break;
-
- case AUDC_GET_BASS:
- *sarg = tea->bass;
- break;
- case AUDC_SET_BASS:
- tea->bass = *sarg;
- tea6300_set(client);
- break;
-
- case AUDC_GET_TREBLE:
- *sarg = tea->treble;
- break;
- case AUDC_SET_TREBLE:
- tea->treble = *sarg;
- tea6300_set(client);
- break;
-
- case AUDC_GET_STEREO:
- *sarg = tea->stereo?VIDEO_SOUND_STEREO:VIDEO_SOUND_MONO;
- break;
- case AUDC_SET_STEREO:
- tea->stereo=(*sarg==VIDEO_SOUND_MONO)?0:1;
- /* TODO: make this write to the TDA9850? */
- break;
-
-/* case AUDC_SWITCH_MUTE: someday, maybe -- not a lot of point to
- case AUDC_NEWCHANNEL: it and it would require preserving state
- case AUDC_GET_DC: huh?? (not used by bttv.c)
-*/
-#endif
- default:
- /* nothing */
- }
- return 0;
-}
-
-static struct i2c_driver driver = {
- "i2c tea6300 driver",
- I2C_DRIVERID_TEA6300,
- I2C_DF_NOTIFY,
- tea6300_probe,
- tea6300_detach,
- tea6300_command,
-};
-
-static struct i2c_client client_template =
-{
- "(unset)", /* name */
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int tea6300_init(void)
-#endif
-{
- i2c_add_driver(&driver);
- return 0;
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/tea6420.c b/drivers/char/tea6420.c
deleted file mode 100644
index 231ed9e4e..000000000
--- a/drivers/char/tea6420.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * for the TEA6420 chip (only found on 3DFX (STB) TV/FM cards to the best
- * of my knowledge)
- * Copyright (C) 2000 Dave Stuart <justdave@ynn.com>
- * This code is placed under the terms of the GNU General Public License
- * Code liberally copied from tea6300 by . . .
- *
- * Copyright (c) 1998 Greg Alexander <galexand@acm.org>
- * This code is placed under the terms of the GNU General Public License
- * Code liberally copied from msp3400.c, which is by Gerd Knorr
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/videodev.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "bttv.h"
-#include "audiochip.h"
-
-
-/* Addresses to scan */
-#define I2C_TEA6420 0x98
-static unsigned short normal_i2c[] = {
- I2C_TEA6420 >> 1,
- I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-
-MODULE_PARM(debug,"i");
-static int debug = 0; /* insmod parameter */
-
-#define dprintk if (debug) printk
-
-
-struct tea6420 {
- int mode; /* set to AUDIO_{OFF,TUNER,RADIO,EXTERN} */
- int stereo;
-};
-
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
-#define TEA6420_S_SA 0x00 /* stereo A input */
-#define TEA6420_S_SB 0x01 /* stereo B */
-#define TEA6420_S_SC 0x02 /* stereo C */
-#define TEA6420_S_SD 0x03 /* stereo D */
-#define TEA6420_S_SE 0x04 /* stereo E */
-#define TEA6420_S_GMU 0x05 /* general mute */
-
-
-/* ******************************** *
- * functions for talking to TEA6420 *
- * ******************************** */
-
-static int tea6420_write(struct i2c_client *client, int val)
-{
- unsigned char buffer[2];
- int result;
-
-/* buffer[0] = addr; */
- buffer[0] = val;
- result = i2c_master_send(client,buffer,1);
- if (1 != result) {
- printk(KERN_WARNING "tea6420: I/O error, trying (write
-0x%x) result = %d\n", val, result);
- return -1;
- }
- return 0;
-}
-
-
-static void do_tea6420_init(struct i2c_client *client)
-{
- struct tea6420 *tea = client->data;
-
- tea->mode=AUDIO_OFF;
- tea->stereo=1;
- tea6420_write(client, TEA6420_S_GMU); /* mute */
-}
-
-static void tea6420_audio(struct i2c_client *client, int mode)
-{
- struct tea6420 *tea = client->data;
-
- /* valid for AUDIO_TUNER, RADIO, EXTERN, OFF */
- dprintk(KERN_DEBUG "tea6420_audio:%d (T,R,E,I,O)\n",mode);
- tea->mode=mode;
- if (mode==AUDIO_OFF) { /* just mute it */
- tea6420_write(client, TEA6420_S_GMU);
- return;
- }
- switch(mode) {
- case AUDIO_TUNER:
- tea6420_write(client, TEA6420_S_SA);
- break;
- case AUDIO_RADIO:
- tea6420_write(client, TEA6420_S_SB);
- break;
- case AUDIO_EXTERN:
- tea6420_write(client, TEA6420_S_SC);
- break;
- }
-}
-
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tea6420_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- struct tea6420 *tea;
- struct i2c_client *client;
-
- client = kmalloc(sizeof *client,GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
-
- client->data = tea = kmalloc(sizeof *tea,GFP_KERNEL);
- if (!tea)
- return -ENOMEM;
- memset(tea,0,sizeof *tea);
- do_tea6420_init(client);
-
- MOD_INC_USE_COUNT;
- strcpy(client->name,"TEA6420");
- printk(KERN_INFO "tea6420: initialized\n");
-
- i2c_attach_client(client);
- return 0;
-}
-
-static int tea6420_probe(struct i2c_adapter *adap)
-{
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, tea6420_attach);
- return 0;
-}
-
-static int tea6420_detach(struct i2c_client *client)
-{
- struct tea6420 *tea = client->data;
-
- do_tea6420_init(client);
- i2c_detach_client(client);
-
- kfree(tea);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int
-tea6420_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- __u16 *sarg = arg;
-
- switch (cmd) {
- case AUDC_SET_RADIO:
- tea6420_audio(client,AUDIO_RADIO);
- break;
- case AUDC_SET_INPUT:
- tea6420_audio(client,*sarg);
- break;
-
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- va->flags |= VIDEO_AUDIO_VOLUME |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
-/* va->volume=MAX(tea->left,tea->right);
- va->balance=(32768*MIN(tea->left,tea->right))/
- (va->volume ? va->volume : 1);
- va->balance=(tea->left<tea->right)?
- (65535-va->balance) : va->balance;
- va->bass = tea->bass;
- va->treble = tea->treble;
-*/ break;
- }
- case VIDIOCSAUDIO:
- {
-
-/* tea->left = (MIN(65536 - va->balance,32768) *
- va->volume) / 32768;
- tea->right = (MIN(va->balance,32768) *
- va->volume) / 32768;
- tea->bass = va->bass;
- tea->treble = va->treble;
- tea6420_set(client);
-*/ break;
- }
-
-default:
- /* nothing */
- }
- return 0;
-}
-
-static struct i2c_driver driver = {
- "i2c tea6420 driver",
- I2C_DRIVERID_TEA6420,
- I2C_DF_NOTIFY,
- tea6420_probe,
- tea6420_detach,
- tea6420_command,
-};
-
-static struct i2c_client client_template =
-{
- "(unset)", /* name */
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int tea6420_init(void)
-#endif
-{
- i2c_add_driver(&driver);
- return 0;
-}
-
-#ifdef MODULE
-void cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 0d6e6f3fa..17fce4ddf 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1839,9 +1839,12 @@ void do_SAK( struct tty_struct *tty)
read_lock(&tasklist_lock);
for_each_task(p) {
if ((p->tty == tty) ||
- ((session > 0) && (p->session == session)))
+ ((session > 0) && (p->session == session))) {
send_sig(SIGKILL, p, 1);
- else if (p->files) {
+ continue;
+ }
+ task_lock(p);
+ if (p->files) {
read_lock(&p->files->file_lock);
/* FIXME: p->files could change */
for (i=0; i < p->files->max_fds; i++) {
@@ -1854,6 +1857,7 @@ void do_SAK( struct tty_struct *tty)
}
read_unlock(&p->files->file_lock);
}
+ task_unlock(p);
}
read_unlock(&tasklist_lock);
#endif
diff --git a/drivers/char/tuner-3036.c b/drivers/char/tuner-3036.c
deleted file mode 100644
index 807ae339b..000000000
--- a/drivers/char/tuner-3036.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Driver for Philips SAB3036 "CITAC" tuner control chip.
- *
- * Author: Phil Blundell <philb@gnu.org>
- *
- * The SAB3036 is just about different enough from the chips that
- * tuner.c copes with to make it not worth the effort to crowbar
- * the support into that file. So instead we have a separate driver.
- *
- * 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 of the License, or (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/version.h>
-#include <linux/init.h>
-
-#include <linux/i2c.h>
-#include <linux/videodev.h>
-
-#include "tuner.h"
-
-static int debug; /* insmod parameter */
-static int this_adap;
-
-static struct i2c_client client_template;
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {0x60, 0x61, I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-/* ---------------------------------------------------------------------- */
-
-static unsigned char
-tuner_getstatus (struct i2c_client *c)
-{
- unsigned char byte;
- if (i2c_master_recv(c, &byte, 1) != 1)
- printk(KERN_ERR "tuner-3036: I/O error.\n");
- return byte;
-}
-
-#define TUNER_FL 0x80
-
-static int
-tuner_islocked (struct i2c_client *c)
-{
- return (tuner_getstatus(c) & TUNER_FL);
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void
-set_tv_freq(struct i2c_client *c, int freq)
-{
- u16 div = ((freq * 20) / 16);
- unsigned long give_up = jiffies + HZ;
- unsigned char buffer[2];
-
- if (debug)
- printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div);
-
- /* Select high tuning current */
- buffer[0] = 0x29;
- buffer[1] = 0x3e;
-
- if (i2c_master_send(c, buffer, 2) != 2)
- printk("tuner: i2c i/o error 1\n");
-
- buffer[0] = 0x80 | ((div>>8) & 0x7f);
- buffer[1] = div & 0xff;
-
- if (i2c_master_send(c, buffer, 2) != 2)
- printk("tuner: i2c i/o error 2\n");
-
- while (!tuner_islocked(c) && time_before(jiffies, give_up))
- schedule();
-
- if (!tuner_islocked(c))
- printk(KERN_WARNING "tuner: failed to achieve PLL lock\n");
-
- /* Select low tuning current and engage AFC */
- buffer[0] = 0x29;
- buffer[1] = 0xb2;
-
- if (i2c_master_send(c, buffer, 2) != 2)
- printk("tuner: i2c i/o error 3\n");
-
- if (debug)
- printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c));
-}
-
-/* ---------------------------------------------------------------------- */
-
-static int
-tuner_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 };
-
- struct i2c_client *client;
-
- if (this_adap > 0)
- return -1;
- this_adap++;
-
- client_template.adapter = adap;
- client_template.addr = addr;
-
- client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == NULL)
- return -ENOMEM;
- memcpy(client, &client_template, sizeof(struct i2c_client));
-
- printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client));
-
- i2c_attach_client(client);
- MOD_INC_USE_COUNT;
-
- if (i2c_master_send(client, buffer, 2) != 2)
- printk("tuner: i2c i/o error 1\n");
- if (i2c_master_send(client, buffer+2, 2) != 2)
- printk("tuner: i2c i/o error 2\n");
- if (i2c_master_send(client, buffer+4, 2) != 2)
- printk("tuner: i2c i/o error 3\n");
- return 0;
-}
-
-static int
-tuner_detach(struct i2c_client *c)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int
-tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- int *iarg = (int*)arg;
-
- switch (cmd)
- {
- case TUNER_SET_TVFREQ:
- set_tv_freq(client, *iarg);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int
-tuner_probe(struct i2c_adapter *adap)
-{
- this_adap = 0;
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_LP))
- return i2c_probe(adap, &addr_data, tuner_attach);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_driver
-i2c_driver_tuner =
-{
- "sab3036", /* name */
- I2C_DRIVERID_SAB3036, /* ID */
- I2C_DF_NOTIFY,
- tuner_probe,
- tuner_detach,
- tuner_command
-};
-
-static struct i2c_client client_template =
-{
- "SAB3036", /* name */
- -1,
- 0,
- 0,
- NULL,
- &i2c_driver_tuner
-};
-
-EXPORT_NO_SYMBOLS;
-
-int __init
-tuner3036_init(void)
-{
- i2c_add_driver(&i2c_driver_tuner);
- return 0;
-}
-
-void __exit
-tuner3036_exit(void)
-{
- i2c_del_driver(&i2c_driver_tuner);
-}
-
-MODULE_DESCRIPTION("SAB3036 tuner driver");
-MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
-MODULE_PARM(debug,"i");
-MODULE_PARM_DESC(debug,"Enable debugging output");
-
-module_init(tuner3036_init);
-module_exit(tuner3036_exit);
diff --git a/drivers/char/tuner.c b/drivers/char/tuner.c
deleted file mode 100644
index dfbf0f6af..000000000
--- a/drivers/char/tuner.c
+++ /dev/null
@@ -1,451 +0,0 @@
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/poll.h>
-#include <linux/i2c.h>
-#include <linux/types.h>
-#include <linux/videodev.h>
-#include <linux/init.h>
-
-#include "tuner.h"
-#include "audiochip.h"
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {0x60,0x6f,I2C_CLIENT_END};
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- normal_i2c, normal_i2c_range,
- probe, probe_range,
- ignore, ignore_range,
- force
-};
-
-static int debug = 0; /* insmod parameter */
-static int type = -1; /* insmod parameter */
-
-static int addr = 0;
-static int this_adap;
-
-#define dprintk if (debug) printk
-
-MODULE_PARM(debug,"i");
-MODULE_PARM(type,"i");
-MODULE_PARM(addr,"i");
-
-struct tuner
-{
- int type; /* chip type */
- int freq; /* keep track of the current settings */
- int std;
-
- int radio;
- int mode; /* PAL(0)/SECAM(1) mode (PHILIPS_SECAM only) */
-};
-
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
-/* ---------------------------------------------------------------------- */
-
-struct tunertype
-{
- char *name;
- unsigned char Vendor;
- unsigned char Type;
-
- unsigned short thresh1; /* frequency Range for UHF,VHF-L, VHF_H */
- unsigned short thresh2;
- unsigned char VHF_L;
- unsigned char VHF_H;
- unsigned char UHF;
- unsigned char config;
- unsigned short IFPCoff;
- unsigned char mode; /* mode change value (tested PHILIPS_SECAM only) */
- /* 0x01 -> ??? no change ??? */
- /* 0x02 -> PAL BDGHI / SECAM L */
- /* 0x04 -> ??? PAL others / SECAM others ??? */
- int capability;
-};
-
-/*
- * The floats in the tuner struct are computed at compile time
- * by gcc and cast back to integers. Thus we don't violate the
- * "no float in kernel" rule.
- */
-static struct tunertype tuners[] = {
- { "Temic PAL", TEMIC, PAL,
- 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
- { "Philips PAL_I", Philips, PAL_I,
- 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
- { "Philips NTSC", Philips, NTSC,
- 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
- { "Philips SECAM", Philips, SECAM,
- 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623,0x02},
- { "NoTuner", NoTuner, NOTUNER,
- 0,0,0x00,0x00,0x00,0x00,0x00,000},
- { "Philips PAL", Philips, PAL,
- 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623},
- { "Temic NTSC", TEMIC, NTSC,
- 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
- { "Temic PAL_I", TEMIC, PAL_I,
- 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
- { "Temic 4036 FY5 NTSC", TEMIC, NTSC,
- 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
- { "Alps HSBH1", TEMIC, NTSC,
- 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
- { "Alps TSBE1",TEMIC,PAL,
- 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
- { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modtec MM205 */
- 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
- { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
- 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
- { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
- 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
- { "Temic 4006FH5", TEMIC, PAL_I,
- 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-};
-#define TUNERS (sizeof(tuners)/sizeof(struct tunertype))
-
-/* ---------------------------------------------------------------------- */
-
-static int tuner_getstatus(struct i2c_client *c)
-{
- unsigned char byte;
-
- if (1 != i2c_master_recv(c,&byte,1))
- return 0;
- return byte;
-}
-
-#define TUNER_POR 0x80
-#define TUNER_FL 0x40
-#define TUNER_MODE 0x38
-#define TUNER_AFC 0x07
-
-static int tuner_islocked (struct i2c_client *c)
-{
- return (tuner_getstatus (c) & TUNER_FL);
-}
-
-static int tuner_afcstatus (struct i2c_client *c)
-{
- return (tuner_getstatus (c) & TUNER_AFC) - 2;
-}
-
-#if 0 /* unused */
-static int tuner_mode (struct i2c_client *c)
-{
- return (tuner_getstatus (c) & TUNER_MODE) >> 3;
-}
-#endif
-
-static void set_tv_freq(struct i2c_client *c, int freq)
-{
- u8 config;
- u16 div;
- struct tunertype *tun;
- struct tuner *t = c->data;
- unsigned char buffer[4];
- int rc;
-
- if (t->type == -1) {
- printk("tuner: tuner type not set\n");
- return;
- }
-
- tun=&tuners[t->type];
- if (freq < tun->thresh1)
- config = tun->VHF_L;
- else if (freq < tun->thresh2)
- config = tun->VHF_H;
- else
- config = tun->UHF;
-
-#if 1 // Fix colorstandard mode change
- if (t->type == TUNER_PHILIPS_SECAM && t->mode)
- config |= tun->mode;
- else
- config &= ~tun->mode;
-#else
- config &= ~tun->mode;
-#endif
-
- div=freq + tun->IFPCoff;
-
- /*
- * Philips FI1216MK2 remark from specification :
- * for channel selection involving band switching, and to ensure
- * smooth tuning to the desired channel without causing
- * unnecessary charge pump action, it is recommended to consider
- * the difference between wanted channel frequency and the
- * current channel frequency. Unnecessary charge pump action
- * will result in very low tuning voltage which may drive the
- * oscillator to extreme conditions.
- */
- /*
- * Progfou: specification says to send config data before
- * frequency in case (wanted frequency < current frequency).
- */
-
- if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
- buffer[0] = tun->config;
- buffer[1] = config;
- buffer[2] = (div>>8) & 0x7f;
- buffer[3] = div & 0xff;
- } else {
- buffer[0] = (div>>8) & 0x7f;
- buffer[1] = div & 0xff;
- buffer[2] = tun->config;
- buffer[3] = config;
- }
-
- if (4 != (rc = i2c_master_send(c,buffer,4)))
- printk("tuner: i2c i/o error: rc == %d (should be 4)\n",rc);
-
-}
-
-static void set_radio_freq(struct i2c_client *c, int freq)
-{
- u8 config;
- u16 div;
- struct tunertype *tun;
- struct tuner *t = (struct tuner*)c->data;
- unsigned char buffer[4];
- int rc;
-
- if (t->type == -1) {
- printk("tuner: tuner type not set\n");
- return;
- }
-
- tun=&tuners[t->type];
- config = 0xa5;
- div=freq + (int)(16*10.7);
- div&=0x7fff;
-
- buffer[0] = (div>>8) & 0x7f;
- buffer[1] = div & 0xff;
- buffer[2] = tun->config;
- buffer[3] = config;
- if (4 != (rc = i2c_master_send(c,buffer,4)))
- printk("tuner: i2c i/o error: rc == %d (should be 4)\n",rc);
-
- if (debug) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
-
- if (tuner_islocked (c))
- printk ("tuner: PLL locked\n");
- else
- printk ("tuner: PLL not locked\n");
-
- printk ("tuner: AFC: %d\n", tuner_afcstatus (c));
- }
-}
-/* ---------------------------------------------------------------------- */
-
-
-static int tuner_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
-{
- struct tuner *t;
- struct i2c_client *client;
-
- if (this_adap > 0)
- return -1;
- this_adap++;
-
- client_template.adapter = adap;
- client_template.addr = addr;
-
- printk("tuner: chip found @ 0x%x\n",addr);
-
- if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
- return -ENOMEM;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->data = t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
- if (NULL == t) {
- kfree(client);
- return -ENOMEM;
- }
- memset(t,0,sizeof(struct tuner));
- if (type >= 0 && type < TUNERS) {
- t->type = type;
- strncpy(client->name, tuners[t->type].name, sizeof(client->name));
- } else {
- t->type = -1;
- }
- i2c_attach_client(client);
- MOD_INC_USE_COUNT;
-
- return 0;
-}
-
-static int tuner_probe(struct i2c_adapter *adap)
-{
- if (0 != addr) {
- normal_i2c_range[0] = addr;
- normal_i2c_range[1] = addr;
- }
- this_adap = 0;
- if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
- return i2c_probe(adap, &addr_data, tuner_attach);
- return 0;
-}
-
-static int tuner_detach(struct i2c_client *client)
-{
- struct tuner *t = (struct tuner*)client->data;
-
- i2c_detach_client(client);
- kfree(t);
- kfree(client);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int
-tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- struct tuner *t = (struct tuner*)client->data;
- int *iarg = (int*)arg;
-#if 0
- __u16 *sarg = (__u16*)arg;
-#endif
-
- switch (cmd) {
-
- /* --- configuration --- */
- case TUNER_SET_TYPE:
- if (t->type != -1)
- return 0;
- if (*iarg < 0 || *iarg >= TUNERS)
- return 0;
- t->type = *iarg;
- dprintk("tuner: type set to %d (%s)\n",
- t->type,tuners[t->type].name);
- strncpy(client->name, tuners[t->type].name, sizeof(client->name));
- break;
- case AUDC_SET_RADIO:
- t->radio = 1;
- break;
-
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCSCHAN:
- {
- struct video_channel *vc = arg;
-
- t->radio = 0;
- if (t->type == TUNER_PHILIPS_SECAM) {
- t->mode = (vc->norm == VIDEO_MODE_SECAM) ? 1 : 0;
- set_tv_freq(client,t->freq);
- }
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long *v = arg;
-
- t->freq = *v;
- if (t->radio) {
- dprintk("tuner: radio freq set to %d.%02d\n",
- (*iarg)/16,(*iarg)%16*100/16);
- set_radio_freq(client,t->freq);
- } else {
- dprintk("tuner: tv freq set to %d.%02d\n",
- (*iarg)/16,(*iarg)%16*100/16);
- set_tv_freq(client,t->freq);
- }
- return 0;
- }
-#if 0
- /* --- old, obsolete interface --- */
- case TUNER_SET_TVFREQ:
- dprintk("tuner: tv freq set to %d.%02d\n",
- (*iarg)/16,(*iarg)%16*100/16);
- set_tv_freq(client,*iarg);
- t->radio = 0;
- t->freq = *iarg;
- break;
-
- case TUNER_SET_RADIOFREQ:
- dprintk("tuner: radio freq set to %d.%02d\n",
- (*iarg)/16,(*iarg)%16*100/16);
- set_radio_freq(client,*iarg);
- t->radio = 1;
- t->freq = *iarg;
- break;
- case TUNER_SET_MODE:
- if (t->type != TUNER_PHILIPS_SECAM) {
- dprintk("tuner: trying to change mode for other than TUNER_PHILIPS_SECAM\n");
- } else {
- int mode=(*sarg==VIDEO_MODE_SECAM)?1:0;
- dprintk("tuner: mode set to %d\n", *sarg);
- t->mode = mode;
- set_tv_freq(client,t->freq);
- }
- break;
-#endif
- default:
- /* nothing */
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_driver driver = {
- "i2c TV tuner driver",
- I2C_DRIVERID_TUNER,
- I2C_DF_NOTIFY,
- tuner_probe,
- tuner_detach,
- tuner_command,
-};
-
-static struct i2c_client client_template =
-{
- "(unset)", /* name */
- -1,
- 0,
- 0,
- NULL,
- &driver
-};
-
-EXPORT_NO_SYMBOLS;
-
-int tuner_init_module(void)
-{
- i2c_add_driver(&driver);
- return 0;
-}
-
-void tuner_cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-
-module_init(tuner_init_module);
-module_exit(tuner_cleanup_module);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/tuner.h b/drivers/char/tuner.h
deleted file mode 100644
index 96fcd3021..000000000
--- a/drivers/char/tuner.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- tuner.h - definition for different tuners
-
- Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de)
- minor modifications by Ralph Metzler (rjkm@thp.uni-koeln.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 of the License, 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.
-*/
-
-#ifndef _TUNER_H
-#define _TUNER_H
-
-#define TUNER_TEMIC_PAL 0 /* Miro Gpio Coding -1 */
-#define TUNER_PHILIPS_PAL_I 1
-#define TUNER_PHILIPS_NTSC 2
-#define TUNER_PHILIPS_SECAM 3
-#define TUNER_ABSENT 4
-#define TUNER_PHILIPS_PAL 5
-#define TUNER_TEMIC_NTSC 6
-#define TUNER_TEMIC_PAL_I 7
-#define TUNER_TEMIC_4036FY5_NTSC 8
-#define TUNER_ALPS_TSBH1_NTSC 9
-#define TUNER_ALPS_TSBE1_PAL 10
-#define TUNER_ALPS_TSBB5_PAL_I 11
-#define TUNER_ALPS_TSBE5_PAL 12
-#define TUNER_ALPS_TSBC5_PAL 13
-
-#define NOTUNER 0
-#define PAL 1
-#define PAL_I 2
-#define NTSC 3
-#define SECAM 4
-
-#define NoTuner 0
-#define Philips 1
-#define TEMIC 2
-#define Sony 3
-#define Alps 4
-
-#define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */
-#define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */
-#define TUNER_SET_RADIOFREQ _IOW('t',3,int) /* set radio freq */
-#define TUNER_SET_MODE _IOW('t',4,int) /* set tuner mode */
-
-#endif
diff --git a/drivers/char/tvmixer.c b/drivers/char/tvmixer.c
deleted file mode 100644
index e1034a152..000000000
--- a/drivers/char/tvmixer.c
+++ /dev/null
@@ -1,353 +0,0 @@
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/i2c.h>
-#include <linux/videodev.h>
-#include <asm/semaphore.h>
-#include <linux/init.h>
-
-#include <linux/sound.h>
-#include <linux/soundcard.h>
-#include <asm/uaccess.h>
-
-#include "audiochip.h"
-
-#define DEV_MAX 4
-
-static int debug = 0;
-static int devnr = -1;
-
-MODULE_PARM(debug,"i");
-MODULE_PARM(devnr,"i");
-
-/* ----------------------------------------------------------------------- */
-
-struct TVMIXER {
- struct i2c_client *dev;
- int minor;
- int count;
-};
-
-static struct TVMIXER devices[DEV_MAX];
-
-static int tvmixer_adapters(struct i2c_adapter *adap);
-static int tvmixer_clients(struct i2c_client *client);
-
-static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-static int tvmixer_open(struct inode *inode, struct file *file);
-static int tvmixer_release(struct inode *inode, struct file *file);
-static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin);
-
-
-static struct i2c_driver driver = {
- "tv card mixer driver",
- 42 /* I2C_DRIVERID_FIXME */,
- I2C_DF_DUMMY,
- tvmixer_adapters,
- tvmixer_clients,
-};
-
-static struct file_operations tvmixer_fops = {
- owner: THIS_MODULE,
- llseek: tvmixer_llseek,
- ioctl: tvmixer_ioctl,
- open: tvmixer_open,
- release: tvmixer_release,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int mix_to_v4l(int i)
-{
- int r;
-
- r = ((i & 0xff) * 65536 + 50) / 100;
- if (r > 65535) r = 65535;
- if (r < 0) r = 0;
- return r;
-}
-
-static int v4l_to_mix(int i)
-{
- int r;
-
- r = (i * 100 + 32768) / 65536;
- if (r > 100) r = 100;
- if (r < 0) r = 0;
- return r | (r << 8);
-}
-
-static int v4l_to_mix2(int l, int r)
-{
- r = (r * 100 + 32768) / 65536;
- if (r > 100) r = 100;
- if (r < 0) r = 0;
- l = (l * 100 + 32768) / 65536;
- if (l > 100) l = 100;
- if (l < 0) l = 0;
- return (r << 8) | l;
-}
-
-static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct video_audio va;
- int left,right,ret,val = 0;
- struct TVMIXER *mix = file->private_data;
- struct i2c_client *client = mix->dev;
-
- if (NULL == client)
- return -ENODEV;
-
- if (cmd == SOUND_MIXER_INFO) {
- mixer_info info;
- strncpy(info.id, "tv card", sizeof(info.id));
- strncpy(info.name, client->name, sizeof(info.name));
- info.modify_counter = 42 /* FIXME */;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == SOUND_OLD_MIXER_INFO) {
- _old_mixer_info info;
- strncpy(info.id, "tv card", sizeof(info.id));
- strncpy(info.name, client->name, sizeof(info.name));
- if (copy_to_user((void *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- if (get_user(val, (int *)arg))
- return -EFAULT;
-
- /* read state */
- memset(&va,0,sizeof(va));
- client->driver->command(client,VIDIOCGAUDIO,&va);
-
- switch (cmd) {
- case MIXER_READ(SOUND_MIXER_RECMASK):
- case MIXER_READ(SOUND_MIXER_CAPS):
- case MIXER_READ(SOUND_MIXER_RECSRC):
- case MIXER_WRITE(SOUND_MIXER_RECSRC):
- ret = 0;
- break;
-
- case MIXER_READ(SOUND_MIXER_STEREODEVS):
- ret = SOUND_MASK_VOLUME;
- break;
- case MIXER_READ(SOUND_MIXER_DEVMASK):
- ret = SOUND_MASK_VOLUME;
- if (va.flags & VIDEO_AUDIO_BASS)
- ret |= SOUND_MASK_BASS;
- if (va.flags & VIDEO_AUDIO_TREBLE)
- ret |= SOUND_MASK_TREBLE;
- break;
-
- case MIXER_WRITE(SOUND_MIXER_VOLUME):
- left = mix_to_v4l(val);
- right = mix_to_v4l(val >> 8);
- va.volume = MAX(left,right);
- va.balance = (32768*MIN(left,right)) / (va.volume ? va.volume : 1);
- va.balance = (left<right) ? (65535-va.balance) : va.balance;
- client->driver->command(client,VIDIOCSAUDIO,&va);
- client->driver->command(client,VIDIOCGAUDIO,&va);
- /* fall throuth */
- case MIXER_READ(SOUND_MIXER_VOLUME):
- left = (MIN(65536 - va.balance,32768) *
- va.volume) / 32768;
- right = (MIN(va.balance,32768) *
- va.volume) / 32768;
- ret = v4l_to_mix2(left,right);
- break;
-
- case MIXER_WRITE(SOUND_MIXER_BASS):
- va.bass = mix_to_v4l(val);
- client->driver->command(client,VIDIOCSAUDIO,&va);
- client->driver->command(client,VIDIOCGAUDIO,&va);
- /* fall throuth */
- case MIXER_READ(SOUND_MIXER_BASS):
- ret = v4l_to_mix(va.bass);
- break;
-
- case MIXER_WRITE(SOUND_MIXER_TREBLE):
- va.treble = mix_to_v4l(val);
- client->driver->command(client,VIDIOCSAUDIO,&va);
- client->driver->command(client,VIDIOCGAUDIO,&va);
- /* fall throuth */
- case MIXER_READ(SOUND_MIXER_TREBLE):
- ret = v4l_to_mix(va.treble);
- break;
-
- default:
- return -EINVAL;
- }
- if (put_user(ret, (int *)arg))
- return -EFAULT;
- return 0;
-}
-
-static int tvmixer_open(struct inode *inode, struct file *file)
-{
- int i, minor = MINOR(inode->i_rdev);
- struct TVMIXER *mix = NULL;
- struct i2c_client *client = NULL;
-
- for (i = 0; i < DEV_MAX; i++) {
- if (devices[i].minor == minor) {
- mix = devices+i;
- client = mix->dev;
- break;
- }
- }
-
- if (NULL == client)
- return -ENODEV;
-
- /* lock bttv in memory while the mixer is in use */
- file->private_data = mix;
- if (client->adapter->inc_use)
- client->adapter->inc_use(client->adapter);
- return 0;
-}
-
-static int tvmixer_release(struct inode *inode, struct file *file)
-{
- struct TVMIXER *mix = file->private_data;
- struct i2c_client *client;
-
- client = mix->dev;
- if (NULL == client) {
- return -ENODEV;
- }
-
- if (client->adapter->dec_use)
- client->adapter->dec_use(client->adapter);
- return 0;
-}
-
-static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin)
-{
- return -ESPIPE;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int tvmixer_adapters(struct i2c_adapter *adap)
-{
- return 0;
-}
-
-static int tvmixer_clients(struct i2c_client *client)
-{
- struct video_audio va;
- int i,minor;
-
- /* TV card ??? */
- if (client->adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848)) {
- if (debug)
- printk("tvmixer: %s is not a tv card\n",
- client->adapter->name);
- return -1;
- }
- printk("tvmixer: debug: %s\n",client->name);
-
- /* unregister ?? */
- for (i = 0; i < DEV_MAX; i++) {
- if (devices[i].dev == client) {
- /* unregister */
- unregister_sound_mixer(devices[i].minor);
- devices[i].dev = NULL;
- devices[i].minor = -1;
- printk("tvmixer: %s unregistered (#1)\n",client->name);
- return 0;
- }
- }
-
- /* look for a free slot */
- for (i = 0; i < DEV_MAX; i++)
- if (NULL == devices[i].dev)
- break;
- if (i == DEV_MAX) {
- printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
- return -1;
- }
-
- /* audio chip with mixer ??? */
- if (NULL == client->driver->command) {
- if (debug)
- printk("tvmixer: %s: driver->command is NULL\n",
- client->driver->name);
- return -1;
- }
- memset(&va,0,sizeof(va));
- if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) {
- if (debug)
- printk("tvmixer: %s: VIDIOCGAUDIO failed\n",
- client->name);
- return -1;
- }
- if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) {
- if (debug)
- printk("tvmixer: %s: has no volume control\n",
- client->name);
- return -1;
- }
-
- /* everything is fine, register */
- if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
- printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
- return -1;
- }
-
- devices[i].minor = minor;
- devices[i].count = 0;
- devices[i].dev = client;
- printk("tvmixer: %s (%s) registered with minor %d\n",
- client->name,client->adapter->name,minor);
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-int tvmixer_init_module(void)
-{
- int i;
-
- for (i = 0; i < DEV_MAX; i++)
- devices[i].minor = -1;
- i2c_add_driver(&driver);
- return 0;
-}
-
-void tvmixer_cleanup_module(void)
-{
- int i;
-
- i2c_del_driver(&driver);
- for (i = 0; i < DEV_MAX; i++) {
- if (devices[i].minor != -1) {
- unregister_sound_mixer(devices[i].minor);
- printk("tvmixer: %s unregistered (#2)\n",
- devices[i].dev->name);
- }
- }
-}
-
-module_init(tvmixer_init_module);
-module_exit(tvmixer_cleanup_module);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/char/videodev.c b/drivers/char/videodev.c
deleted file mode 100644
index c806ff264..000000000
--- a/drivers/char/videodev.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Video capture interface for Linux
- *
- * A generic video device interface for the LINUX operating system
- * using a set of device structures/vectors for low level operations.
- *
- * 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 of the License, or (at your option) any later version.
- *
- * Author: Alan Cox, <alan@redhat.com>
- *
- * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
- * - Added procfs support
- */
-
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/videodev.h>
-#include <linux/init.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/kmod.h>
-
-
-#define VIDEO_NUM_DEVICES 256
-
-/*
- * Active devices
- */
-
-static struct video_device *video_device[VIDEO_NUM_DEVICES];
-
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
-
-#include <linux/proc_fs.h>
-
-struct videodev_proc_data {
- struct list_head proc_list;
- char name[16];
- struct video_device *vdev;
- struct proc_dir_entry *proc_entry;
-};
-
-static struct proc_dir_entry *video_dev_proc_entry = NULL;
-struct proc_dir_entry *video_proc_entry = NULL;
-EXPORT_SYMBOL(video_proc_entry);
-LIST_HEAD(videodev_proc_list);
-
-#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
-
-
-#ifdef CONFIG_VIDEO_BWQCAM
-extern int init_bw_qcams(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_CPIA
-extern int cpia_init(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_PLANB
-extern int init_planbs(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_ZORAN
-extern int init_zoran_cards(struct video_init *);
-#endif
-
-static struct video_init video_init_list[]={
-#ifdef CONFIG_VIDEO_BWQCAM
- {"bw-qcam", init_bw_qcams},
-#endif
-#ifdef CONFIG_VIDEO_CPIA
- {"cpia", cpia_init},
-#endif
-#ifdef CONFIG_VIDEO_PLANB
- {"planb", init_planbs},
-#endif
-#ifdef CONFIG_VIDEO_ZORAN
- {"zoran", init_zoran_cards},
-#endif
- {"end", NULL}
-};
-
-/*
- * Read will do some smarts later on. Buffer pin etc.
- */
-
-static ssize_t video_read(struct file *file,
- char *buf, size_t count, loff_t *ppos)
-{
- struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
- if(vfl->read)
- return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
- else
- return -EINVAL;
-}
-
-
-/*
- * Write for now does nothing. No reason it shouldnt do overlay setting
- * for some boards I guess..
- */
-
-static ssize_t video_write(struct file *file, const char *buf,
- size_t count, loff_t *ppos)
-{
- struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
- if(vfl->write)
- return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
- else
- return 0;
-}
-
-/*
- * Poll to see if we're readable, can probably be used for timing on incoming
- * frames, etc..
- */
-
-static unsigned int video_poll(struct file *file, poll_table * wait)
-{
- struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
- if(vfl->poll)
- return vfl->poll(vfl, file, wait);
- else
- return 0;
-}
-
-
-/*
- * Open a video device.
- */
-
-static int video_open(struct inode *inode, struct file *file)
-{
- unsigned int minor = MINOR(inode->i_rdev);
- int err;
- struct video_device *vfl;
-
- if(minor>=VIDEO_NUM_DEVICES)
- return -ENODEV;
-
- vfl=video_device[minor];
- if(vfl==NULL) {
- char modname[20];
-
- sprintf (modname, "char-major-%d-%d", VIDEO_MAJOR, minor);
- request_module(modname);
- vfl=video_device[minor];
- if (vfl==NULL)
- return -ENODEV;
- }
- if(vfl->busy)
- return -EBUSY;
- vfl->busy=1; /* In case vfl->open sleeps */
-
- if(vfl->open)
- {
- err=vfl->open(vfl,0); /* Tell the device it is open */
- if(err)
- {
- vfl->busy=0;
- return err;
- }
- }
- return 0;
-}
-
-/*
- * Last close of a video for Linux device
- */
-
-static int video_release(struct inode *inode, struct file *file)
-{
- struct video_device *vfl;
- lock_kernel();
- vfl=video_device[MINOR(inode->i_rdev)];
- if(vfl->close)
- vfl->close(vfl);
- vfl->busy=0;
- unlock_kernel();
- return 0;
-}
-
-/*
- * Question: Should we be able to capture and then seek around the
- * image ?
- */
-
-static long long video_lseek(struct file * file,
- long long offset, int origin)
-{
- return -ESPIPE;
-}
-
-static int video_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
- int err=vfl->ioctl(vfl, cmd, (void *)arg);
-
- if(err!=-ENOIOCTLCMD)
- return err;
-
- switch(cmd)
- {
- default:
- return -EINVAL;
- }
-}
-
-/*
- * We need to do MMAP support
- */
-
-
-int video_mmap(struct file *file, struct vm_area_struct *vma)
-{
- int ret = -EINVAL;
- struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
- if(vfl->mmap) {
- lock_kernel();
- ret = vfl->mmap(vfl, (char *)vma->vm_start,
- (unsigned long)(vma->vm_end-vma->vm_start));
- unlock_kernel();
- }
- return ret;
-}
-
-/*
- * /proc support
- */
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
-
-/* Hmm... i'd like to see video_capability information here, but
- * how can I access it (without changing the other drivers? -claudio
- */
-static int videodev_proc_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *out = page;
- struct video_device *vfd = data;
- struct videodev_proc_data *d;
- struct list_head *tmp;
- int len;
- char c = ' ';
-
- list_for_each (tmp, &videodev_proc_list) {
- d = list_entry(tmp, struct videodev_proc_data, proc_list);
- if (vfd == d->vdev)
- break;
- }
-
- /* Sanity check */
- if (tmp == &videodev_proc_list)
- goto skip;
-
-#define PRINT_VID_TYPE(x) do { if (vfd->type & x) \
- out += sprintf (out, "%c%s", c, #x); c='|';} while (0)
-
- out += sprintf (out, "name : %s\n", vfd->name);
- out += sprintf (out, "type :");
- PRINT_VID_TYPE(VID_TYPE_CAPTURE);
- PRINT_VID_TYPE(VID_TYPE_TUNER);
- PRINT_VID_TYPE(VID_TYPE_TELETEXT);
- PRINT_VID_TYPE(VID_TYPE_OVERLAY);
- PRINT_VID_TYPE(VID_TYPE_CHROMAKEY);
- PRINT_VID_TYPE(VID_TYPE_CLIPPING);
- PRINT_VID_TYPE(VID_TYPE_FRAMERAM);
- PRINT_VID_TYPE(VID_TYPE_SCALES);
- PRINT_VID_TYPE(VID_TYPE_MONOCHROME);
- PRINT_VID_TYPE(VID_TYPE_SUBCAPTURE);
- PRINT_VID_TYPE(VID_TYPE_MPEG_DECODER);
- PRINT_VID_TYPE(VID_TYPE_MPEG_ENCODER);
- PRINT_VID_TYPE(VID_TYPE_MJPEG_DECODER);
- PRINT_VID_TYPE(VID_TYPE_MJPEG_ENCODER);
- out += sprintf (out, "\n");
- out += sprintf (out, "hardware : 0x%x\n", vfd->hardware);
-#if 0
- out += sprintf (out, "channels : %d\n", d->vcap.channels);
- out += sprintf (out, "audios : %d\n", d->vcap.audios);
- out += sprintf (out, "maxwidth : %d\n", d->vcap.maxwidth);
- out += sprintf (out, "maxheight : %d\n", d->vcap.maxheight);
- out += sprintf (out, "minwidth : %d\n", d->vcap.minwidth);
- out += sprintf (out, "minheight : %d\n", d->vcap.minheight);
-#endif
-
-skip:
- len = out - page;
- len -= off;
- if (len < count) {
- *eof = 1;
- if (len <= 0)
- return 0;
- } else
- len = count;
-
- *start = page + off;
-
- return len;
-}
-
-static void videodev_proc_create(void)
-{
- video_proc_entry = create_proc_entry("video", S_IFDIR, &proc_root);
-
- if (video_proc_entry == NULL) {
- printk("video_dev: unable to initialise /proc/video\n");
- return;
- }
-
- video_proc_entry->owner = THIS_MODULE;
- video_dev_proc_entry = create_proc_entry("dev", S_IFDIR, video_proc_entry);
-
- if (video_dev_proc_entry == NULL) {
- printk("video_dev: unable to initialise /proc/video/dev\n");
- return;
- }
-
- video_dev_proc_entry->owner = THIS_MODULE;
-}
-
-#ifdef MODULE
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
-static void videodev_proc_destroy(void)
-{
- if (video_dev_proc_entry != NULL)
- remove_proc_entry("dev", video_proc_entry);
-
- if (video_proc_entry != NULL)
- remove_proc_entry("video", &proc_root);
-}
-#endif
-#endif
-
-static void videodev_proc_create_dev (struct video_device *vfd, char *name)
-{
- struct videodev_proc_data *d;
- struct proc_dir_entry *p;
-
- if (video_dev_proc_entry == NULL)
- return;
-
- d = kmalloc (sizeof (struct videodev_proc_data), GFP_KERNEL);
- if (!d)
- return;
-
- p = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, video_dev_proc_entry);
- p->data = vfd;
- p->read_proc = videodev_proc_read;
-
- d->proc_entry = p;
- d->vdev = vfd;
- strcpy (d->name, name);
-
- /* How can I get capability information ? */
-
- list_add (&d->proc_list, &videodev_proc_list);
-}
-
-static void videodev_proc_destroy_dev (struct video_device *vfd)
-{
- struct list_head *tmp;
- struct videodev_proc_data *d;
-
- list_for_each (tmp, &videodev_proc_list) {
- d = list_entry(tmp, struct videodev_proc_data, proc_list);
- if (vfd == d->vdev) {
- remove_proc_entry(d->name, video_dev_proc_entry);
- list_del (&d->proc_list);
- kfree (d);
- break;
- }
- }
-}
-
-#endif /* CONFIG_VIDEO_PROC_FS */
-
-extern struct file_operations video_fops;
-
-/**
- * video_register_device - register video4linux devices
- * @vfd: video device structure we want to register
- * @type: type of device to register
- * FIXME: needs a semaphore on 2.3.x
- *
- * The registration code assigns minor numbers based on the type
- * requested. -ENFILE is returned in all the device slots for this
- * category are full. If not then the minor field is set and the
- * driver initialize function is called (if non %NULL).
- *
- * Zero is returned on success.
- *
- * Valid types are
- *
- * %VFL_TYPE_GRABBER - A frame grabber
- *
- * %VFL_TYPE_VTX - A teletext device
- *
- * %VFL_TYPE_VBI - Vertical blank data (undecoded)
- *
- * %VFL_TYPE_RADIO - A radio card
- */
-
-int video_register_device(struct video_device *vfd, int type)
-{
- int i=0;
- int base;
- int err;
- int end;
- char *name_base;
-
- switch(type)
- {
- case VFL_TYPE_GRABBER:
- base=0;
- end=64;
- name_base = "video";
- break;
- case VFL_TYPE_VTX:
- base=192;
- end=224;
- name_base = "vtx";
- break;
- case VFL_TYPE_VBI:
- base=224;
- end=240;
- name_base = "vbi";
- break;
- case VFL_TYPE_RADIO:
- base=64;
- end=128;
- name_base = "radio";
- break;
- default:
- return -1;
- }
-
- for(i=base;i<end;i++)
- {
- if(video_device[i]==NULL)
- {
- char name[16];
-
- video_device[i]=vfd;
- vfd->minor=i;
- /* The init call may sleep so we book the slot out
- then call */
- MOD_INC_USE_COUNT;
- if(vfd->initialize)
- {
- err=vfd->initialize(vfd);
- if(err<0)
- {
- video_device[i]=NULL;
- MOD_DEC_USE_COUNT;
- return err;
- }
- }
- sprintf (name, "v4l/%s%d", name_base, i - base);
- /*
- * Start the device root only. Anything else
- * has serious privacy issues.
- */
- vfd->devfs_handle =
- devfs_register (NULL, name, DEVFS_FL_DEFAULT,
- VIDEO_MAJOR, vfd->minor,
- S_IFCHR | S_IRUSR | S_IWUSR,
- &video_fops, NULL);
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- sprintf (name, "%s%d", name_base, i - base);
- videodev_proc_create_dev (vfd, name);
-#endif
-
-
- return 0;
- }
- }
- return -ENFILE;
-}
-
-/**
- * video_unregister_device - unregister a video4linux device
- * @vfd: the device to unregister
- *
- * This unregisters the passed device and deassigns the minor
- * number. Future open calls will be met with errors.
- */
-
-void video_unregister_device(struct video_device *vfd)
-{
- if(video_device[vfd->minor]!=vfd)
- panic("vfd: bad unregister");
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- videodev_proc_destroy_dev (vfd);
-#endif
-
- devfs_unregister (vfd->devfs_handle);
- video_device[vfd->minor]=NULL;
- MOD_DEC_USE_COUNT;
-}
-
-
-static struct file_operations video_fops=
-{
- owner: THIS_MODULE,
- llseek: video_lseek,
- read: video_read,
- write: video_write,
- ioctl: video_ioctl,
- mmap: video_mmap,
- open: video_open,
- release: video_release,
- poll: video_poll,
-};
-
-/*
- * Initialise video for linux
- */
-
-int __init videodev_init(void)
-{
- struct video_init *vfli = video_init_list;
-
- printk(KERN_INFO "Linux video capture interface: v1.00\n");
- if(devfs_register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops))
- {
- printk("video_dev: unable to get major %d\n", VIDEO_MAJOR);
- return -EIO;
- }
-
- /*
- * Init kernel installed video drivers
- */
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- videodev_proc_create ();
-#endif
-
- while(vfli->init!=NULL)
- {
- vfli->init(vfli);
- vfli++;
- }
- return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
- return videodev_init();
-}
-
-void cleanup_module(void)
-{
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- videodev_proc_destroy ();
-#endif
-
- devfs_unregister_chrdev(VIDEO_MAJOR, "video_capture");
-}
-
-#endif
-
-EXPORT_SYMBOL(video_register_device);
-EXPORT_SYMBOL(video_unregister_device);
-
-MODULE_AUTHOR("Alan Cox");
-MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
diff --git a/drivers/char/vino.c b/drivers/char/vino.c
deleted file mode 100644
index a9ac3086b..000000000
--- a/drivers/char/vino.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* $Id: vino.c,v 1.4 1999/02/09 23:59:36 ulfc Exp $
- * drivers/char/vino.c
- *
- * (incomplete) Driver for the Vino Video input system found in SGI Indys.
- *
- * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
- *
- * This isn't complete yet, please don't expect any video until I've written
- * some more code.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/videodev.h>
-
-#include <asm/addrspace.h>
-#include <asm/system.h>
-
-#include "vino.h"
-
-struct vino_device {
- struct video_device vdev;
-
- unsigned long chan;
-#define VINO_CHAN_A 0
-#define VINO_CHAN_B 1
-
- unsigned long flags;
-#define VINO_DMA_ACTIVE (1<<0)
-};
-
-/* We can actually receive TV and IndyCam input at the same time. Believe it or
- * not..
- */
-static struct vino_device vino[2];
-
-/* Those registers have to be accessed by either *one* 64 bit write or *one* 64
- * bit read. We need some asm to fix this. We can't use mips3 as standard
- * because we just save 32 bits at context switch.
- */
-
-static __inline__ unsigned long long vino_reg_read(unsigned long addr)
-{
- unsigned long long ret __attribute__ ((aligned (64)));
- unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
- unsigned long flags;
-
- save_and_cli(flags);
- __asm__ __volatile__(
- ".set\tmips3\n\t"
- ".set\tnoat\n\t"
- "ld\t$1,(%0)\n\t"
- "sd\t$1,(%1)\n\t"
- ".set\tat\n\t"
- ".set\tmips0"
- :
- :"r" (virt_addr),
- "r" (&ret)
- :"$1");
- restore_flags(flags);
-
- return ret;
-}
-
-static __inline__ void vino_reg_write(unsigned long long value,
- unsigned long addr)
-{
- unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
- unsigned long flags;
-
- /* we might lose the upper parts of the registers which are not saved
- * if there comes an interrupt in our way, play safe */
-
- save_and_cli(flags);
- __asm__ __volatile__(
- ".set\tmips3\n\t"
- ".set\tnoat\n\t"
- "ld\t$1,(%0)\n\t"
- "sd\t$1,(%1)\n\t"
- ".set\tat\n\t"
- ".set\tmips0"
- :
- :"r" (&value),
- "r" (virt_addr)
- :"$1");
- restore_flags(flags);
-}
-
-static __inline__ void vino_reg_and(unsigned long long value,
- unsigned long addr)
-{
- unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
- unsigned long flags;
-
- save_and_cli(flags);
- __asm__ __volatile__(
- ".set\tmips3\n\t"
- ".set\tnoat\n\t"
- "ld\t$1,(%0)\n\t"
- "ld\t$2,(%1)\n\t"
- "and\t$1,$1,$2\n\t"
- "sd\t$1,(%0)\n\t"
- ".set\tat\n\t"
- ".set\tmips0"
- :
- :"r" (virt_addr),
- "r" (&value)
- :"$1","$2");
- restore_flags(flags);
-}
-
-static __inline__ void vino_reg_or(unsigned long long value,
- unsigned long addr)
-{
- unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
- unsigned long flags;
-
- save_and_cli(flags);
- __asm__ __volatile__(
- ".set\tmips3\n\t"
- ".set\tnoat\n\t"
- "ld\t$1,(%0)\n\t"
- "ld\t$2,(%1)\n\t"
- "or\t$1,$1,$2\n\t"
- "sd\t$1,(%0)\n\t"
- ".set\tat\n\t"
- ".set\tmips0"
- :
- :"r" (virt_addr),
- "r" (&value)
- :"$1","$2");
- restore_flags(flags);
-}
-
-static int vino_dma_setup(void)
-{
- return 0;
-}
-
-static void vino_dma_stop(void)
-{
-
-}
-
-static int vino_init(void)
-{
- unsigned long ret;
- unsigned short rev, id;
- unsigned long long foo;
- unsigned long *bar;
-
- bar = (unsigned long *) &foo;
-
- ret = vino_reg_read(VINO_REVID);
-
- rev = (ret & VINO_REVID_REV_MASK);
- id = (ret & VINO_REVID_ID_MASK) >> 4;
-
- printk("Vino: ID:%02hx Rev:%02hx\n", id, rev);
-
- foo = vino_reg_read(VINO_A_DESC_DATA0);
- printk("0x%lx", bar[0]);
- printk("%lx ", bar[1]);
- foo = vino_reg_read(VINO_A_DESC_DATA1);
- printk("0x%lx", bar[0]);
- printk("%lx ", bar[1]);
- foo = vino_reg_read(VINO_A_DESC_DATA2);
- printk("0x%lx", bar[0]);
- printk("%lx ", bar[1]);
- foo = vino_reg_read(VINO_A_DESC_DATA3);
- printk("0x%lx", bar[0]);
- printk("%lx\n", bar[1]);
- foo = vino_reg_read(VINO_B_DESC_DATA0);
- printk("0x%lx", bar[0]);
- printk("%lx ", bar[1]);
- foo = vino_reg_read(VINO_B_DESC_DATA1);
- printk("0x%lx", bar[0]);
- printk("%lx ", bar[1]);
- foo = vino_reg_read(VINO_B_DESC_DATA2);
- printk("0x%lx", bar[0]);
- printk("%lx ", bar[1]);
- foo = vino_reg_read(VINO_B_DESC_DATA3);
- printk("0x%lx", bar[0]);
- printk("%lx\n", bar[1]);
-
- return 0;
-}
-
-static void vino_dma_go(struct vino_device *v)
-{
-
-}
-
-/* Reset the vino back to default state */
-
-static void vino_setup(struct vino_device *v)
-{
-
-}
-
-static int vino_open(struct video_device *dev, int flags)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void vino_close(struct video_device *dev)
-{
- MOD_DEC_USE_COUNT;
-}
-
-static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- return 0;
-}
-
-static int vino_mmap(struct video_device *dev, const char *adr,
- unsigned long size)
-{
- return 0;
-}
-
-static struct video_device vino_dev = {
- "Vino IndyCam/TV",
- VID_TYPE_CAPTURE,
- VID_HARDWARE_VINO,
- vino_open,
- vino_close,
- NULL, /* vino_read */
- NULL, /* vino_write */
- NULL, /* vino_poll */
- vino_ioctl,
- vino_mmap,
- NULL, /* vino_init */
- NULL,
- 0,
- 0
-};
-
-int __init init_vino(struct video_device *dev)
-{
- int err;
-
- err = vino_init();
- if (err)
- return err;
-
-#if 0
- if (video_register_device(&vinodev, VFL_TYPE_GRABBER) == -1) {
- return -ENODEV;
- }
-#endif
-
- return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
- int err;
-
- err = vino_init();
- if (err)
- return err;
-
- return 0;
-}
-
-void cleanup_module(void)
-{
-}
-#endif
diff --git a/drivers/char/vino.h b/drivers/char/vino.h
deleted file mode 100644
index 8caadc9aa..000000000
--- a/drivers/char/vino.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* $Id: vino.h,v 1.1 1999/02/08 18:29:32 ulfc Exp $
- * drivers/sgi/vino.h
- *
- * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
- */
-
-#define VINO_BASE 0x0008000
-
-#define VINO_REVID 0x0000
-#define VINO_CTRL 0x0008
-#define VINO_INTSTAT 0x0010 /* Interrupt status */
-#define VINO_I2C_CTRL 0x0018
-#define VINO_I2C_DATA 0x0020
-#define VINO_A_ALPHA 0x0028 /* Channel A ... */
-#define VINO_A_CLIPS 0x0030 /* Clipping start */
-#define VINO_A_CLIPE 0x0038 /* Clipping end */
-#define VINO_A_FRAMERT 0x0040 /* Framerate */
-#define VINO_A_FLDCNT 0x0048 /* Field counter */
-#define VINO_A_LNSZ 0x0050
-#define VINO_A_LNCNT 0x0058
-#define VINO_A_PGIX 0x0060 /* Page index */
-#define VINO_A_DESC_PTR 0x0068 /* Ptr to next four descriptors */
-#define VINO_A_DESC_TLB_PTR 0x0070 /* Ptr to start of descriptor table */
-#define VINO_A_DESC_DATA0 0x0078 /* Descriptor data 0 */
-#define VINO_A_DESC_DATA1 0x0080 /* ... */
-#define VINO_A_DESC_DATA2 0x0088
-#define VINO_A_DESC_DATA3 0x0090
-#define VINO_A_FIFO_THRESHOLD 0x0098 /* FIFO threshold */
-#define VINO_A_FIFO_RP 0x00a0
-#define VINO_A_FIFO_WP 0x00a8
-#define VINO_B_ALPHA 0x00b0 /* Channel B ... */
-#define VINO_B_CLIPS 0x00b8
-#define VINO_B_CLIPE 0x00c0
-#define VINO_B_FRAMERT 0x00c8
-#define VINO_B_FLDCNT 0x00d0
-#define VINO_B_LNSZ 0x00d8
-#define VINO_B_LNCNT 0x00e0
-#define VINO_B_PGIX 0x00e8
-#define VINO_B_DESC_PTR 0x00f0
-#define VINO_B_DESC_TLB_PTR 0x00f8
-#define VINO_B_DESC_DATA0 0x0100
-#define VINO_B_DESC_DATA1 0x0108
-#define VINO_B_DESC_DATA2 0x0110
-#define VINO_B_DESC_DATA3 0x0118
-#define VINO_B_FIFO_THRESHOLD 0x0120
-#define VINO_B_FIFO_RP 0x0128
-#define VINO_B_FIFO_WP 0x0130
-
-/* Bits in the VINO_REVID register */
-
-#define VINO_REVID_REV_MASK 0x000f /* bits 0:3 */
-#define VINO_REVID_ID_MASK 0x00f0 /* bits 4:7 */
-
-/* Bits in the VINO_CTRL register */
-
-#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
-#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */
-#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */
-#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */
-#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */
-#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */
-#define VINO_CTRL_B_END_DESC_TLB_INT (1<<6) /* End of desc table int */
-#define VINO_CTRL_A_DMA_ENBL (1<<7)
-#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
-#define VINO_CTRL_A_SYNC_ENBL (1<<9)
-#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
-#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
-#define VINO_CTRL_A_LUMA_ONLY (1<<12)
-#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
-#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
-#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
-#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
-#define VINO_CTRL_B_DMA_ENBL (1<<19)
-#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
-#define VINO_CTRL_B_SYNC_ENBL (1<<21)
-#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
-#define VINO_CTRL_B_RGB (1<<22) /* 1=RGB 0=YUV */
-#define VINO_CTRL_B_LUMA_ONLY (1<<23)
-#define VINO_CTRL_B_DEC_ENBL (1<<24) /* Decimation */
-#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 25:28 */
-#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
-#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
-
-/* Bits in the Interrupt and Status register */
-
-#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */
-#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */
-#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */
-#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */
-#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */
-#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */
-
-/* Bits in the Clipping Start register */
-
-#define VINO_CLIPS_START 0x3ff /* bits 0:9 */
-#define VINO_CLIPS_ODD_MASK 0x7fc00 /* bits 10:18 */
-#define VINO_CLIPS_EVEN_MASK 0xff80000 /* bits 19:27 */
-
-/* Bits in the Clipping End register */
-
-#define VINO_CLIPE_END 0x3ff /* bits 0:9 */
-#define VINO_CLIPE_ODD_MASK 0x7fc00 /* bits 10:18 */
-#define VINO_CLIPE_EVEN_MASK 0xff80000 /* bits 19:27 */
-
-/* Bits in the Frame Rate register */
-
-#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
-#define VINO_FRAMERT_RT_MASK 0x1ffe /* bits 1:12 */
-
-/* Bits in the VINO_I2C_CTRL */
-
-#define VINO_CTRL_I2C_IDLE (1<<0) /* write: 0=force idle
- * read: 0=idle 1=not idle */
-#define VINO_CTRL_I2C_DIR (1<<1) /* 0=read 1=write */
-#define VINO_CTRL_I2C_MORE_BYTES (1<<2) /* 0=last byte 1=more bytes */
-#define VINO_CTRL_I2C_TRANS_BUSY (1<<4) /* 0=trans done 1=trans busy */
-#define VINO_CTRL_I2C_ACK (1<<5) /* 0=ack received 1=ack not */
-#define VINO_CTRL_I2C_BUS_ERROR (1<<7) /* 0=no bus err 1=bus err */
diff --git a/drivers/char/wdt285.c b/drivers/char/wdt285.c
index 66633fd20..6745493de 100644
--- a/drivers/char/wdt285.c
+++ b/drivers/char/wdt285.c
@@ -31,7 +31,7 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
-#include <asm/system.h>
+#include <asm/mach-types.h>
#include <asm/dec21285.h>
/*
diff --git a/drivers/char/zr36057.h b/drivers/char/zr36057.h
deleted file mode 100644
index b672357bc..000000000
--- a/drivers/char/zr36057.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- zr36057.h - zr36057 register offsets
-
- Copyright (C) 1998 Dave Perks <dperks@ibm.net>
-
- 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 of the License, 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.
- */
-
-#ifndef _ZR36057_H_
-#define _ZR36057_H_
-
-
-/* Zoran ZR36057 registers */
-
-#define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */
-#define ZR36057_VFEHCR_HSPol (1<<30)
-#define ZR36057_VFEHCR_HStart 10
-#define ZR36057_VFEHCR_HEnd 0
-#define ZR36057_VFEHCR_Hmask 0x3ff
-
-#define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */
-#define ZR36057_VFEVCR_VSPol (1<<30)
-#define ZR36057_VFEVCR_VStart 10
-#define ZR36057_VFEVCR_VEnd 0
-#define ZR36057_VFEVCR_Vmask 0x3ff
-
-#define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */
-#define ZR36057_VFESPFR_ExtFl (1<<26)
-#define ZR36057_VFESPFR_TopField (1<<25)
-#define ZR36057_VFESPFR_VCLKPol (1<<24)
-#define ZR36057_VFESPFR_HFilter 21
-#define ZR36057_VFESPFR_HorDcm 14
-#define ZR36057_VFESPFR_VerDcm 8
-#define ZR36057_VFESPFR_DispMode 6
-#define ZR36057_VFESPFR_YUV422 (0<<3)
-#define ZR36057_VFESPFR_RGB888 (1<<3)
-#define ZR36057_VFESPFR_RGB565 (2<<3)
-#define ZR36057_VFESPFR_RGB555 (3<<3)
-#define ZR36057_VFESPFR_ErrDif (1<<2)
-#define ZR36057_VFESPFR_Pack24 (1<<1)
-#define ZR36057_VFESPFR_LittleEndian (1<<0)
-
-#define ZR36057_VDTR 0x00c /* Video Display "Top" Register */
-
-#define ZR36057_VDBR 0x010 /* Video Display "Bottom" Register */
-
-#define ZR36057_VSSFGR 0x014 /* Video Stride, Status, and Frame Grab Register */
-#define ZR36057_VSSFGR_DispStride 16
-#define ZR36057_VSSFGR_VidOvf (1<<8)
-#define ZR36057_VSSFGR_SnapShot (1<<1)
-#define ZR36057_VSSFGR_FrameGrab (1<<0)
-
-#define ZR36057_VDCR 0x018 /* Video Display Configuration Register */
-#define ZR36057_VDCR_VidEn (1<<31)
-#define ZR36057_VDCR_MinPix 24
-#define ZR36057_VDCR_Triton (1<<24)
-#define ZR36057_VDCR_VidWinHt 12
-#define ZR36057_VDCR_VidWinWid 0
-
-#define ZR36057_MMTR 0x01c /* Masking Map "Top" Register */
-
-#define ZR36057_MMBR 0x020 /* Masking Map "Bottom" Register */
-
-#define ZR36057_OCR 0x024 /* Overlay Control Register */
-#define ZR36057_OCR_OvlEnable (1 << 15)
-#define ZR36057_OCR_MaskStride 0
-
-#define ZR36057_SPGPPCR 0x028 /* System, PCI, and General Purpose Pins Control Register */
-#define ZR36057_SPGPPCR_SoftReset (1<<24)
-
-#define ZR36057_GPPGCR1 0x02c /* General Purpose Pins and GuestBus Control Register (1) */
-
-#define ZR36057_MCSAR 0x030 /* MPEG Code Source Address Register */
-
-#define ZR36057_MCTCR 0x034 /* MPEG Code Transfer Control Register */
-#define ZR36057_MCTCR_CodTime (1 << 30)
-#define ZR36057_MCTCR_CEmpty (1 << 29)
-#define ZR36057_MCTCR_CFlush (1 << 28)
-#define ZR36057_MCTCR_CodGuestID 20
-#define ZR36057_MCTCR_CodGuestReg 16
-
-#define ZR36057_MCMPR 0x038 /* MPEG Code Memory Pointer Register */
-
-#define ZR36057_ISR 0x03c /* Interrupt Status Register */
-#define ZR36057_ISR_GIRQ1 (1<<30)
-#define ZR36057_ISR_GIRQ0 (1<<29)
-#define ZR36057_ISR_CodRepIRQ (1<<28)
-#define ZR36057_ISR_JPEGRepIRQ (1<<27)
-
-#define ZR36057_ICR 0x040 /* Interrupt Control Register */
-#define ZR36057_ICR_GIRQ1 (1<<30)
-#define ZR36057_ICR_GIRQ0 (1<<29)
-#define ZR36057_ICR_CodRepIRQ (1<<28)
-#define ZR36057_ICR_JPEGRepIRQ (1<<27)
-#define ZR36057_ICR_IntPinEn (1<<24)
-
-#define ZR36057_I2CBR 0x044 /* I2C Bus Register */
-#define ZR36057_I2CBR_SDA (1<<1)
-#define ZR36057_I2CBR_SCL (1<<0)
-
-#define ZR36057_JMC 0x100 /* JPEG Mode and Control */
-#define ZR36057_JMC_JPG (1 << 31)
-#define ZR36057_JMC_JPGExpMode (0 << 29)
-#define ZR36057_JMC_JPGCmpMode (1 << 29)
-#define ZR36057_JMC_MJPGExpMode (2 << 29)
-#define ZR36057_JMC_MJPGCmpMode (3 << 29)
-#define ZR36057_JMC_RTBUSY_FB (1 << 6)
-#define ZR36057_JMC_Go_en (1 << 5)
-#define ZR36057_JMC_SyncMstr (1 << 4)
-#define ZR36057_JMC_Fld_per_buff (1 << 3)
-#define ZR36057_JMC_VFIFO_FB (1 << 2)
-#define ZR36057_JMC_CFIFO_FB (1 << 1)
-#define ZR36057_JMC_Stll_LitEndian (1 << 0)
-
-#define ZR36057_JPC 0x104 /* JPEG Process Control */
-#define ZR36057_JPC_P_Reset (1 << 7)
-#define ZR36057_JPC_CodTrnsEn (1 << 5)
-#define ZR36057_JPC_Active (1 << 0)
-
-#define ZR36057_VSP 0x108 /* Vertical Sync Parameters */
-#define ZR36057_VSP_VsyncSize 16
-#define ZR36057_VSP_FrmTot 0
-
-#define ZR36057_HSP 0x10c /* Horizontal Sync Parameters */
-#define ZR36057_HSP_HsyncStart 16
-#define ZR36057_HSP_LineTot 0
-
-#define ZR36057_FHAP 0x110 /* Field Horizontal Active Portion */
-#define ZR36057_FHAP_NAX 16
-#define ZR36057_FHAP_PAX 0
-
-#define ZR36057_FVAP 0x114 /* Field Vertical Active Portion */
-#define ZR36057_FVAP_NAY 16
-#define ZR36057_FVAP_PAY 0
-
-#define ZR36057_FPP 0x118 /* Field Process Parameters */
-#define ZR36057_FPP_Odd_Even (1 << 0)
-
-#define ZR36057_JCBA 0x11c /* JPEG Code Base Address */
-
-#define ZR36057_JCFT 0x120 /* JPEG Code FIFO Threshold */
-
-#define ZR36057_JCGI 0x124 /* JPEG Codec Guest ID */
-#define ZR36057_JCGI_JPEGuestID 4
-#define ZR36057_JCGI_JPEGuestReg 0
-
-#define ZR36057_GCR2 0x12c /* GuestBus Control Register (2) */
-
-#define ZR36057_POR 0x200 /* Post Office Register */
-#define ZR36057_POR_POPen (1<<25)
-#define ZR36057_POR_POTime (1<<24)
-#define ZR36057_POR_PODir (1<<23)
-
-#define ZR36057_STR 0x300 /* "Still" Transfer Register */
-
-#endif
diff --git a/drivers/char/zr36060.h b/drivers/char/zr36060.h
deleted file mode 100644
index d94f56b0b..000000000
--- a/drivers/char/zr36060.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- zr36060.h - zr36060 register offsets
-
- Copyright (C) 1998 Dave Perks <dperks@ibm.net>
-
- 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 of the License, 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.
- */
-
-#ifndef _ZR36060_H_
-#define _ZR36060_H_
-
-
-/* Zoran ZR36060 registers */
-
-#define ZR36060_LoadParameters 0x000
-#define ZR36060_Load (1<<7)
-#define ZR36060_SyncRst (1<<0)
-
-#define ZR36060_CodeFifoStatus 0x001
-#define ZR36060_Load (1<<7)
-#define ZR36060_SyncRst (1<<0)
-
-#endif
diff --git a/drivers/char/zr36120.c b/drivers/char/zr36120.c
deleted file mode 100644
index 6e860021e..000000000
--- a/drivers/char/zr36120.c
+++ /dev/null
@@ -1,2086 +0,0 @@
-/*
- zr36120.c - Zoran 36120/36125 based framegrabbers
-
- Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
-
- 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 of the License, 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.
-*/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/malloc.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <linux/video_decoder.h>
-#include <asm/segment.h>
-
-#include <linux/version.h>
-#include <asm/uaccess.h>
-
-#include "tuner.h"
-#include "zr36120.h"
-#include "zr36120_mem.h"
-
-/* mark an required function argument unused - lintism */
-#define UNUSED(x) (void)(x)
-
-/* sensible default */
-#ifndef CARDTYPE
-#define CARDTYPE 0
-#endif
-
-/* Anybody who uses more than four? */
-#define ZORAN_MAX 4
-
-static unsigned int triton1=0; /* triton1 chipset? */
-static unsigned int cardtype[ZORAN_MAX]={ [ 0 ... ZORAN_MAX-1 ] = CARDTYPE };
-
-MODULE_AUTHOR("Pauline Middelink <middelin@polyware.nl>");
-MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber");
-MODULE_PARM(triton1,"i");
-MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i");
-
-static int zoran_cards;
-static struct zoran zorans[ZORAN_MAX];
-
-/*
- * the meaning of each element can be found in zr36120.h
- * Determining the value of gpdir/gpval can be tricky. The
- * best way is to run the card under the original software
- * and read the values from the general purpose registers
- * 0x28 and 0x2C. How you do that is left as an exercise
- * to the impatient reader :)
- */
-#define T 1 /* to seperate the bools from the ints */
-#define F 0
-static struct tvcard tvcards[] = {
- /* reported working by <middelin@polyware.nl> */
-/*0*/ { "Trust Victor II",
- 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
- /* reported working by <Michael.Paxton@aihw.gov.au> */
-/*1*/ { "Aitech WaveWatcher TV-PCI",
- 3, 0, T, F, T, T, 0x7F, 0x80, { 1, TUNER(3), SVHS(6) }, { 0 } },
- /* reported working by ? */
-/*2*/ { "Genius Video Wonder PCI Video Capture Card",
- 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
- /* reported working by <Pascal.Gabriel@wanadoo.fr> */
-/*3*/ { "Guillemot Maxi-TV PCI",
- 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
- /* reported working by "Craig Whitmore <lennon@igrin.co.nz> */
-/*4*/ { "Quadrant Buster",
- 3, 3, T, F, T, T, 0x7F, 0x80, { SVHS(1), TUNER(2), 3 }, { 1, 2, 3 } },
- /* a debug entry which has all inputs mapped */
-/*5*/ { "ZR36120 based framegrabber (all inputs enabled)",
- 6, 0, T, T, T, T, 0x7F, 0x80, { 1, 2, 3, 4, 5, 6 }, { 0 } }
-};
-#undef T
-#undef F
-#define NRTVCARDS (sizeof(tvcards)/sizeof(tvcards[0]))
-
-#ifdef __sparc__
-#define ENDIANESS 0
-#else
-#define ENDIANESS ZORAN_VFEC_LE
-#endif
-
-static struct { const char name[8]; uint mode; uint bpp; } palette2fmt[] = {
-/* n/a */ { "n/a", 0, 0 },
-/* GREY */ { "GRAY", 0, 0 },
-/* HI240 */ { "HI240", 0, 0 },
-/* RGB565 */ { "RGB565", ZORAN_VFEC_RGB_RGB565|ENDIANESS, 2 },
-/* RGB24 */ { "RGB24", ZORAN_VFEC_RGB_RGB888|ENDIANESS|ZORAN_VFEC_PACK24, 3 },
-/* RGB32 */ { "RGB32", ZORAN_VFEC_RGB_RGB888|ENDIANESS, 4 },
-/* RGB555 */ { "RGB555", ZORAN_VFEC_RGB_RGB555|ENDIANESS, 2 },
-/* YUV422 */ { "YUV422", ZORAN_VFEC_RGB_YUV422|ENDIANESS, 2 },
-/* YUYV */ { "YUYV", 0, 0 },
-/* UYVY */ { "UYVY", 0, 0 },
-/* YUV420 */ { "YUV420", 0, 0 },
-/* YUV411 */ { "YUV411", 0, 0 },
-/* RAW */ { "RAW", 0, 0 },
-/* YUV422P */ { "YUV422P", 0, 0 },
-/* YUV411P */ { "YUV411P", 0, 0 }};
-#define NRPALETTES (sizeof(palette2fmt)/sizeof(palette2fmt[0]))
-#undef ENDIANESS
-
-/* ----------------------------------------------------------------------- */
-/* ZORAN chipset detector */
-/* shamelessly stolen from bttv.c */
-/* Reason for beeing here: we need to detect if we are running on a */
-/* Triton based chipset, and if so, enable a certain bit */
-/* ----------------------------------------------------------------------- */
-static
-void __init handle_chipset(void)
-{
- struct pci_dev *dev = NULL;
-
- /* Just in case some nut set this to something dangerous */
- if (triton1)
- triton1 = ZORAN_VDC_TRICOM;
-
- while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, dev)))
- {
- printk(KERN_INFO "zoran: Host bridge 82437FX Triton PIIX\n");
- triton1 = ZORAN_VDC_TRICOM;
- }
-}
-
-/* ----------------------------------------------------------------------- */
-/* ZORAN functions */
-/* ----------------------------------------------------------------------- */
-
-static void zoran_set_geo(struct zoran* ztv, struct vidinfo* i);
-
-#if 0 /* unused */
-static
-void zoran_dump(struct zoran *ztv)
-{
- char str[256];
- char *p=str; /* shut up, gcc! */
- int i;
-
- for (i=0; i<0x60; i+=4) {
- if ((i % 16) == 0) {
- if (i) printk("%s\n",str);
- p = str;
- p+= sprintf(str, KERN_DEBUG " %04x: ",i);
- }
- p += sprintf(p, "%08x ",zrread(i));
- }
-}
-#endif /* unused */
-
-static
-void reap_states(struct zoran* ztv)
-{
- /* count frames */
- ztv->fieldnr++;
-
- /*
- * Are we busy at all?
- * This depends on if there is a workqueue AND the
- * videotransfer is enabled on the chip...
- */
- if (ztv->workqueue && (zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
- {
- struct vidinfo* newitem;
-
- /* did we get a complete frame? */
- if (zrread(ZORAN_VSTR) & ZORAN_VSTR_GRAB)
- return;
-
-DEBUG(printk(CARD_DEBUG "completed %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));
-
- /* we are done with this buffer, tell everyone */
- ztv->workqueue->status = FBUFFER_DONE;
- ztv->workqueue->fieldnr = ztv->fieldnr;
- /* not good, here for BTTV_FIELDNR reasons */
- ztv->lastfieldnr = ztv->fieldnr;
-
- switch (ztv->workqueue->kindof) {
- case FBUFFER_GRAB:
- wake_up_interruptible(&ztv->grabq);
- break;
- case FBUFFER_VBI:
- wake_up_interruptible(&ztv->vbiq);
- break;
- default:
- printk(CARD_INFO "somebody killed the workqueue (kindof=%d)!\n",CARD,ztv->workqueue->kindof);
- }
-
- /* item completed, skip to next item in queue */
- write_lock(&ztv->lock);
- newitem = ztv->workqueue->next;
- ztv->workqueue->next = 0; /* mark completed */
- ztv->workqueue = newitem;
- write_unlock(&ztv->lock);
- }
-
- /*
- * ok, so it seems we have nothing in progress right now.
- * Lets see if we can find some work.
- */
- if (ztv->workqueue)
- {
- struct vidinfo* newitem;
-again:
-
-DEBUG(printk(CARD_DEBUG "starting %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));
-
- /* loadup the frame settings */
- read_lock(&ztv->lock);
- zoran_set_geo(ztv,ztv->workqueue);
- read_unlock(&ztv->lock);
-
- switch (ztv->workqueue->kindof) {
- case FBUFFER_GRAB:
- case FBUFFER_VBI:
- zrand(~ZORAN_OCR_OVLEN, ZORAN_OCR);
- zror(ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
- zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
-
- /* start single-shot grab */
- zror(ZORAN_VSTR_GRAB, ZORAN_VSTR);
- break;
- default:
- printk(CARD_INFO "what is this doing on the queue? (kindof=%d)\n",CARD,ztv->workqueue->kindof);
- write_lock(&ztv->lock);
- newitem = ztv->workqueue->next;
- ztv->workqueue->next = 0;
- ztv->workqueue = newitem;
- write_unlock(&ztv->lock);
- if (newitem)
- goto again; /* yeah, sure.. */
- }
- /* bye for now */
- return;
- }
-DEBUG(printk(CARD_DEBUG "nothing in queue\n",CARD));
-
- /*
- * What? Even the workqueue is empty? Am i really here
- * for nothing? Did i come all that way to... do nothing?
- */
-
- /* do we need to overlay? */
- if (test_bit(STATE_OVERLAY, &ztv->state))
- {
- /* are we already overlaying? */
- if (!(zrread(ZORAN_OCR) & ZORAN_OCR_OVLEN) ||
- !(zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
- {
-DEBUG(printk(CARD_DEBUG "starting overlay\n",CARD));
-
- read_lock(&ztv->lock);
- zoran_set_geo(ztv,&ztv->overinfo);
- read_unlock(&ztv->lock);
-
- zror(ZORAN_OCR_OVLEN, ZORAN_OCR);
- zrand(~ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
- zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
- }
-
- /*
- * leave overlaying on, but turn interrupts off.
- */
- zrand(~ZORAN_ICR_EN,ZORAN_ICR);
- return;
- }
-
- /* do we have any VBI idle time processing? */
- if (test_bit(STATE_VBI, &ztv->state))
- {
- struct vidinfo* item;
- struct vidinfo* lastitem;
-
- /* protect the workqueue */
- write_lock(&ztv->lock);
- lastitem = ztv->workqueue;
- if (lastitem)
- while (lastitem->next) lastitem = lastitem->next;
- for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
- if (item->next == 0 && item->status == FBUFFER_FREE)
- {
-DEBUG(printk(CARD_DEBUG "%p added to queue\n",CARD,item));
- item->status = FBUFFER_BUSY;
- if (!lastitem)
- ztv->workqueue = item;
- else
- lastitem->next = item;
- lastitem = item;
- }
- write_unlock(&ztv->lock);
- if (ztv->workqueue)
- goto again; /* hey, _i_ graduated :) */
- }
-
- /*
- * Then we must be realy IDLE
- */
-DEBUG(printk(CARD_DEBUG "turning off\n",CARD));
- /* nothing further to do, disable DMA and further IRQs */
- zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
- zrand(~ZORAN_ICR_EN,ZORAN_ICR);
-}
-
-static
-void zoran_irq(int irq, void *dev_id, struct pt_regs * regs)
-{
- u32 stat,estat;
- int count = 0;
- struct zoran *ztv = (struct zoran *)dev_id;
-
- UNUSED(irq); UNUSED(regs);
- for (;;) {
- /* get/clear interrupt status bits */
- stat=zrread(ZORAN_ISR);
- estat=stat & zrread(ZORAN_ICR);
- if (!estat)
- return;
- zrwrite(estat,ZORAN_ISR);
- IDEBUG(printk(CARD_DEBUG "estat %08x\n",CARD,estat));
- IDEBUG(printk(CARD_DEBUG " stat %08x\n",CARD,stat));
-
- if (estat & ZORAN_ISR_CODE)
- {
- IDEBUG(printk(CARD_DEBUG "CodReplIRQ\n",CARD));
- }
- if (estat & ZORAN_ISR_GIRQ0)
- {
- IDEBUG(printk(CARD_DEBUG "GIRQ0\n",CARD));
- if (!ztv->card->usegirq1)
- reap_states(ztv);
- }
- if (estat & ZORAN_ISR_GIRQ1)
- {
- IDEBUG(printk(CARD_DEBUG "GIRQ1\n",CARD));
- if (ztv->card->usegirq1)
- reap_states(ztv);
- }
-
- count++;
- if (count > 10)
- printk(CARD_ERR "irq loop %d (%x)\n",CARD,count,estat);
- if (count > 20)
- {
- zrwrite(0, ZORAN_ICR);
- printk(CARD_ERR "IRQ lockup, cleared int mask\n",CARD);
- }
- }
-}
-
-static
-int zoran_muxsel(struct zoran* ztv, int channel, int norm)
-{
- int rv;
-
- /* set the new video norm */
- rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &norm);
- if (rv)
- return rv;
- ztv->norm = norm;
-
- /* map the given channel to the cards decoder's channel */
- channel = ztv->card->video_mux[channel] & CHANNEL_MASK;
-
- /* set the new channel */
- rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &channel);
- return rv;
-}
-
-/* Tell the interrupt handler what to to. */
-static
-void zoran_cap(struct zoran* ztv, int on)
-{
-DEBUG(printk(CARD_DEBUG "zoran_cap(%d) state=%x\n",CARD,on,ztv->state));
-
- if (on) {
- ztv->running = 1;
-
- /*
- * turn interrupts (back) on. The DMA will be enabled
- * inside the irq handler when it detects a restart.
- */
- zror(ZORAN_ICR_EN,ZORAN_ICR);
- }
- else {
- /*
- * turn both interrupts and DMA off
- */
- zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
- zrand(~ZORAN_ICR_EN,ZORAN_ICR);
-
- ztv->running = 0;
- }
-}
-
-static ulong dmask[] = {
- 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8,
- 0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80,
- 0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800,
- 0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000,
- 0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000,
- 0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000,
- 0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000,
- 0xF0000000, 0xE0000000, 0xC0000000, 0x80000000
-};
-
-static
-void zoran_built_overlay(struct zoran* ztv, int count, struct video_clip *vcp)
-{
- ulong* mtop;
- int ystep = (ztv->vidXshift + ztv->vidWidth+31)/32; /* next DWORD */
- int i;
-
-DEBUG(printk(KERN_DEBUG " overlay at %p, ystep=%d, clips=%d\n",ztv->overinfo.overlay,ystep,count));
-
- for (i=0; i<count; i++) {
- struct video_clip *vp = vcp+i;
- UNUSED(vp);
-DEBUG(printk(KERN_DEBUG " %d: clip(%d,%d,%d,%d)\n", i,vp->x,vp->y,vp->width,vp->height));
- }
-
- /*
- * activate the visible portion of the screen
- * Note we take some shortcuts here, because we
- * know the width can never be < 32. (I.e. a DWORD)
- * We also assume the overlay starts somewhere in
- * the FIRST dword.
- */
- {
- int start = ztv->vidXshift;
- ulong firstd = dmask[start];
- ulong lastd = ~dmask[(start + ztv->overinfo.w) & 31];
- mtop = ztv->overinfo.overlay;
- for (i=0; i<ztv->overinfo.h; i++) {
- int w = ztv->vidWidth;
- ulong* line = mtop;
- if (start & 31) {
- *line++ = firstd;
- w -= 32-(start&31);
- }
- memset(line, ~0, w/8);
- if (w & 31)
- line[w/32] = lastd;
- mtop += ystep;
- }
- }
-
- /* process clipping regions */
- for (i=0; i<count; i++) {
- int h;
- if (vcp->x < 0 || (uint)vcp->x > ztv->overinfo.w ||
- vcp->y < 0 || vcp->y > ztv->overinfo.h ||
- vcp->width < 0 || (uint)(vcp->x+vcp->width) > ztv->overinfo.w ||
- vcp->height < 0 || (vcp->y+vcp->height) > ztv->overinfo.h)
- {
- DEBUG(printk(CARD_DEBUG "illegal clipzone (%d,%d,%d,%d) not in (0,0,%d,%d), adapting\n",CARD,vcp->x,vcp->y,vcp->width,vcp->height,ztv->overinfo.w,ztv->overinfo.h));
- if (vcp->x < 0) vcp->x = 0;
- if ((uint)vcp->x > ztv->overinfo.w) vcp->x = ztv->overinfo.w;
- if (vcp->y < 0) vcp->y = 0;
- if (vcp->y > ztv->overinfo.h) vcp->y = ztv->overinfo.h;
- if (vcp->width < 0) vcp->width = 0;
- if ((uint)(vcp->x+vcp->width) > ztv->overinfo.w) vcp->width = ztv->overinfo.w - vcp->x;
- if (vcp->height < 0) vcp->height = 0;
- if (vcp->y+vcp->height > ztv->overinfo.h) vcp->height = ztv->overinfo.h - vcp->y;
-// continue;
- }
-
- mtop = &ztv->overinfo.overlay[vcp->y*ystep];
- for (h=0; h<=vcp->height; h++) {
- int w;
- int x = ztv->vidXshift + vcp->x;
- for (w=0; w<=vcp->width; w++) {
- clear_bit(x&31, &mtop[x/32]);
- x++;
- }
- mtop += ystep;
- }
- ++vcp;
- }
-
- mtop = ztv->overinfo.overlay;
- zrwrite(virt_to_bus(mtop), ZORAN_MTOP);
- zrwrite(virt_to_bus(mtop+ystep), ZORAN_MBOT);
- zraor((ztv->vidInterlace*ystep)<<0,~ZORAN_OCR_MASKSTRIDE,ZORAN_OCR);
-}
-
-struct tvnorm
-{
- u16 Wt, Wa, Ht, Ha, HStart, VStart;
-};
-
-static struct tvnorm tvnorms[] = {
- /* PAL-BDGHI */
-/* { 864, 720, 625, 576, 131, 21 },*/
-/*00*/ { 864, 768, 625, 576, 81, 17 },
- /* NTSC */
-/*01*/ { 858, 720, 525, 480, 121, 10 },
- /* SECAM */
-/*02*/ { 864, 720, 625, 576, 131, 21 },
- /* BW50 */
-/*03*/ { 864, 720, 625, 576, 131, 21 },
- /* BW60 */
-/*04*/ { 858, 720, 525, 480, 121, 10 }
-};
-#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
-
-/*
- * Program the chip for a setup as described in the vidinfo struct.
- *
- * Side-effects: calculates vidXshift, vidInterlace,
- * vidHeight, vidWidth which are used in a later stage
- * to calculate the overlay mask
- *
- * This is an internal function, as such it does not check the
- * validity of the struct members... Spectaculair crashes will
- * follow /very/ quick when you're wrong and the chip right :)
- */
-static
-void zoran_set_geo(struct zoran* ztv, struct vidinfo* i)
-{
- ulong top, bot;
- int stride;
- int winWidth, winHeight;
- int maxWidth, maxHeight, maxXOffset, maxYOffset;
- long vfec;
-
-DEBUG(printk(CARD_DEBUG "set_geo(rect=(%d,%d,%d,%d), norm=%d, format=%d, bpp=%d, bpl=%d, busadr=%lx, overlay=%p)\n",CARD,i->x,i->y,i->w,i->h,ztv->norm,i->format,i->bpp,i->bpl,i->busadr,i->overlay));
-
- /*
- * make sure the DMA transfers are inhibited during our
- * reprogramming of the chip
- */
- zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
-
- maxWidth = tvnorms[ztv->norm].Wa;
- maxHeight = tvnorms[ztv->norm].Ha/2;
- maxXOffset = tvnorms[ztv->norm].HStart;
- maxYOffset = tvnorms[ztv->norm].VStart;
-
- /* setup vfec register (keep ExtFl,TopField and VCLKPol settings) */
- vfec = (zrread(ZORAN_VFEC) & (ZORAN_VFEC_EXTFL|ZORAN_VFEC_TOPFIELD|ZORAN_VFEC_VCLKPOL)) |
- (palette2fmt[i->format].mode & (ZORAN_VFEC_RGB|ZORAN_VFEC_ERRDIF|ZORAN_VFEC_LE|ZORAN_VFEC_PACK24));
-
- /*
- * Set top, bottom ptrs. Since these must be DWORD aligned,
- * possible adjust the x and the width of the window.
- * so the endposition stay the same. The vidXshift will make
- * sure we are not writing pixels before the requested x.
- */
- ztv->vidXshift = 0;
- winWidth = i->w;
- if (winWidth < 0)
- winWidth = -winWidth;
- top = i->busadr + i->x*i->bpp + i->y*i->bpl;
- if (top & 3) {
- ztv->vidXshift = (top & 3) / i->bpp;
- winWidth += ztv->vidXshift;
- DEBUG(printk(KERN_DEBUG " window-x shifted %d pixels left\n",ztv->vidXshift));
- top &= ~3;
- }
-
- /*
- * bottom points to next frame but in interleaved mode we want
- * to 'mix' the 2 frames to one capture, so 'bot' points to one
- * (physical) line below the top line.
- */
- bot = top + i->bpl;
- zrwrite(top,ZORAN_VTOP);
- zrwrite(bot,ZORAN_VBOT);
-
- /*
- * Make sure the winWidth is DWORD aligned too,
- * thereby automaticly making sure the stride to the
- * next line is DWORD aligned too (as required by spec).
- */
- if ((winWidth*i->bpp) & 3) {
-DEBUG(printk(KERN_DEBUG " window-width enlarged by %d pixels\n",(winWidth*i->bpp) & 3));
- winWidth += (winWidth*i->bpp) & 3;
- }
-
- /* determine the DispMode and stride */
- if (i->h >= 0 && i->h <= maxHeight) {
- /* single frame grab suffices for this height. */
- vfec |= ZORAN_VFEC_DISPMOD;
- ztv->vidInterlace = 0;
- stride = i->bpl - (winWidth*i->bpp);
- winHeight = i->h;
- }
- else {
- /* interleaving needed for this height */
- ztv->vidInterlace = 1;
- stride = i->bpl*2 - (winWidth*i->bpp);
- winHeight = i->h/2;
- }
- if (winHeight < 0) /* can happen for VBI! */
- winHeight = -winHeight;
-
- /* safety net, sometimes bpl is too short??? */
- if (stride<0) {
-DEBUG(printk(CARD_DEBUG "WARNING stride = %d\n",CARD,stride));
- stride = 0;
- }
-
- zraor((winHeight<<12)|(winWidth<<0),~(ZORAN_VDC_VIDWINHT|ZORAN_VDC_VIDWINWID), ZORAN_VDC);
- zraor(stride<<16,~ZORAN_VSTR_DISPSTRIDE,ZORAN_VSTR);
-
- /* remember vidWidth, vidHeight for overlay calculations */
- ztv->vidWidth = winWidth;
- ztv->vidHeight = winHeight;
-DEBUG(printk(KERN_DEBUG " top=%08lx, bottom=%08lx\n",top,bot));
-DEBUG(printk(KERN_DEBUG " winWidth=%d, winHeight=%d\n",winWidth,winHeight));
-DEBUG(printk(KERN_DEBUG " maxWidth=%d, maxHeight=%d\n",maxWidth,maxHeight));
-DEBUG(printk(KERN_DEBUG " stride=%d\n",stride));
-
- /*
- * determine horizontal scales and crops
- */
- if (i->w < 0) {
- int Hstart = 1;
- int Hend = Hstart + winWidth;
-DEBUG(printk(KERN_DEBUG " Y: scale=0, start=%d, end=%d\n", Hstart, Hend));
- zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
- }
- else {
- int Wa = maxWidth;
- int X = (winWidth*64+Wa-1)/Wa;
- int We = winWidth*64/X;
- int HorDcm = 64-X;
- int hcrop1 = 2*(Wa-We)/4;
- /*
- * BUGFIX: Juha Nurmela <junki@qn-lpr2-165.quicknet.inet.fi>
- * found the solution to the color phase shift.
- * See ChangeLog for the full explanation)
- */
- int Hstart = (maxXOffset + hcrop1) | 1;
- int Hend = Hstart + We - 1;
-
-DEBUG(printk(KERN_DEBUG " X: scale=%d, start=%d, end=%d\n", HorDcm, Hstart, Hend));
-
- zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
- vfec |= HorDcm<<14;
-
- if (HorDcm<16)
- vfec |= ZORAN_VFEC_HFILTER_1; /* no filter */
- else if (HorDcm<32)
- vfec |= ZORAN_VFEC_HFILTER_3; /* 3 tap filter */
- else if (HorDcm<48)
- vfec |= ZORAN_VFEC_HFILTER_4; /* 4 tap filter */
- else vfec |= ZORAN_VFEC_HFILTER_5; /* 5 tap filter */
- }
-
- /*
- * Determine vertical scales and crops
- *
- * when height is negative, we want to read starting at line 0
- * One day someone might need access to these lines...
- */
- if (i->h < 0) {
- int Vstart = 0;
- int Vend = Vstart + winHeight;
-DEBUG(printk(KERN_DEBUG " Y: scale=0, start=%d, end=%d\n", Vstart, Vend));
- zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
- }
- else {
- int Ha = maxHeight;
- int Y = (winHeight*64+Ha-1)/Ha;
- int He = winHeight*64/Y;
- int VerDcm = 64-Y;
- int vcrop1 = 2*(Ha-He)/4;
- int Vstart = maxYOffset + vcrop1;
- int Vend = Vstart + He - 1;
-
-DEBUG(printk(KERN_DEBUG " Y: scale=%d, start=%d, end=%d\n", VerDcm, Vstart, Vend));
- zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
- vfec |= VerDcm<<8;
- }
-
-DEBUG(printk(KERN_DEBUG " F: format=%d(=%s)\n",i->format,palette2fmt[i->format].name));
-
- /* setup the requested format */
- zrwrite(vfec, ZORAN_VFEC);
-}
-
-static
-void zoran_common_open(struct zoran* ztv, int flags)
-{
- UNUSED(flags);
-
- /* already opened? */
- if (ztv->users++ != 0)
- return;
-
- /* unmute audio */
- /* /what/ audio? */
-
- ztv->state = 0;
-
- /* setup the encoder to the initial values */
- ztv->picture.colour=254<<7;
- ztv->picture.brightness=128<<8;
- ztv->picture.hue=128<<8;
- ztv->picture.contrast=216<<7;
- i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &ztv->picture);
-
- /* default to the composite input since my camera is there */
- zoran_muxsel(ztv, 0, VIDEO_MODE_PAL);
-}
-
-static
-void zoran_common_close(struct zoran* ztv)
-{
- if (--ztv->users != 0)
- return;
-
- /* mute audio */
- /* /what/ audio? */
-
- /* stop the chip */
- zoran_cap(ztv, 0);
-}
-
-/*
- * Open a zoran card. Right now the flags are just a hack
- */
-static int zoran_open(struct video_device *dev, int flags)
-{
- struct zoran *ztv = (struct zoran*)dev;
- struct vidinfo* item;
- char* pos;
-
- DEBUG(printk(CARD_DEBUG "open(dev,%d)\n",CARD,flags));
-
- /*********************************************
- * We really should be doing lazy allocing...
- *********************************************/
- /* allocate a frame buffer */
- if (!ztv->fbuffer)
- ztv->fbuffer = bmalloc(ZORAN_MAX_FBUFSIZE);
- if (!ztv->fbuffer) {
- /* could not get a buffer, bail out */
- return -ENOBUFS;
- }
- /* at this time we _always_ have a framebuffer */
- memset(ztv->fbuffer,0,ZORAN_MAX_FBUFSIZE);
-
- if (!ztv->overinfo.overlay)
- ztv->overinfo.overlay = (void*)kmalloc(1024*1024/8, GFP_KERNEL);
- if (!ztv->overinfo.overlay) {
- /* could not get an overlay buffer, bail out */
- bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
- return -ENOBUFS;
- }
- /* at this time we _always_ have a overlay */
-
- /* clear buffer status, and give them a DMAable address */
- pos = ztv->fbuffer;
- for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
- {
- item->status = FBUFFER_FREE;
- item->memadr = pos;
- item->busadr = virt_to_bus(pos);
- pos += ZORAN_MAX_FBUFFER;
- }
-
- /* do the common part of all open's */
- zoran_common_open(ztv, flags);
-
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static
-void zoran_close(struct video_device* dev)
-{
- struct zoran *ztv = (struct zoran*)dev;
-
- DEBUG(printk(CARD_DEBUG "close(dev)\n",CARD));
-
- /* driver specific closure */
- clear_bit(STATE_OVERLAY, &ztv->state);
-
- zoran_common_close(ztv);
-
- /*
- * This is sucky but right now I can't find a good way to
- * be sure its safe to free the buffer. We wait 5-6 fields
- * which is more than sufficient to be sure.
- */
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ/10); /* Wait 1/10th of a second */
-
- /* free the allocated framebuffer */
- if (ztv->fbuffer)
- bfree( ztv->fbuffer, ZORAN_MAX_FBUFSIZE );
- ztv->fbuffer = 0;
- if (ztv->overinfo.overlay)
- kfree( ztv->overinfo.overlay );
- ztv->overinfo.overlay = 0;
-
- MOD_DEC_USE_COUNT;
-}
-
-/*
- * This read function could be used reentrant in a SMP situation.
- *
- * This is made possible by the spinlock which is kept till we
- * found and marked a buffer for our own use. The lock must
- * be released as soon as possible to prevent lock contention.
- */
-static
-long zoran_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
-{
- struct zoran *ztv = (struct zoran*)dev;
- unsigned long max;
- struct vidinfo* unused = 0;
- struct vidinfo* done = 0;
-
- DEBUG(printk(CARD_DEBUG "zoran_read(%p,%ld,%d)\n",CARD,buf,count,nonblock));
-
- /* find ourself a free or completed buffer */
- for (;;) {
- struct vidinfo* item;
-
- write_lock_irq(&ztv->lock);
- for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
- {
- if (!unused && item->status == FBUFFER_FREE)
- unused = item;
- if (!done && item->status == FBUFFER_DONE)
- done = item;
- }
- if (done || unused)
- break;
-
- /* no more free buffers, wait for them. */
- write_unlock_irq(&ztv->lock);
- if (nonblock)
- return -EWOULDBLOCK;
- interruptible_sleep_on(&ztv->grabq);
- if (signal_pending(current))
- return -EINTR;
- }
-
- /* Do we have 'ready' data? */
- if (!done) {
- /* no? than this will take a while... */
- if (nonblock) {
- write_unlock_irq(&ztv->lock);
- return -EWOULDBLOCK;
- }
-
- /* mark the unused buffer as wanted */
- unused->status = FBUFFER_BUSY;
- unused->w = 320;
- unused->h = 240;
- unused->format = VIDEO_PALETTE_RGB24;
- unused->bpp = palette2fmt[unused->format].bpp;
- unused->bpl = unused->w * unused->bpp;
- unused->next = 0;
- { /* add to tail of queue */
- struct vidinfo* oldframe = ztv->workqueue;
- if (!oldframe) ztv->workqueue = unused;
- else {
- while (oldframe->next) oldframe = oldframe->next;
- oldframe->next = unused;
- }
- }
- write_unlock_irq(&ztv->lock);
-
- /* tell the state machine we want it filled /NOW/ */
- zoran_cap(ztv, 1);
-
- /* wait till this buffer gets grabbed */
- while (unused->status == FBUFFER_BUSY) {
- interruptible_sleep_on(&ztv->grabq);
- /* see if a signal did it */
- if (signal_pending(current))
- return -EINTR;
- }
- done = unused;
- }
- else
- write_unlock_irq(&ztv->lock);
-
- /* Yes! we got data! */
- max = done->bpl * done->h;
- if (count > max)
- count = max;
- if (copy_to_user((void*)buf, done->memadr, count))
- count = -EFAULT;
-
- /* keep the engine running */
- done->status = FBUFFER_FREE;
-// zoran_cap(ztv,1);
-
- /* tell listeners this buffer became free */
- wake_up_interruptible(&ztv->grabq);
-
- /* goodbye */
- DEBUG(printk(CARD_DEBUG "zoran_read() returns %lu\n",CARD,count));
- return count;
-}
-
-static
-long zoran_write(struct video_device* dev, const char* buf, unsigned long count, int nonblock)
-{
- struct zoran *ztv = (struct zoran *)dev;
- UNUSED(ztv); UNUSED(dev); UNUSED(buf); UNUSED(count); UNUSED(nonblock);
- DEBUG(printk(CARD_DEBUG "zoran_write\n",CARD));
- return -EINVAL;
-}
-
-#if LINUX_VERSION_CODE >= 0x020100
-static
-unsigned int zoran_poll(struct video_device *dev, struct file *file, poll_table *wait)
-{
- struct zoran *ztv = (struct zoran *)dev;
- struct vidinfo* item;
- unsigned int mask = 0;
-
- poll_wait(file, &ztv->grabq, wait);
-
- for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
- if (item->status == FBUFFER_DONE)
- {
- mask |= (POLLIN | POLLRDNORM);
- break;
- }
-
- DEBUG(printk(CARD_DEBUG "zoran_poll()=%x\n",CARD,mask));
-
- return mask;
-}
-#endif
-
-/* append a new clipregion to the vector of video_clips */
-static
-void new_clip(struct video_window* vw, struct video_clip* vcp, int x, int y, int w, int h)
-{
- vcp[vw->clipcount].x = x;
- vcp[vw->clipcount].y = y;
- vcp[vw->clipcount].width = w;
- vcp[vw->clipcount].height = h;
- vw->clipcount++;
-}
-
-static
-int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
-{
- struct zoran* ztv = (struct zoran*)dev;
-
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability c;
- DEBUG(printk(CARD_DEBUG "VIDIOCGCAP\n",CARD));
-
- strcpy(c.name,ztv->video_dev.name);
- c.type = VID_TYPE_CAPTURE|
- VID_TYPE_OVERLAY|
- VID_TYPE_CLIPPING|
- VID_TYPE_FRAMERAM|
- VID_TYPE_SCALES;
- if (ztv->have_tuner)
- c.type |= VID_TYPE_TUNER;
- if (ztv->have_decoder) {
- c.channels = ztv->card->video_inputs;
- c.audios = ztv->card->audio_inputs;
- } else
- /* no decoder -> no channels */
- c.channels = c.audios = 0;
- c.maxwidth = 768;
- c.maxheight = 576;
- c.minwidth = 32;
- c.minheight = 32;
- if (copy_to_user(arg,&c,sizeof(c)))
- return -EFAULT;
- break;
- }
-
- case VIDIOCGCHAN:
- {
- struct video_channel v;
- int mux;
- if (copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCGCHAN(%d)\n",CARD,v.channel));
- v.flags=VIDEO_VC_AUDIO
-#ifdef VIDEO_VC_NORM
- |VIDEO_VC_NORM
-#endif
- ;
- v.tuners=0;
- v.type=VIDEO_TYPE_CAMERA;
-#ifdef I_EXPECT_POSSIBLE_NORMS_IN_THE_API
- v.norm=VIDEO_MODE_PAL|
- VIDEO_MODE_NTSC|
- VIDEO_MODE_SECAM;
-#else
- v.norm=VIDEO_MODE_PAL;
-#endif
- /* too many inputs? no decoder -> no channels */
- if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs)
- return -EINVAL;
-
- /* now determine the name of the channel */
- mux = ztv->card->video_mux[v.channel];
- if (mux & IS_TUNER) {
- /* lets assume only one tuner, yes? */
- strcpy(v.name,"Television");
- v.type = VIDEO_TYPE_TV;
- if (ztv->have_tuner) {
- v.flags |= VIDEO_VC_TUNER;
- v.tuners = 1;
- }
- }
- else if (mux & IS_SVHS)
- sprintf(v.name,"S-Video-%d",v.channel);
- else
- sprintf(v.name,"CVBS-%d",v.channel);
-
- if (copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- break;
- }
- case VIDIOCSCHAN:
- { /* set video channel */
- struct video_channel v;
- if (copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCSCHAN(%d,%d)\n",CARD,v.channel,v.norm));
-
- /* too many inputs? no decoder -> no channels */
- if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs)
- return -EINVAL;
-
- if (v.norm != VIDEO_MODE_PAL &&
- v.norm != VIDEO_MODE_NTSC &&
- v.norm != VIDEO_MODE_SECAM &&
- v.norm != VIDEO_MODE_AUTO)
- return -EOPNOTSUPP;
-
- /* make it happen, nr1! */
- return zoran_muxsel(ztv,v.channel,v.norm);
- }
-
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCGTUNER(%d)\n",CARD,v.tuner));
-
- /* Only no or one tuner for now */
- if (!ztv->have_tuner || v.tuner)
- return -EINVAL;
-
- strcpy(v.name,"Television");
- v.rangelow = 0;
- v.rangehigh = ~0;
- v.flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
- v.mode = ztv->norm;
- v.signal = 0xFFFF; /* unknown */
-
- if (copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- break;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCSTUNER(%d,%d)\n",CARD,v.tuner,v.mode));
-
- /* Only no or one tuner for now */
- if (!ztv->have_tuner || v.tuner)
- return -EINVAL;
-
- /* and it only has certain valid modes */
- if( v.mode != VIDEO_MODE_PAL &&
- v.mode != VIDEO_MODE_NTSC &&
- v.mode != VIDEO_MODE_SECAM)
- return -EOPNOTSUPP;
-
- /* engage! */
- return zoran_muxsel(ztv,v.tuner,v.mode);
- }
-
- case VIDIOCGPICT:
- {
- struct video_picture p = ztv->picture;
- DEBUG(printk(CARD_DEBUG "VIDIOCGPICT\n",CARD));
- p.depth = ztv->depth;
- switch (p.depth) {
- case 8: p.palette=VIDEO_PALETTE_YUV422;
- break;
- case 15: p.palette=VIDEO_PALETTE_RGB555;
- break;
- case 16: p.palette=VIDEO_PALETTE_RGB565;
- break;
- case 24: p.palette=VIDEO_PALETTE_RGB24;
- break;
- case 32: p.palette=VIDEO_PALETTE_RGB32;
- break;
- }
- if (copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- break;
- }
- case VIDIOCSPICT:
- {
- struct video_picture p;
- if (copy_from_user(&p, arg,sizeof(p)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCSPICT(%d,%d,%d,%d,%d,%d,%d)\n",CARD,p.brightness,p.hue,p.colour,p.contrast,p.whiteness,p.depth,p.palette));
-
- /* depth must match with framebuffer */
- if (p.depth != ztv->depth)
- return -EINVAL;
-
- /* check if palette matches this bpp */
- if (p.palette>NRPALETTES ||
- palette2fmt[p.palette].bpp != ztv->overinfo.bpp)
- return -EINVAL;
-
- write_lock_irq(&ztv->lock);
- ztv->overinfo.format = p.palette;
- ztv->picture = p;
- write_unlock_irq(&ztv->lock);
-
- /* tell the decoder */
- i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);
- break;
- }
-
- case VIDIOCGWIN:
- {
- struct video_window vw;
- DEBUG(printk(CARD_DEBUG "VIDIOCGWIN\n",CARD));
- read_lock(&ztv->lock);
- vw.x = ztv->overinfo.x;
- vw.y = ztv->overinfo.y;
- vw.width = ztv->overinfo.w;
- vw.height = ztv->overinfo.h;
- vw.chromakey= 0;
- vw.flags = 0;
- if (ztv->vidInterlace)
- vw.flags|=VIDEO_WINDOW_INTERLACE;
- read_unlock(&ztv->lock);
- if (copy_to_user(arg,&vw,sizeof(vw)))
- return -EFAULT;
- break;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- struct video_clip *vcp;
- int on;
- if (copy_from_user(&vw,arg,sizeof(vw)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCSWIN(%d,%d,%d,%d,%x,%d)\n",CARD,vw.x,vw.y,vw.width,vw.height,vw.flags,vw.clipcount));
-
- if (vw.flags)
- return -EINVAL;
-
- if (vw.clipcount>256)
- return -EDOM; /* Too many! */
-
- /*
- * Do any clips.
- */
- vcp = vmalloc(sizeof(struct video_clip)*(vw.clipcount+4));
- if (vcp==NULL)
- return -ENOMEM;
- if (vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount))
- return -EFAULT;
-
- on = ztv->running;
- if (on)
- zoran_cap(ztv, 0);
-
- /*
- * strange, it seems xawtv sometimes calls us with 0
- * width and/or height. Ignore these values
- */
- if (vw.x == 0)
- vw.x = ztv->overinfo.x;
- if (vw.y == 0)
- vw.y = ztv->overinfo.y;
-
- /* by now we are committed to the new data... */
- write_lock_irq(&ztv->lock);
- ztv->overinfo.x = vw.x;
- ztv->overinfo.y = vw.y;
- ztv->overinfo.w = vw.width;
- ztv->overinfo.h = vw.height;
- write_unlock_irq(&ztv->lock);
-
- /*
- * Impose display clips
- */
- if (vw.x+vw.width > ztv->swidth)
- new_clip(&vw, vcp, ztv->swidth-vw.x, 0, vw.width-1, vw.height-1);
- if (vw.y+vw.height > ztv->sheight)
- new_clip(&vw, vcp, 0, ztv->sheight-vw.y, vw.width-1, vw.height-1);
-
- /* built the requested clipping zones */
- zoran_set_geo(ztv, &ztv->overinfo);
- zoran_built_overlay(ztv, vw.clipcount, vcp);
- vfree(vcp);
-
- /* if we were on, restart the video engine */
- if (on)
- zoran_cap(ztv, 1);
- break;
- }
-
- case VIDIOCCAPTURE:
- {
- int v;
- get_user_ret(v,(int*)arg, -EFAULT);
- DEBUG(printk(CARD_DEBUG "VIDIOCCAPTURE(%d)\n",CARD,v));
-
- if (v==0) {
- clear_bit(STATE_OVERLAY, &ztv->state);
- zoran_cap(ztv, 1);
- }
- else {
- /* is VIDIOCSFBUF, VIDIOCSWIN done? */
- if (ztv->overinfo.busadr==0 || ztv->overinfo.w==0 || ztv->overinfo.h==0)
- return -EINVAL;
-
- set_bit(STATE_OVERLAY, &ztv->state);
- zoran_cap(ztv, 1);
- }
- break;
- }
-
- case VIDIOCGFBUF:
- {
- struct video_buffer v;
- DEBUG(printk(CARD_DEBUG "VIDIOCGFBUF\n",CARD));
- read_lock(&ztv->lock);
- v.base = (void *)ztv->overinfo.busadr;
- v.height = ztv->sheight;
- v.width = ztv->swidth;
- v.depth = ztv->depth;
- v.bytesperline = ztv->overinfo.bpl;
- read_unlock(&ztv->lock);
- if(copy_to_user(arg, &v,sizeof(v)))
- return -EFAULT;
- break;
- }
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
-#if LINUX_VERSION_CODE >= 0x020100
- if(!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_ADMIN))
-#else
- if(!suser())
-#endif
- return -EPERM;
- if (copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCSFBUF(%p,%d,%d,%d,%d)\n",CARD,v.base, v.width,v.height,v.depth,v.bytesperline));
-
- if (v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
- return -EINVAL;
- if (v.bytesperline<1)
- return -EINVAL;
- if (ztv->running)
- return -EBUSY;
- write_lock_irq(&ztv->lock);
- ztv->overinfo.busadr = (ulong)v.base;
- ztv->sheight = v.height;
- ztv->swidth = v.width;
- ztv->depth = v.depth; /* bits per pixel */
- ztv->overinfo.bpp = ((v.depth+1)&0x38)/8;/* bytes per pixel */
- ztv->overinfo.bpl = v.bytesperline; /* bytes per line */
- write_unlock_irq(&ztv->lock);
- break;
- }
-
- case VIDIOCKEY:
- {
- /* Will be handled higher up .. */
- break;
- }
-
- case VIDIOCSYNC:
- {
- int i;
- get_user_ret(i,(int*)arg, -EFAULT);
- DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d)\n",CARD,i));
- if (i<0 || i>ZORAN_MAX_FBUFFERS)
- return -EINVAL;
- switch (ztv->grabinfo[i].status) {
- case FBUFFER_FREE:
- return -EINVAL;
- case FBUFFER_BUSY:
- /* wait till this buffer gets grabbed */
- while (ztv->grabinfo[i].status == FBUFFER_BUSY) {
- interruptible_sleep_on(&ztv->grabq);
- /* see if a signal did it */
- if (signal_pending(current))
- return -EINTR;
- }
- /* don't fall through; a DONE buffer is not UNUSED */
- break;
- case FBUFFER_DONE:
- ztv->grabinfo[i].status = FBUFFER_FREE;
- /* tell ppl we have a spare buffer */
- wake_up_interruptible(&ztv->grabq);
- break;
- }
- DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d) returns\n",CARD,i));
- break;
- }
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap vm;
- struct vidinfo* frame;
- if (copy_from_user(&vm,arg,sizeof(vm)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCMCAPTURE(%d,(%d,%d),%d)\n",CARD,vm.frame,vm.width,vm.height,vm.format));
- if (vm.frame<0 || vm.frame>ZORAN_MAX_FBUFFERS ||
- vm.width<32 || vm.width>768 ||
- vm.height<32 || vm.height>576 ||
- vm.format>NRPALETTES ||
- palette2fmt[vm.format].mode == 0)
- return -EINVAL;
-
- /* we are allowed to take over UNUSED and DONE buffers */
- frame = &ztv->grabinfo[vm.frame];
- if (frame->status == FBUFFER_BUSY)
- return -EBUSY;
-
- /* setup the other parameters if they are given */
- write_lock_irq(&ztv->lock);
- frame->w = vm.width;
- frame->h = vm.height;
- frame->format = vm.format;
- frame->bpp = palette2fmt[frame->format].bpp;
- frame->bpl = frame->w*frame->bpp;
- frame->status = FBUFFER_BUSY;
- frame->next = 0;
- { /* add to tail of queue */
- struct vidinfo* oldframe = ztv->workqueue;
- if (!oldframe) ztv->workqueue = frame;
- else {
- while (oldframe->next) oldframe = oldframe->next;
- oldframe->next = frame;
- }
- }
- write_unlock_irq(&ztv->lock);
- zoran_cap(ztv, 1);
- break;
- }
-
- case VIDIOCGMBUF:
- {
- struct video_mbuf mb;
- int i;
- DEBUG(printk(CARD_DEBUG "VIDIOCGMBUF\n",CARD));
- mb.size = ZORAN_MAX_FBUFSIZE;
- mb.frames = ZORAN_MAX_FBUFFERS;
- for (i=0; i<ZORAN_MAX_FBUFFERS; i++)
- mb.offsets[i] = i*ZORAN_MAX_FBUFFER;
- if(copy_to_user(arg, &mb,sizeof(mb)))
- return -EFAULT;
- break;
- }
-
- case VIDIOCGUNIT:
- {
- struct video_unit vu;
- DEBUG(printk(CARD_DEBUG "VIDIOCGUNIT\n",CARD));
- vu.video = ztv->video_dev.minor;
- vu.vbi = ztv->vbi_dev.minor;
- vu.radio = VIDEO_NO_UNIT;
- vu.audio = VIDEO_NO_UNIT;
- vu.teletext = VIDEO_NO_UNIT;
- if(copy_to_user(arg, &vu,sizeof(vu)))
- return -EFAULT;
- break;
- }
-
- case VIDIOCGFREQ:
- {
- unsigned long v = ztv->tuner_freq;
- if (copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCGFREQ\n",CARD));
- break;
- }
- case VIDIOCSFREQ:
- {
- unsigned long v;
- if (copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCSFREQ\n",CARD));
-
- if (ztv->have_tuner) {
- int fixme = v;
- if (i2c_control_device(&(ztv->i2c), I2C_DRIVERID_TUNER, TUNER_SET_TVFREQ, &fixme) < 0)
- return -EAGAIN;
- }
- ztv->tuner_freq = v;
- break;
- }
-
- /* Why isn't this in the API?
- * And why doesn't it take a buffer number?
- case BTTV_FIELDNR:
- {
- unsigned long v = ztv->lastfieldnr;
- if (copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "BTTV_FIELDNR\n",CARD));
- break;
- }
- */
-
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static
-int zoran_mmap(struct video_device* dev, const char* adr, unsigned long size)
-{
- struct zoran* ztv = (struct zoran*)dev;
- unsigned long start = (unsigned long)adr;
- unsigned long pos;
-
- DEBUG(printk(CARD_DEBUG "zoran_mmap(0x%p,%ld)\n",CARD,adr,size));
-
- /* sanity checks */
- if (size > ZORAN_MAX_FBUFSIZE || !ztv->fbuffer)
- return -EINVAL;
-
- /* start mapping the whole shabang to user memory */
- pos = (unsigned long)ztv->fbuffer;
- while (size>0) {
- unsigned long page = virt_to_phys((void*)pos);
- if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- return 0;
-}
-
-static struct video_device zr36120_template=
-{
- "UNSET",
- VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
- VID_HARDWARE_ZR36120,
-
- zoran_open,
- zoran_close,
- zoran_read,
- zoran_write,
-#if LINUX_VERSION_CODE >= 0x020100
- zoran_poll, /* poll */
-#endif
- zoran_ioctl,
- zoran_mmap,
- NULL, /* initialize */
- NULL,
- 0,
- -1
-};
-
-static
-int vbi_open(struct video_device *dev, int flags)
-{
- struct zoran *ztv = (struct zoran*)dev->priv;
- struct vidinfo* item;
-
- DEBUG(printk(CARD_DEBUG "vbi_open(dev,%d)\n",CARD,flags));
-
- /*
- * During VBI device open, we continiously grab VBI-like
- * data in the vbi buffer when we have nothing to do.
- * Only when there is an explicit request for VBI data
- * (read call) we /force/ a read.
- */
-
- /* allocate buffers */
- for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
- {
- item->status = FBUFFER_FREE;
-
- /* alloc */
- if (!item->memadr) {
- item->memadr = bmalloc(ZORAN_VBI_BUFSIZE);
- if (!item->memadr) {
- /* could not get a buffer, bail out */
- while (item != ztv->readinfo) {
- item--;
- bfree(item->memadr, ZORAN_VBI_BUFSIZE);
- item->memadr = 0;
- item->busadr = 0;
- }
- return -ENOBUFS;
- }
- }
-
- /* determine the DMAable address */
- item->busadr = virt_to_bus(item->memadr);
- }
-
- /* do the common part of all open's */
- zoran_common_open(ztv, flags);
-
- set_bit(STATE_VBI, &ztv->state);
- /* start read-ahead */
- zoran_cap(ztv, 1);
-
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static
-void vbi_close(struct video_device *dev)
-{
- struct zoran *ztv = (struct zoran*)dev->priv;
- struct vidinfo* item;
-
- DEBUG(printk(CARD_DEBUG "vbi_close(dev)\n",CARD));
-
- /* driver specific closure */
- clear_bit(STATE_VBI, &ztv->state);
-
- zoran_common_close(ztv);
-
- /*
- * This is sucky but right now I can't find a good way to
- * be sure its safe to free the buffer. We wait 5-6 fields
- * which is more than sufficient to be sure.
- */
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ/10); /* Wait 1/10th of a second */
-
- for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
- {
- if (item->memadr)
- bfree(item->memadr, ZORAN_VBI_BUFSIZE);
- item->memadr = 0;
- }
-
- MOD_DEC_USE_COUNT;
-}
-
-/*
- * This read function could be used reentrant in a SMP situation.
- *
- * This is made possible by the spinlock which is kept till we
- * found and marked a buffer for our own use. The lock must
- * be released as soon as possible to prevent lock contention.
- */
-static
-long vbi_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
-{
- struct zoran *ztv = (struct zoran*)dev->priv;
- unsigned long max;
- struct vidinfo* unused = 0;
- struct vidinfo* done = 0;
-
- DEBUG(printk(CARD_DEBUG "vbi_read(0x%p,%ld,%d)\n",CARD,buf,count,nonblock));
-
- /* find ourself a free or completed buffer */
- for (;;) {
- struct vidinfo* item;
-
- write_lock_irq(&ztv->lock);
- for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++) {
- if (!unused && item->status == FBUFFER_FREE)
- unused = item;
- if (!done && item->status == FBUFFER_DONE)
- done = item;
- }
- if (done || unused)
- break;
-
- /* no more free buffers, wait for them. */
- write_unlock_irq(&ztv->lock);
- if (nonblock)
- return -EWOULDBLOCK;
- interruptible_sleep_on(&ztv->vbiq);
- if (signal_pending(current))
- return -EINTR;
- }
-
- /* Do we have 'ready' data? */
- if (!done) {
- /* no? than this will take a while... */
- if (nonblock) {
- write_unlock_irq(&ztv->lock);
- return -EWOULDBLOCK;
- }
-
- /* mark the unused buffer as wanted */
- unused->status = FBUFFER_BUSY;
- unused->next = 0;
- { /* add to tail of queue */
- struct vidinfo* oldframe = ztv->workqueue;
- if (!oldframe) ztv->workqueue = unused;
- else {
- while (oldframe->next) oldframe = oldframe->next;
- oldframe->next = unused;
- }
- }
- write_unlock_irq(&ztv->lock);
-
- /* tell the state machine we want it filled /NOW/ */
- zoran_cap(ztv, 1);
-
- /* wait till this buffer gets grabbed */
- while (unused->status == FBUFFER_BUSY) {
- interruptible_sleep_on(&ztv->vbiq);
- /* see if a signal did it */
- if (signal_pending(current))
- return -EINTR;
- }
- done = unused;
- }
- else
- write_unlock_irq(&ztv->lock);
-
- /* Yes! we got data! */
- max = done->bpl * -done->h;
- if (count > max)
- count = max;
-
- /* check if the user gave us enough room to write the data */
- if (!access_ok(VERIFY_WRITE, buf, count)) {
- count = -EFAULT;
- goto out;
- }
-
- /*
- * Now transform/strip the data from YUV to Y-only
- * NB. Assume the Y is in the LSB of the YUV data.
- */
- {
- unsigned char* optr = buf;
- unsigned char* eptr = buf+count;
-
- /* are we beeing accessed from an old driver? */
- if (count == 2*19*2048) {
- /*
- * Extreme HACK, old VBI programs expect 2048 points
- * of data, and we only got 864 orso. Double each
- * datapoint and clear the rest of the line.
- * This way we have appear to have a
- * sample_frequency of 29.5 Mc.
- */
- int x,y;
- unsigned char* iptr = done->memadr+1;
- for (y=done->h; optr<eptr && y<0; y++)
- {
- /* copy to doubled data to userland */
- for (x=0; optr+1<eptr && x<-done->w; x++)
- {
- unsigned char a = iptr[x*2];
- *optr++ = a;
- *optr++ = a;
- }
- /* and clear the rest of the line */
- for (x*=2; optr<eptr && x<done->bpl; x++)
- *optr++ = 0;
- /* next line */
- iptr += done->bpl;
- }
- }
- else {
- /*
- * Other (probably newer) programs asked
- * us what geometry we are using, and are
- * reading the correct size.
- */
- int x,y;
- unsigned char* iptr = done->memadr+1;
- for (y=done->h; optr<eptr && y<0; y++)
- {
- /* copy to doubled data to userland */
- for (x=0; optr<eptr && x<-done->w; x++)
- *optr++ = iptr[x*2];
- /* and clear the rest of the line */
- for (;optr<eptr && x<done->bpl; x++)
- *optr++ = 0;
- /* next line */
- iptr += done->bpl;
- }
- }
-
- /* API compliance:
- * place the framenumber (half fieldnr) in the last long
- */
- ((ulong*)eptr)[-1] = done->fieldnr/2;
- }
-
- /* keep the engine running */
- done->status = FBUFFER_FREE;
- zoran_cap(ztv, 1);
-
- /* tell listeners this buffer just became free */
- wake_up_interruptible(&ztv->vbiq);
-
- /* goodbye */
-out:
- DEBUG(printk(CARD_DEBUG "vbi_read() returns %lu\n",CARD,count));
- return count;
-}
-
-#if LINUX_VERSION_CODE >= 0x020100
-static
-unsigned int vbi_poll(struct video_device *dev, struct file *file, poll_table *wait)
-{
- struct zoran *ztv = (struct zoran*)dev->priv;
- struct vidinfo* item;
- unsigned int mask = 0;
-
- poll_wait(file, &ztv->vbiq, wait);
-
- for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
- if (item->status == FBUFFER_DONE)
- {
- mask |= (POLLIN | POLLRDNORM);
- break;
- }
-
- DEBUG(printk(CARD_DEBUG "vbi_poll()=%x\n",CARD,mask));
-
- return mask;
-}
-#endif
-
-static
-int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct zoran* ztv = (struct zoran*)dev->priv;
-
- switch (cmd) {
- case VIDIOCGVBIFMT:
- {
- struct vbi_format f;
- DEBUG(printk(CARD_DEBUG "VIDIOCGVBIINFO\n",CARD));
- f.sampling_rate = 14750000UL;
- f.samples_per_line = -ztv->readinfo[0].w;
- f.sample_format = VIDEO_PALETTE_RAW;
- f.start[0] = f.start[1] = ztv->readinfo[0].y;
- f.start[1] += 312;
- f.count[0] = f.count[1] = -ztv->readinfo[0].h;
- f.flags = VBI_INTERLACED;
- if (copy_to_user(arg,&f,sizeof(f)))
- return -EFAULT;
- break;
- }
- case VIDIOCSVBIFMT:
- {
- struct vbi_format f;
- int i;
- if (copy_from_user(&f, arg,sizeof(f)))
- return -EFAULT;
- DEBUG(printk(CARD_DEBUG "VIDIOCSVBIINFO(%d,%d,%d,%d,%d,%d,%d,%x)\n",CARD,f.sampling_rate,f.samples_per_line,f.sample_format,f.start[0],f.start[1],f.count[0],f.count[1],f.flags));
-
- /* lots of parameters are fixed... (PAL) */
- if (f.sampling_rate != 14750000UL ||
- f.samples_per_line > 864 ||
- f.sample_format != VIDEO_PALETTE_RAW ||
- f.start[0] < 0 ||
- f.start[0] != f.start[1]-312 ||
- f.count[0] != f.count[1] ||
- f.start[0]+f.count[0] >= 288 ||
- f.flags != VBI_INTERLACED)
- return -EINVAL;
-
- write_lock_irq(&ztv->lock);
- ztv->readinfo[0].y = f.start[0];
- ztv->readinfo[0].w = -f.samples_per_line;
- ztv->readinfo[0].h = -f.count[0];
- ztv->readinfo[0].bpl = f.samples_per_line*ztv->readinfo[0].bpp;
- for (i=1; i<ZORAN_VBI_BUFFERS; i++)
- ztv->readinfo[i] = ztv->readinfo[i];
- write_unlock_irq(&ztv->lock);
- break;
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static struct video_device vbi_template=
-{
- "UNSET",
- VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
- VID_HARDWARE_ZR36120,
-
- vbi_open,
- vbi_close,
- vbi_read,
- zoran_write,
-#if LINUX_VERSION_CODE >= 0x020100
- vbi_poll, /* poll */
-#endif
- vbi_ioctl,
- NULL, /* no mmap */
- NULL, /* no initialize */
- NULL, /* priv */
- 0, /* busy */
- -1 /* minor */
-};
-
-/*
- * Scan for a Zoran chip, request the irq and map the io memory
- */
-static
-int __init find_zoran(void)
-{
- int result;
- struct zoran *ztv;
- struct pci_dev *dev = NULL;
- unsigned char revision;
- int zoran_num=0;
-
- while ((dev = pci_find_device(PCI_VENDOR_ID_ZORAN,PCI_DEVICE_ID_ZORAN_36120, dev)))
- {
- /* Ok, a ZR36120/ZR36125 found! */
- ztv = &zorans[zoran_num];
- ztv->dev = dev;
-
- if (pci_enable_device(dev))
- return -EIO;
-
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &revision);
- printk(KERN_INFO "zoran: Zoran %x (rev %d) ",
- dev->device, revision);
- printk("bus: %d, devfn: %d, irq: %d, ",
- dev->bus->number, dev->devfn, dev->irq);
- printk("memory: 0x%08lx.\n", ztv->zoran_adr);
-
- ztv->zoran_mem = ioremap(ztv->zoran_adr, 0x1000);
- DEBUG(printk(KERN_DEBUG "zoran: mapped-memory at 0x%p\n",ztv->zoran_mem));
-
- result = request_irq(dev->irq, zoran_irq,
- SA_SHIRQ|SA_INTERRUPT,"zoran",(void *)ztv);
- if (result==-EINVAL)
- {
- printk(KERN_ERR "zoran: Bad irq number or handler\n");
- return -EINVAL;
- }
- if (result==-EBUSY)
- printk(KERN_ERR "zoran: IRQ %d busy, change your PnP config in BIOS\n",dev->irq);
- if (result < 0)
- return result;
-
- /* Enable bus-mastering */
- pci_set_master(dev);
-
- zoran_num++;
- }
- if(zoran_num)
- printk(KERN_INFO "zoran: %d Zoran card(s) found.\n",zoran_num);
- return zoran_num;
-}
-
-static
-int __init init_zoran(int card)
-{
- struct zoran *ztv = &zorans[card];
- int i;
-
- /* if the given cardtype valid? */
- if (cardtype[card]>=NRTVCARDS) {
- printk(KERN_INFO "invalid cardtype(%d) detected\n",cardtype[card]);
- return -1;
- }
-
- /* reset the zoran */
- zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
- udelay(10);
- zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
- udelay(10);
-
- /* zoran chip specific details */
- ztv->card = tvcards+cardtype[card]; /* point to the selected card */
- ztv->norm = 0; /* PAL */
- ztv->tuner_freq = 0;
-
- /* videocard details */
- ztv->swidth = 800;
- ztv->sheight = 600;
- ztv->depth = 16;
-
- /* State details */
- ztv->fbuffer = 0;
- ztv->overinfo.kindof = FBUFFER_OVERLAY;
- ztv->overinfo.status = FBUFFER_FREE;
- ztv->overinfo.x = 0;
- ztv->overinfo.y = 0;
- ztv->overinfo.w = 768; /* 640 */
- ztv->overinfo.h = 576; /* 480 */
- ztv->overinfo.format = VIDEO_PALETTE_RGB565;
- ztv->overinfo.bpp = palette2fmt[ztv->overinfo.format].bpp;
- ztv->overinfo.bpl = ztv->overinfo.bpp*ztv->swidth;
- ztv->overinfo.busadr = 0;
- ztv->overinfo.memadr = 0;
- ztv->overinfo.overlay = 0;
- for (i=0; i<ZORAN_MAX_FBUFFERS; i++) {
- ztv->grabinfo[i] = ztv->overinfo;
- ztv->grabinfo[i].kindof = FBUFFER_GRAB;
- }
- init_waitqueue_head(&ztv->grabq);
-
- /* VBI details */
- ztv->readinfo[0] = ztv->overinfo;
- ztv->readinfo[0].kindof = FBUFFER_VBI;
- ztv->readinfo[0].w = -864;
- ztv->readinfo[0].h = -38;
- ztv->readinfo[0].format = VIDEO_PALETTE_YUV422;
- ztv->readinfo[0].bpp = palette2fmt[ztv->readinfo[0].format].bpp;
- ztv->readinfo[0].bpl = 1024*ztv->readinfo[0].bpp;
- for (i=1; i<ZORAN_VBI_BUFFERS; i++)
- ztv->readinfo[i] = ztv->readinfo[0];
- init_waitqueue_head(&ztv->vbiq);
-
- /* maintenance data */
- ztv->have_decoder = 0;
- ztv->have_tuner = 0;
- ztv->tuner_type = 0;
- ztv->running = 0;
- ztv->users = 0;
- ztv->lock = RW_LOCK_UNLOCKED;
- ztv->workqueue = 0;
- ztv->fieldnr = 0;
- ztv->lastfieldnr = 0;
-
- if (triton1)
- zrand(~ZORAN_VDC_TRICOM, ZORAN_VDC);
-
- /* external FL determines TOP frame */
- zror(ZORAN_VFEC_EXTFL, ZORAN_VFEC);
-
- /* set HSpol */
- if (ztv->card->hsync_pos)
- zrwrite(ZORAN_VFEH_HSPOL, ZORAN_VFEH);
- /* set VSpol */
- if (ztv->card->vsync_pos)
- zrwrite(ZORAN_VFEV_VSPOL, ZORAN_VFEV);
-
- /* Set the proper General Purpuse register bits */
- /* implicit: no softreset, 0 waitstates */
- zrwrite(ZORAN_PCI_SOFTRESET|(ztv->card->gpdir<<0),ZORAN_PCI);
- /* implicit: 3 duration and recovery PCI clocks on guest 0-3 */
- zrwrite(ztv->card->gpval<<24,ZORAN_GUEST);
-
- /* clear interrupt status */
- zrwrite(~0, ZORAN_ISR);
-
- /*
- * i2c template
- */
- ztv->i2c = zoran_i2c_bus_template;
- sprintf(ztv->i2c.name,"zoran-%d",card);
- ztv->i2c.data = ztv;
-
- /*
- * Now add the template and register the device unit
- */
- ztv->video_dev = zr36120_template;
- strcpy(ztv->video_dev.name, ztv->i2c.name);
- ztv->video_dev.priv = ztv;
- if (video_register_device(&ztv->video_dev, VFL_TYPE_GRABBER) < 0)
- return -1;
-
- ztv->vbi_dev = vbi_template;
- strcpy(ztv->vbi_dev.name, ztv->i2c.name);
- ztv->vbi_dev.priv = ztv;
- if (video_register_device(&ztv->vbi_dev, VFL_TYPE_VBI) < 0) {
- video_unregister_device(&ztv->video_dev);
- return -1;
- }
- i2c_register_bus(&ztv->i2c);
-
- /* set interrupt mask - the PIN enable will be set later */
- zrwrite(ZORAN_ICR_GIRQ0|ZORAN_ICR_GIRQ1|ZORAN_ICR_CODE, ZORAN_ICR);
-
- printk(KERN_INFO "%s: installed %s\n",ztv->i2c.name,ztv->card->name);
- return 0;
-}
-
-static
-void __exit release_zoran(int max)
-{
- struct zoran *ztv;
- int i;
-
- for (i=0;i<max; i++)
- {
- ztv = &zorans[i];
-
- /* turn off all capturing, DMA and IRQs */
- /* reset the zoran */
- zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
- udelay(10);
- zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
- udelay(10);
-
- /* first disable interrupts before unmapping the memory! */
- zrwrite(0, ZORAN_ICR);
- zrwrite(0xffffffffUL,ZORAN_ISR);
-
- /* free it */
- free_irq(ztv->dev->irq,ztv);
-
- /* unregister i2c_bus */
- i2c_unregister_bus((&ztv->i2c));
-
- /* unmap and free memory */
- if (ztv->zoran_mem)
- iounmap(ztv->zoran_mem);
-
- video_unregister_device(&ztv->video_dev);
- video_unregister_device(&ztv->vbi_dev);
- }
-}
-
-void __exit zr36120_exit(void)
-{
- release_zoran(zoran_cards);
-}
-
-int __init zr36120_init(void)
-{
- int card;
-
- handle_chipset();
- zoran_cards = find_zoran();
- if (zoran_cards<0)
- /* no cards found, no need for a driver */
- return -EIO;
-
- /* initialize Zorans */
- for (card=0; card<zoran_cards; card++) {
- if (init_zoran(card)<0) {
- /* only release the zorans we have registered */
- release_zoran(card);
- return -EIO;
- }
- }
- return 0;
-}
-
-module_init(zr36120_init);
-module_exit(zr36120_exit);
diff --git a/drivers/char/zr36120.h b/drivers/char/zr36120.h
deleted file mode 100644
index e500de10d..000000000
--- a/drivers/char/zr36120.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- zr36120.h - Zoran 36120/36125 based framegrabbers
-
- Copyright (C) 1998-1999 Pauline Middelink (middelin@polyware.nl)
-
- 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 of the License, 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.
-*/
-
-#ifndef _ZR36120_H
-#define _ZR36120_H
-
-#ifdef __KERNEL__
-
-#include <linux/types.h>
-#include <linux/wait.h>
-
-#include <linux/i2c-old.h>
-#include <linux/videodev.h>
-
-#include <asm/io.h>
-
-/*
- * Debug macro's, place an x behind the ) for actual debug-compilation
- * E.g. #define DEBUG(x...) x
- */
-#define DEBUG(x...) /* Debug driver */
-#define IDEBUG(x...) /* Debug interrupt handler */
-#define PDEBUG 0 /* Debug PCI writes */
-
-/* defined in zr36120_i2c */
-extern struct i2c_bus zoran_i2c_bus_template;
-
-#define ZORAN_MAX_FBUFFERS 2
-#define ZORAN_MAX_FBUFFER (768*576*2)
-#define ZORAN_MAX_FBUFSIZE (ZORAN_MAX_FBUFFERS*ZORAN_MAX_FBUFFER)
-
-#define ZORAN_VBI_BUFFERS 2
-#define ZORAN_VBI_BUFSIZE (22*1024*2)
-
-struct tvcard {
- char* name; /* name of the cardtype */
- int video_inputs; /* number of channels defined in video_mux */
- int audio_inputs; /* number of channels defined in audio_mux */
- __u32 swapi2c:1, /* need to swap i2c wires SDA/SCL? */
- usegirq1:1, /* VSYNC at GIRQ1 instead of GIRQ0? */
- vsync_pos:1, /* positive VSYNC signal? */
- hsync_pos:1, /* positive HSYNC signal? */
- gpdir:8, /* General Purpose Direction register */
- gpval:8; /* General Purpose Value register */
- int video_mux[6]; /* mapping channel number to physical input */
-#define IS_TUNER 0x80
-#define IS_SVHS 0x40
-#define CHANNEL_MASK 0x3F
- int audio_mux[6]; /* mapping channel number to physical input */
-};
-#define TUNER(x) ((x)|IS_TUNER)
-#define SVHS(x) ((x)|IS_SVHS)
-
-struct vidinfo {
- struct vidinfo* next; /* next active buffer */
- uint kindof;
-#define FBUFFER_OVERLAY 0
-#define FBUFFER_GRAB 1
-#define FBUFFER_VBI 2
- uint status;
-#define FBUFFER_FREE 0
-#define FBUFFER_BUSY 1
-#define FBUFFER_DONE 2
- ulong fieldnr; /* # of field, not framer! */
- uint x,y;
- int w,h; /* w,h can be negative! */
- uint format; /* index in palette2fmt[] */
- uint bpp; /* lookup from palette2fmt[] */
- uint bpl; /* calc: width * bpp */
- ulong busadr; /* bus addr for DMA engine */
- char* memadr; /* kernel addr for making copies */
- ulong* overlay; /* kernel addr of overlay mask */
-};
-
-struct zoran
-{
- struct video_device video_dev;
-#define CARD_DEBUG KERN_DEBUG "%s(%lu): "
-#define CARD_INFO KERN_INFO "%s(%lu): "
-#define CARD_ERR KERN_ERR "%s(%lu): "
-#define CARD ztv->video_dev.name,ztv->fieldnr
-
- /* zoran chip specific details */
- struct i2c_bus i2c; /* i2c registration data */
- struct pci_dev* dev; /* ptr to PCI device */
- ulong zoran_adr; /* bus address of IO memory */
- char* zoran_mem; /* kernel address of IO memory */
- struct tvcard* card; /* the cardtype */
- uint norm; /* 0=PAL, 1=NTSC, 2=SECAM */
- uint tuner_freq; /* Current freq in kHz */
- struct video_picture picture; /* Current picture params */
-
- /* videocard details */
- uint swidth; /* screen width */
- uint sheight; /* screen height */
- uint depth; /* depth in bits */
-
- /* State details */
- char* fbuffer; /* framebuffers for mmap */
- struct vidinfo overinfo; /* overlay data */
- struct vidinfo grabinfo[ZORAN_MAX_FBUFFERS]; /* grabbing data*/
- wait_queue_head_t grabq; /* grabbers queue */
-
- /* VBI details */
- struct video_device vbi_dev;
- struct vidinfo readinfo[2]; /* VBI data - flip buffers */
- wait_queue_head_t vbiq; /* vbi queue */
-
- /* maintenance data */
- int have_decoder; /* did we detect a mux? */
- int have_tuner; /* did we detect a tuner? */
- int users; /* howmany video/vbi open? */
- int tuner_type; /* tuner type, when found */
- int running; /* are we rolling? */
- rwlock_t lock;
- int state; /* what is requested of us? */
-#define STATE_OVERLAY 0
-#define STATE_VBI 1
- struct vidinfo* workqueue; /* buffers to grab, head is active */
- ulong fieldnr; /* #field, ticked every VSYNC */
- ulong lastfieldnr; /* #field, ticked every GRAB */
-
- int vidInterlace; /* calculated */
- int vidXshift; /* calculated */
- uint vidWidth; /* calculated */
- uint vidHeight; /* calculated */
-};
-
-#define zrwrite(dat,adr) writel((dat),(char *) (ztv->zoran_mem+(adr)))
-#define zrread(adr) readl(ztv->zoran_mem+(adr))
-
-#if PDEBUG == 0
-#define zrand(dat,adr) zrwrite((dat) & zrread(adr), adr)
-#define zror(dat,adr) zrwrite((dat) | zrread(adr), adr)
-#define zraor(dat,mask,adr) zrwrite( ((dat)&~(mask)) | ((mask)&zrread(adr)), adr)
-#else
-#define zrand(dat, adr) \
-do { \
- ulong data = (dat) & zrread((adr)); \
- zrwrite(data, (adr)); \
- if (0 != (~(dat) & zrread((adr)))) \
- printk(KERN_DEBUG "zoran: zrand at %d(%d) detected set bits(%x)\n", __LINE__, (adr), (dat)); \
-} while(0)
-
-#define zror(dat, adr) \
-do { \
- ulong data = (dat) | zrread((adr)); \
- zrwrite(data, (adr)); \
- if ((dat) != ((dat) & zrread(adr))) \
- printk(KERN_DEBUG "zoran: zror at %d(%d) detected unset bits(%x)\n", __LINE__, (adr), (dat)); \
-} while(0)
-
-#define zraor(dat, mask, adr) \
-do { \
- ulong data; \
- if ((dat) & (mask)) \
- printk(KERN_DEBUG "zoran: zraor at %d(%d) detected bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
- data = ((dat)&~(mask)) | ((mask) & zrread((adr))); \
- zrwrite(data,(adr)); \
- if ( (dat) != (~(mask) & zrread((adr))) ) \
- printk(KERN_DEBUG "zoran: zraor at %d(%d) could not set all bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
-} while(0)
-#endif
-
-#endif
-
-/* zoran PCI address space */
-#define ZORAN_VFEH 0x000 /* Video Front End Horizontal Conf. */
-#define ZORAN_VFEH_HSPOL (1<<30)
-#define ZORAN_VFEH_HSTART (0x3FF<<10)
-#define ZORAN_VFEH_HEND (0x3FF<<0)
-
-#define ZORAN_VFEV 0x004 /* Video Front End Vertical Conf. */
-#define ZORAN_VFEV_VSPOL (1<<30)
-#define ZORAN_VFEV_VSTART (0x3FF<<10)
-#define ZORAN_VFEV_VEND (0x3FF<<0)
-
-#define ZORAN_VFEC 0x008 /* Video Front End Scaler and Pixel */
-#define ZORAN_VFEC_EXTFL (1<<26)
-#define ZORAN_VFEC_TOPFIELD (1<<25)
-#define ZORAN_VFEC_VCLKPOL (1<<24)
-#define ZORAN_VFEC_HFILTER (7<<21)
-#define ZORAN_VFEC_HFILTER_1 (0<<21) /* no lumi, 3-tap chromo */
-#define ZORAN_VFEC_HFILTER_2 (1<<21) /* 3-tap lumi, 3-tap chromo */
-#define ZORAN_VFEC_HFILTER_3 (2<<21) /* 4-tap lumi, 4-tap chromo */
-#define ZORAN_VFEC_HFILTER_4 (3<<21) /* 5-tap lumi, 4-tap chromo */
-#define ZORAN_VFEC_HFILTER_5 (4<<21) /* 4-tap lumi, 4-tap chromo */
-#define ZORAN_VFEC_DUPFLD (1<<20)
-#define ZORAN_VFEC_HORDCM (63<<14)
-#define ZORAN_VFEC_VERDCM (63<<8)
-#define ZORAN_VFEC_DISPMOD (1<<6)
-#define ZORAN_VFEC_RGB (3<<3)
-#define ZORAN_VFEC_RGB_YUV422 (0<<3)
-#define ZORAN_VFEC_RGB_RGB888 (1<<3)
-#define ZORAN_VFEC_RGB_RGB565 (2<<3)
-#define ZORAN_VFEC_RGB_RGB555 (3<<3)
-#define ZORAN_VFEC_ERRDIF (1<<2)
-#define ZORAN_VFEC_PACK24 (1<<1)
-#define ZORAN_VFEC_LE (1<<0)
-
-#define ZORAN_VTOP 0x00C /* Video Display "Top" */
-
-#define ZORAN_VBOT 0x010 /* Video Display "Bottom" */
-
-#define ZORAN_VSTR 0x014 /* Video Display Stride */
-#define ZORAN_VSTR_DISPSTRIDE (0xFFFF<<16)
-#define ZORAN_VSTR_VIDOVF (1<<8)
-#define ZORAN_VSTR_SNAPSHOT (1<<1)
-#define ZORAN_VSTR_GRAB (1<<0)
-
-#define ZORAN_VDC 0x018 /* Video Display Conf. */
-#define ZORAN_VDC_VIDEN (1<<31)
-#define ZORAN_VDC_MINPIX (0x1F<<25)
-#define ZORAN_VDC_TRICOM (1<<24)
-#define ZORAN_VDC_VIDWINHT (0x3FF<<12)
-#define ZORAN_VDC_VIDWINWID (0x3FF<<0)
-
-#define ZORAN_MTOP 0x01C /* Masking Map "Top" */
-
-#define ZORAN_MBOT 0x020 /* Masking Map "Bottom" */
-
-#define ZORAN_OCR 0x024 /* Overlay Control */
-#define ZORAN_OCR_OVLEN (1<<15)
-#define ZORAN_OCR_MASKSTRIDE (0xFF<<0)
-
-#define ZORAN_PCI 0x028 /* System, PCI and GPP Control */
-#define ZORAN_PCI_SOFTRESET (1<<24)
-#define ZORAN_PCI_WAITSTATE (3<<16)
-#define ZORAN_PCI_GENPURDIR (0xFF<<0)
-
-#define ZORAN_GUEST 0x02C /* GuestBus Control */
-
-#define ZORAN_CSOURCE 0x030 /* Code Source Address */
-
-#define ZORAN_CTRANS 0x034 /* Code Transfer Control */
-
-#define ZORAN_CMEM 0x038 /* Code Memory Pointer */
-
-#define ZORAN_ISR 0x03C /* Interrupt Status Register */
-#define ZORAN_ISR_CODE (1<<28)
-#define ZORAN_ISR_GIRQ0 (1<<29)
-#define ZORAN_ISR_GIRQ1 (1<<30)
-
-#define ZORAN_ICR 0x040 /* Interrupt Control Register */
-#define ZORAN_ICR_EN (1<<24)
-#define ZORAN_ICR_CODE (1<<28)
-#define ZORAN_ICR_GIRQ0 (1<<29)
-#define ZORAN_ICR_GIRQ1 (1<<30)
-
-#define ZORAN_I2C 0x044 /* I2C-Bus */
-#define ZORAN_I2C_SCL (1<<1)
-#define ZORAN_I2C_SDA (1<<0)
-
-#define ZORAN_POST 0x48 /* PostOffice */
-#define ZORAN_POST_PEN (1<<25)
-#define ZORAN_POST_TIME (1<<24)
-#define ZORAN_POST_DIR (1<<23)
-#define ZORAN_POST_GUESTID (3<<20)
-#define ZORAN_POST_GUEST (7<<16)
-#define ZORAN_POST_DATA (0xFF<<0)
-
-#endif
diff --git a/drivers/char/zr36120_i2c.c b/drivers/char/zr36120_i2c.c
deleted file mode 100644
index 0de59b9f1..000000000
--- a/drivers/char/zr36120_i2c.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- zr36120_i2c.c - Zoran 36120/36125 based framegrabbers
-
- Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
-
- 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 of the License, 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.
-*/
-
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#include <linux/version.h>
-#include <linux/video_decoder.h>
-#include <asm/uaccess.h>
-
-#include "tuner.h"
-#include "zr36120.h"
-
-/* ----------------------------------------------------------------------- */
-/* I2C functions */
-/* ----------------------------------------------------------------------- */
-
-/* software I2C functions */
-
-#define I2C_DELAY 10
-
-static void i2c_setlines(struct i2c_bus *bus,int ctrl,int data)
-{
- struct zoran *ztv = (struct zoran*)bus->data;
- unsigned int b = 0;
- if (data) b |= ztv->card->swapi2c ? ZORAN_I2C_SCL : ZORAN_I2C_SDA;
- if (ctrl) b |= ztv->card->swapi2c ? ZORAN_I2C_SDA : ZORAN_I2C_SCL;
- zrwrite(b, ZORAN_I2C);
- udelay(I2C_DELAY);
-}
-
-static int i2c_getdataline(struct i2c_bus *bus)
-{
- struct zoran *ztv = (struct zoran*)bus->data;
- if (ztv->card->swapi2c)
- return zrread(ZORAN_I2C) & ZORAN_I2C_SCL;
- return zrread(ZORAN_I2C) & ZORAN_I2C_SDA;
-}
-
-static
-void attach_inform(struct i2c_bus *bus, int id)
-{
- struct zoran *ztv = (struct zoran*)bus->data;
- struct video_decoder_capability dc;
- int rv;
-
- switch (id) {
- case I2C_DRIVERID_VIDEODECODER:
- DEBUG(printk(CARD_INFO "decoder attached\n",CARD));
-
- /* fetch the capabilites of the decoder */
- rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc);
- if (rv) {
- DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD));
- break;
- }
- DEBUG(printk(CARD_DEBUG "capabilities %d %d %d\n",CARD,dc.flags,dc.inputs,dc.outputs));
-
- /* Test if the decoder can de VBI transfers */
- if (dc.flags & 16 /*VIDEO_DECODER_VBI*/)
- ztv->have_decoder = 2;
- else
- ztv->have_decoder = 1;
- break;
- case I2C_DRIVERID_TUNER:
- ztv->have_tuner = 1;
- DEBUG(printk(CARD_INFO "tuner attached\n",CARD));
- if (ztv->tuner_type >= 0)
- {
- if (i2c_control_device(&ztv->i2c,I2C_DRIVERID_TUNER,TUNER_SET_TYPE,&ztv->tuner_type)<0)
- DEBUG(printk(CARD_INFO "attach_inform; tuner wont be set to type %d\n",CARD,ztv->tuner_type));
- }
- break;
- default:
- DEBUG(printk(CARD_INFO "attach_inform; unknown device id=%d\n",CARD,id));
- break;
- }
-}
-
-static
-void detach_inform(struct i2c_bus *bus, int id)
-{
- struct zoran *ztv = (struct zoran*)bus->data;
-
- switch (id) {
- case I2C_DRIVERID_VIDEODECODER:
- ztv->have_decoder = 0;
- DEBUG(printk(CARD_INFO "decoder detached\n",CARD));
- break;
- case I2C_DRIVERID_TUNER:
- ztv->have_tuner = 0;
- DEBUG(printk(CARD_INFO "tuner detached\n",CARD));
- break;
- default:
- DEBUG(printk(CARD_INFO "detach_inform; unknown device id=%d\n",CARD,id));
- break;
- }
-}
-
-struct i2c_bus zoran_i2c_bus_template =
-{
- "ZR36120",
- I2C_BUSID_ZORAN,
- NULL,
-
- SPIN_LOCK_UNLOCKED,
-
- attach_inform,
- detach_inform,
-
- i2c_setlines,
- i2c_getdataline,
- NULL,
- NULL
-};
diff --git a/drivers/char/zr36120_mem.c b/drivers/char/zr36120_mem.c
deleted file mode 100644
index b4c6078d3..000000000
--- a/drivers/char/zr36120_mem.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- zr36120_mem.c - Zoran 36120/36125 based framegrabbers
-
- Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
-
- 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 of the License, 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.
-*/
-
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/wrapper.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#ifdef CONFIG_BIGPHYS_AREA
-#include <linux/bigphysarea.h>
-#endif
-
-#include "zr36120.h"
-#include "zr36120_mem.h"
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-void* bmalloc(unsigned long size)
-{
- void* mem;
-#ifdef CONFIG_BIGPHYS_AREA
- mem = bigphysarea_alloc_pages(size/PAGE_SIZE, 1, GFP_KERNEL);
-#else
- /*
- * The following function got a lot of memory at boottime,
- * so we know its always there...
- */
- mem = (void*)__get_free_pages(GFP_USER|GFP_DMA,get_order(size));
-#endif
- if (mem) {
- unsigned long adr = (unsigned long)mem;
- while (size > 0) {
- mem_map_reserve(virt_to_page(phys_to_virt(adr)));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- }
- return mem;
-}
-
-void bfree(void* mem, unsigned long size)
-{
- if (mem) {
- unsigned long adr = (unsigned long)mem;
- unsigned long siz = size;
- while (siz > 0) {
- mem_map_unreserve(virt_to_page(phys_to_virt(adr)));
- adr += PAGE_SIZE;
- siz -= PAGE_SIZE;
- }
-#ifdef CONFIG_BIGPHYS_AREA
- bigphysarea_free_pages(mem);
-#else
- free_pages((unsigned long)mem,get_order(size));
-#endif
- }
-}
diff --git a/drivers/char/zr36120_mem.h b/drivers/char/zr36120_mem.h
deleted file mode 100644
index aad117acc..000000000
--- a/drivers/char/zr36120_mem.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* either kmalloc() or bigphysarea() alloced memory - continuous */
-void* bmalloc(unsigned long size);
-void bfree(void* mem, unsigned long size);