summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Config.in6
-rw-r--r--drivers/char/Makefile52
-rw-r--r--drivers/char/bttv.c623
-rw-r--r--drivers/char/bttv.h18
-rw-r--r--drivers/char/epca.c3
-rw-r--r--drivers/char/generic_serial.c35
-rw-r--r--drivers/char/lp.c8
-rw-r--r--drivers/char/mem.c31
-rw-r--r--drivers/char/msp3400.c16
-rw-r--r--drivers/char/rio/func.h2
-rw-r--r--drivers/char/rio/host.h8
-rw-r--r--drivers/char/rio/linux_compat.h1
-rw-r--r--drivers/char/rio/rio_linux.c285
-rw-r--r--drivers/char/rio/rio_linux.h27
-rw-r--r--drivers/char/rio/rioboot.c111
-rw-r--r--drivers/char/rio/riocmd.c1
-rw-r--r--drivers/char/rio/rioctrl.c4
-rw-r--r--drivers/char/rio/rioinit.c2
-rw-r--r--drivers/char/rio/riotty.c38
-rw-r--r--drivers/char/rio/unixrup.h2
-rw-r--r--drivers/char/rtc.c7
-rw-r--r--drivers/char/sh-sci.c31
-rw-r--r--drivers/char/sh-sci.h25
-rw-r--r--drivers/char/sx.c10
-rw-r--r--drivers/char/tda7432.c505
-rw-r--r--drivers/char/tda8425.c1
-rw-r--r--drivers/char/tda985x.c58
-rw-r--r--drivers/char/tda9875.c371
-rw-r--r--drivers/char/tea6420.c268
-rw-r--r--drivers/char/tty_io.c8
-rw-r--r--drivers/char/videodev.c6
31 files changed, 1889 insertions, 674 deletions
diff --git a/drivers/char/Config.in b/drivers/char/Config.in
index 9df21affa..792832a30 100644
--- a/drivers/char/Config.in
+++ b/drivers/char/Config.in
@@ -50,6 +50,10 @@ if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then
bool ' Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS
fi
tristate ' Specialix SX (and SI) card support' CONFIG_SX
+ tristate ' Specialix RIO system support' CONFIG_RIO
+ if [ "$CONFIG_RIO" != "n" ]; then
+ bool ' Support really old RIO/PCI cards' CONFIG_RIO_OLDPCI
+ fi
bool ' Stallion multiport serial support' CONFIG_STALDRV
if [ "$CONFIG_STALDRV" = "y" ]; then
tristate ' Stallion EasyIO or EC8/32 support' CONFIG_STALLION
@@ -201,7 +205,7 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
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
+ dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT $CONFIG_SOUND
fi
dep_tristate ' Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV
if [ "$CONFIG_ALL_PPC" = "y" ]; then
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 22deb4fad..f75dabd18 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -136,41 +136,38 @@ obj-$(CONFIG_SPECIALIX) += specialix.o
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
obj-$(CONFIG_SX) += sx.o
+# If either SX or RIO is in the kernel, generic_serial goes in the
+# kernel, and the module is no longer required. The "in kernel" case
+# is last to be able to override the module case.... This is an
+# example of the new "makefile automatically figures out the
+# dependencies".... -- REW
-# If either is in the kernel, generic_serial goes in the kernel, and
-# the module is no longer required. The "in kernel" case is last to be
-# able to override the module case.... This is an example of the new
-# "makefile automatically figures out the dependencies".... -- REW
+GS=n
+ifeq ($(CONFIG_RIO),m)
+ M_OBJS += generic_serial.o
+ MOD_SUB_DIRS += rio
+ GS = m
+endif
-GS = n
ifeq ($(CONFIG_SX),m)
GS = m
+ M_OBJS += sx.o
endif
-ifeq ($(CONFIG_RIO),m)
- GS = m
-endif
-ifeq ($(CONFIG_SX),y)
- GS = y
-endif
-ifeq ($(CONFIG_RIO),y)
- GS = y
-endif
-obj-$(GS) += generic_serial.o
-
-
-
ifeq ($(CONFIG_RIO),y)
-obj-y += rio/rio.o generic_serial.o
-SUB_DIRS += rio
-MOD_SUB_DIRS += rio
-else
- ifeq ($(CONFIG_RIO),m)
- obj-m += generic_serial.o
+ L_OBJS += rio/rio.o generic_serial.o
+ SUB_DIRS += rio
MOD_SUB_DIRS += rio
- endif
+ GS = y
endif
+ifeq ($(CONFIG_SX),y)
+ L_OBJS += sx.o
+ GS = y
+endif
+
+obj-$(GS) += generic_serial.o
+
obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o
obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o
obj-$(CONFIG_PRINTER) += lp.o
@@ -205,7 +202,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
obj-$(CONFIG_AMIGAMOUSE) += amigamouse.o
obj-$(CONFIG_ATARIMOUSE) += atarimouse.o
-obj-$(CONFIG_ADBMOUSE) += adbmouse.o busmouse.o
+obj-$(CONFIG_ADBMOUSE) += adbmouse.o
obj-$(CONFIG_PC110_PAD) += pc110pad.o
obj-$(CONFIG_WDT) += wdt.o
obj-$(CONFIG_WDTPCI) += wdt_pci.o
@@ -232,7 +229,8 @@ else
endif
endif
-obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tda8425.o tda985x.o tea6300.o
+obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o \
+ tda7432.o tda8425.o tda985x.o tda9875.o tea6300.o tea6420.o
ifeq ($(CONFIG_VIDEO_BT848),y)
L_TUNERS=y
else
diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c
index f55f992d8..b17efd429 100644
--- a/drivers/char/bttv.c
+++ b/drivers/char/bttv.c
@@ -43,19 +43,13 @@
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/vmalloc.h>
-
-#ifdef LOCK_I2C_BUS
-# error INSTALL ERROR
-# error gcc uses the old, obsolete i2c.h include file. Please install the \
- new i2c stack. Please install it by patching the kernel, otherwise \
- gcc will not find the new header files.
-#endif
+#include <linux/init.h>
#include "bttv.h"
#include "tuner.h"
-#define DEBUG(x) /* Debug driver */
-#define IDEBUG(x) /* Debug interrupt handler */
+#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))
@@ -100,7 +94,7 @@ static int triton1=0;
static unsigned long remap[BTTV_MAX];
static unsigned int radio[BTTV_MAX];
static unsigned int card[BTTV_MAX] = { 0, 0, 0, 0 };
-static unsigned int pll[BTTV_MAX] = { 0, 0, 0, 0};
+static unsigned int pll[BTTV_MAX] = { -1, -1, -1, -1};
static unsigned int fieldnr = 0;
static unsigned int verbose = 1;
static unsigned int debug = 0;
@@ -473,7 +467,7 @@ static struct i2c_client i2c_client_template = {
NULL
};
-static int init_bttv_i2c(struct bttv *btv)
+static int __init init_bttv_i2c(struct bttv *btv)
{
/* i2c bit_adapter */
memcpy(&btv->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter));
@@ -495,7 +489,7 @@ static int init_bttv_i2c(struct bttv *btv)
}
/* read I2C */
-static int I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
+static int __init I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
{
unsigned char buffer = 0;
@@ -520,7 +514,7 @@ static int I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
}
/* write I2C */
-static int I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
+static int __init I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
unsigned char b2, int both)
{
unsigned char buffer[2];
@@ -537,7 +531,7 @@ static int I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
}
/* read EEPROM */
-static void readee(struct bttv *btv, unsigned char *eedata, int addr)
+static void __init readee(struct bttv *btv, unsigned char *eedata, int addr)
{
int i;
@@ -564,7 +558,7 @@ static struct HAUPPAUGE_TUNER
int id;
char *name;
}
-hauppauge_tuner[] =
+hauppauge_tuner[] __initdata =
{
{ TUNER_ABSENT, "" },
{ TUNER_ABSENT, "External" },
@@ -612,8 +606,7 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "Temic 4046FM5" },
};
-static void
-hauppauge_eeprom(struct bttv *btv)
+static void __init hauppauge_eeprom(struct bttv *btv)
{
if (eeprom_data[9] < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER))
{
@@ -622,10 +615,11 @@ hauppauge_eeprom(struct bttv *btv)
printk("bttv%d: Hauppauge eeprom: tuner=%s (%d)\n",btv->nr,
hauppauge_tuner[eeprom_data[9]].name,btv->tuner_type);
}
+
+ return;
}
-static void
-hauppauge_boot_msp34xx(struct bttv *btv)
+static void __init hauppauge_boot_msp34xx(struct bttv *btv)
{
int i;
@@ -661,7 +655,7 @@ hauppauge_boot_msp34xx(struct bttv *btv)
/* This is basically the same procedure as
* used by Alessandro Rubini in his pxc200
* driver, but using BTTV functions */
-static void init_PXC200(struct bttv *btv)
+static void __init init_PXC200(struct bttv *btv)
{
static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
@@ -711,21 +705,25 @@ static struct CARD {
unsigned id;
int cardnr;
char *name;
-} cards[] = {
+} cards[] __initdata = {
{ 0x00011002, BTTV_HAUPPAUGE878, "ATI TV Wonder" },
- { 0x00031461, BTTV_AVERMEDIA98, "AVerMedia TVPhone98" },
+ { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
+ { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
+ { 0x00041461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
{ 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" },
{ 0x1118153b, BTTV_TERRATVALUE, "Terratec TV Value" },
+ { 0x1200bd11, BTTV_PINNACLERAVE, "Pinnacle PCTV Rave" },
{ 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" },
{ 0x14610002, BTTV_AVERMEDIA98, "Avermedia TVCapture 98" },
{ 0x18501851, BTTV_CHRONOS_VS2, "Chronos Video Shuttle II" },
{ 0x18521852, BTTV_TYPHOON_TVIEW, "Typhoon TView TV/FM Tuner" },
+ { 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" },
+ { 0x402010fc, 0 /* no tvcards entry yet */, "I-O Data Co. GV-BCV3/PCI" },
{ 0x6606217d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0x1200bd11, BTTV_PINNACLERAVE, "Pinnacle PCTV Rave" },
{ 0, -1, NULL }
};
@@ -747,6 +745,13 @@ struct tvcard
int tda9840:1;
int tda985x:1;
int tea63xx:1;
+ int tea64xx:1;
+ int tda7432:1;
+ int tda9875:1;
+
+ /* other settings */
+ int pll;
+ int tuner_type;
};
static struct tvcard tvcards[] =
@@ -754,149 +759,161 @@ static struct tvcard tvcards[] =
/* 0x00 */
{ " *** UNKNOWN *** ",
3, 1, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0},0,
- 1,1,1,1,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 },
+ 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 },
+ 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,1,1,1,1,0,0,1, PLL_NONE, -1 },
{ "Intel",
- 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4},0,
- 1,1,1,1,0 },
+ 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 },
+ 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 },
+ 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
{ "MATRIX-Vision MV-Delta",
5, 1, -1, 3, 0, { 2, 3, 1, 0, 0},{0 }, 0,
- 1,1,1,1,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 },
+ 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 },
+ 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 },
+ 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,
- 1,1,1,1,0 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
/* 0x10 */
{ "Pixelview PlayTV (bt878)",
- 3, 1, 0, 2, 0x01e000, { 2, 0, 1, 1},
+ 3, 1, 0, 2, 0x01fe00, { 2, 0, 1, 1},
{ 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },0,
- 1,1,1,1,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 },
+ 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 },
+ 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,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 },
+ 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
{ "Lucky Star Image World ConferenceTV",
- 3, 1, 0, 2, 16777215, { 2, 3, 1, 1}, { 131072, 1, 1638400, 3, 4},0,
- 1,1,1,1,0 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 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 },
+ 1,1,1,1,0,0,0,1, PLL_NONE, -1 },
{ "Terratec TerraTValue",
- 3, 1, 0, 2, 0xf00, { 2, 3, 1, 1}, { 0x500, 0, 0x300, 0x900, 0x900},0,
- 1,1,1,1,0 },
+ 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,0x620100,0x621100,0x620000,0xE210000,0x620000},0,
- 1,1,1,1,1 },
+ 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 },
+ 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 },
+ 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 },
+ { 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, 0, 1, 1},
- { 0x551400, 0x551200, 0, 0, 0x551200 }, 0,1,1,1,1,0 },
+ 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 },
-
+ 1,1,1,1,0,0,0,1, PLL_NONE, -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 },
};
#define TVCARDS (sizeof(tvcards)/sizeof(struct tvcard))
-static void
-dump_eeprom(struct bttv *btv,int addr)
+static void __init dump_eeprom(struct bttv *btv,int addr)
{
int i;
@@ -913,8 +930,7 @@ dump_eeprom(struct bttv *btv,int addr)
}
}
-static int
-idcard_eeprom(struct bttv *btv)
+static int __init idcard_eeprom(struct bttv *btv)
{
unsigned id;
int i,n;
@@ -1477,6 +1493,10 @@ static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int
unsigned char lmask, rmask, *p;
int W, l, r;
int i;
+
+ if (debug)
+ printk("bttv clip: %dx%d+%d+%d\n",w,h,x,y);
+
/* bitmap is fixed width, 128 bytes (1024 pixels represented) */
if (x<0)
{
@@ -1497,10 +1517,10 @@ static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int
w=1024-x;
l=x>>3;
- r=(x+w)>>3;
+ r=(x+w-1)>>3;
W=r-l-1;
lmask=lmaskt[x&7];
- rmask=rmaskt[(x+w)&7];
+ rmask=rmaskt[(x+w-1)&7];
p=clipmap+128*y+l;
if (W>0)
@@ -1716,8 +1736,7 @@ static void bt848_set_geo(struct bttv *btv,
struct tvnorm *tvn;
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&btv->s_lock, flags);
tvn=&tvnorms[btv->win.norm];
@@ -1771,7 +1790,7 @@ static void bt848_set_geo(struct bttv *btv,
btwrite(format, BT848_COLOR_FMT);
btwrite(bswap | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
- restore_flags(flags);
+ spin_unlock_irqrestore(&btv->s_lock, flags);
}
@@ -1835,6 +1854,7 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
{
unsigned int *ro, *re;
unsigned int *vbuf;
+ unsigned long flags;
if(btv->fbuffer==NULL)
{
@@ -1870,7 +1890,7 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
if (debug)
printk("bttv%d: cap vgrab: queue %d (%d:%dx%d)\n",
btv->nr,mp->frame,mp->format,mp->width,mp->height);
- cli();
+ 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;
@@ -1885,12 +1905,13 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
#endif
if (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;
- sti();
+ spin_unlock_irqrestore(&btv->s_lock, flags);
btor(3, BT848_CAP_CTL);
btor(3, BT848_GPIO_DMA_CTL);
return 0;
@@ -1911,23 +1932,25 @@ static long bttv_read(struct video_device *v, char *buf, unsigned long count, in
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
+ unsigned long flags;
+
if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
return -EFAULT;
todo-=q;
buf+=q;
- cli();
+ spin_lock_irqsave(&btv->s_lock, flags);
if (todo && q==VBIBUF_SIZE-btv->vbip)
{
if(nonblock)
{
- sti();
+ spin_unlock_irqrestore(&btv->s_lock, flags);
if(count==todo)
return -EWOULDBLOCK;
return count-todo;
}
+ spin_unlock_irqrestore(&btv->s_lock, flags);
interruptible_sleep_on(&btv->vbiq);
- sti();
if(signal_pending(current))
{
if(todo==count)
@@ -1935,7 +1958,8 @@ static long bttv_read(struct video_device *v, char *buf, unsigned long count, in
else
return count-todo;
}
- }
+ } else
+ spin_unlock_irqrestore(&btv->s_lock, flags);
}
if (todo)
{
@@ -1958,7 +1982,7 @@ static void bt848_restart(struct bttv *btv)
{
if (verbose)
printk("bttv%d: resetting chip\n",btv->nr);
- btwrite(0xfffffUL, BT848_INT_STAT);
+ btwrite(~0x0UL, BT848_INT_STAT);
btand(~15, BT848_GPIO_DMA_CTL);
btwrite(0, BT848_SRESET);
btwrite(virt_to_bus(btv->risc_jmp+2),
@@ -1984,6 +2008,8 @@ static int bttv_open(struct video_device *dev, int flags)
int i,ret;
ret = -EBUSY;
+
+ MOD_INC_USE_COUNT;
down(&btv->lock);
if (btv->user)
goto out_unlock;
@@ -2005,11 +2031,11 @@ static int bttv_open(struct video_device *dev, int flags)
set_pll(btv);
btv->user++;
up(&btv->lock);
- MOD_INC_USE_COUNT;
return 0;
out_unlock:
up(&btv->lock);
+ MOD_DEC_USE_COUNT;
return ret;
}
@@ -2033,14 +2059,15 @@ static void bttv_close(struct video_device *dev)
btread(BT848_I2C); /* This fixes the PCI posting delay */
- /*
- * 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 */
+ 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.
@@ -2726,6 +2753,8 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
+ unsigned long flags;
+
if (btv->needs_restart) {
down(&btv->lock);
bt848_restart(btv);
@@ -2736,18 +2765,18 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
todo-=q;
buf+=q;
- cli();
+ spin_lock_irqsave(&btv->s_lock, flags);
if (todo && q==VBIBUF_SIZE-btv->vbip)
{
if(nonblock)
{
- sti();
+ spin_unlock_irqrestore(&btv->s_lock, flags);
if(count==todo)
return -EWOULDBLOCK;
return count-todo;
}
+ spin_unlock_irqrestore(&btv->s_lock, flags);
interruptible_sleep_on(&btv->vbiq);
- sti();
if(signal_pending(current))
{
if(todo==count)
@@ -2755,7 +2784,8 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
else
return count-todo;
}
- }
+ } else
+ spin_unlock_irqrestore(&btv->s_lock, flags);
}
if (todo)
{
@@ -2784,6 +2814,8 @@ static int vbi_open(struct video_device *dev, int flags)
{
struct bttv *btv=(struct bttv *)(dev-2);
+ MOD_INC_USE_COUNT;
+
down(&btv->lock);
if (btv->needs_restart)
bt848_restart(btv);
@@ -2792,7 +2824,6 @@ static int vbi_open(struct video_device *dev, int flags)
bt848_set_risc_jmps(btv,-1);
up(&btv->lock);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2864,6 +2895,7 @@ 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;
@@ -2876,11 +2908,11 @@ static int radio_open(struct video_device *dev, int flags)
bt848_muxsel(btv,0);
up(&btv->lock);
- MOD_INC_USE_COUNT;
return 0;
busy_unlock:
up(&btv->lock);
+ MOD_DEC_USE_COUNT;
return -EBUSY;
}
@@ -2986,7 +3018,7 @@ static struct video_device radio_template=
#define TRITON_PEER_CONCURRENCY (1<<3)
-static void handle_chipset(void)
+static void __init handle_chipset(void)
{
struct pci_dev *dev = NULL;
@@ -3018,7 +3050,7 @@ static void handle_chipset(void)
/* can tda9855.c handle this too maybe? */
-static void init_tda9840(struct bttv *btv)
+static void __init init_tda9840(struct bttv *btv)
{
/* Horrible Hack */
I2CWrite(btv, I2C_TDA9840, TDA9840_SW, 0x2a, 1); /* sound mode switching */
@@ -3034,17 +3066,16 @@ static void init_tda9840(struct bttv *btv)
/* Figure out card and tuner type */
-static void idcard(int i)
+static void __init idcard(struct bttv *btv)
{
- struct bttv *btv = &bttvs[i];
int type,eeprom = 0;
btwrite(0, BT848_GPIO_OUT_EN);
- DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", i, btread(BT848_GPIO_DATA)));
+ DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", btv->nr, btread(BT848_GPIO_DATA)));
/* Default the card to the user-selected one. */
- if (card[i] >= 0 && card[i] < TVCARDS)
- btv->type=card[i];
+ if (card[btv->nr] >= 0 && card[btv->nr] < TVCARDS)
+ btv->type=card[btv->nr];
/* If we were asked to auto-detect, then do so! */
if (btv->type == BTTV_UNKNOWN) {
@@ -3063,7 +3094,7 @@ static void idcard(int i)
btv->type=BTTV_HAUPPAUGE;
}
- /* STB cards have a eeprom @ 0xae */
+ /* STB cards have a eeprom @ 0xae (old bt848) */
} else if (I2CRead(btv, I2C_STBEE, "eeprom")>=0) {
btv->type=BTTV_STB;
}
@@ -3078,20 +3109,20 @@ static void idcard(int i)
}
/* print which board we have found */
- printk(KERN_INFO "bttv%d: model: ",btv->nr);
-
sprintf(btv->video_dev.name,"BT%d%s(%.22s)",
btv->id,
(btv->id==848 && btv->revision==0x12) ? "A" : "",
tvcards[btv->type].name);
- printk("%s\n",btv->video_dev.name);
+ printk(KERN_INFO "bttv%d: model: %s\n",btv->nr,btv->video_dev.name);
+
/* 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 (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878) {
+ /* pick up some config infos from the eeprom */
if (0xa0 != eeprom) {
eeprom = 0xa0;
readee(btv,eeprom_data,0xa0);
@@ -3099,32 +3130,42 @@ static void idcard(int i)
hauppauge_eeprom(btv);
hauppauge_boot_msp34xx(btv);
}
- if (btv->type == BTTV_MAXI) {
- /* PHILIPS FI1216MK2 tuner (PAL/SECAM) */
- btv->tuner_type=TUNER_PHILIPS_SECAM;
- }
-
if (btv->type == BTTV_PXC200)
init_PXC200(btv);
-
- if (btv->type == BTTV_CONFERENCETV)
- btv->tuner_type = 1;
-
- if (btv->type == BTTV_HAUPPAUGE878 ||
- btv->type == BTTV_CONFERENCETV ||
- btv->type == BTTV_PIXVIEWPLAYTV ||
- btv->type == BTTV_AVERMEDIA98 ||
- btv->type == BTTV_MAGICTVIEW061 ||
- btv->type == BTTV_MAGICTVIEW063 ||
- btv->type == BTTV_CHRONOS_VS2 ||
- btv->type == BTTV_TYPHOON_TVIEW ||
- btv->type == BTTV_PXELVWPLTVPRO ||
- btv->type == BTTV_WINFAST2000) {
- btv->pll.pll_ifreq=28636363;
- btv->pll.pll_crystal=BT848_IFORM_XT0;
- }
- if (btv->tuner_type != -1)
+
+ /* pll configuration */
+ if (!(btv->id==848 && btv->revision==0x11)) {
+ /* defaults from card list */
+ if (PLL_28 == 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 != tvcards[btv->type].tuner_type)
+ btv->tuner_type = tvcards[btv->type].tuner_type;
+ if (btv->tuner_type != -1)
call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
/* try to detect audio/fader chips */
@@ -3154,12 +3195,28 @@ static void idcard(int i)
request_module("tda985x");
}
- if (tvcards[btv->type].tea63xx /* &&
- I2CRead(btv, I2C_TEA6300, "TEA63xx") >= 0 */) {
+ if (tvcards[btv->type].tda9875 &&
+ I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) {
+ if (autoload)
+ request_module("tda9875");
+ }
+
+ if (tvcards[btv->type].tda7432 &&
+ I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) {
+ if (autoload)
+ request_module("tda7432");
+ }
+
+ if (tvcards[btv->type].tea63xx) {
if (autoload)
request_module("tea6300");
}
+ if (tvcards[btv->type].tea64xx) {
+ if (autoload)
+ request_module("tea6420");
+ }
+
if (tvcards[btv->type].tuner != -1) {
if (autoload)
request_module("tuner");
@@ -3171,6 +3228,10 @@ static void idcard(int i)
static void bt848_set_risc_jmps(struct bttv *btv, int flags)
{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
+
if (-1 == flags) {
/* defaults */
flags = 0;
@@ -3242,7 +3303,11 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags)
btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12));
}
- btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP);
+ 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 */
@@ -3253,18 +3318,17 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags)
bt848_dma(btv, 3);
else
bt848_dma(btv, 0);
+
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
-static int
-init_video_dev(struct bttv *btv)
+static int __init init_video_dev(struct bttv *btv)
{
- int num = btv - bttvs;
-
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));
- idcard(num);
+ idcard(btv);
if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER)<0)
return -1;
@@ -3273,7 +3337,7 @@ init_video_dev(struct bttv *btv)
video_unregister_device(&btv->video_dev);
return -1;
}
- if (radio[num])
+ if (radio[btv->nr])
{
if(video_register_device(&btv->radio_dev, VFL_TYPE_RADIO)<0)
{
@@ -3285,9 +3349,8 @@ init_video_dev(struct bttv *btv)
return 1;
}
-static int init_bt848(int i)
+static int __init init_bt848(struct bttv *btv)
{
- struct bttv *btv = &bttvs[i];
int j;
btv->user=0;
@@ -3297,14 +3360,14 @@ static int init_bt848(int i)
* might help to make a new card work */
if (verbose >= 2)
printk("bttv%d: gpio: out_enable=0x%x, data=0x%x, in=0x%x\n",
- i,
+ 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",i,(unsigned long) btv->bt848_mem));
+ 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;
@@ -3412,7 +3475,7 @@ static int init_bt848(int i)
btwrite(0x00, BT848_O_SCLOOP);
/* clear interrupt status */
- btwrite(0xfffffUL, BT848_INT_STAT);
+ btwrite(~0x0UL, BT848_INT_STAT);
/* set interrupt mask */
btwrite(btv->triton1|
@@ -3452,7 +3515,6 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
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));
@@ -3561,6 +3623,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
}
if (stat&(8<<28))
{
+ btv->gq_start = 0;
btv->gq_grab = btv->gqueue[btv->gq_out++];
btv->gq_out = btv->gq_out % MAX_GBUFFERS;
if (debug)
@@ -3613,7 +3676,9 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
{
IDEBUG(printk ("bttv%d: IRQ_I2CDONE\n", btv->nr));
}
-
+
+ btwrite(astat,BT848_INT_STAT);
+
count++;
if (count > 10)
printk (KERN_WARNING "bttv%d: irq loop %d\n",
@@ -3633,7 +3698,76 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
* Scan for a Bt848 card, request the irq and map the io memory
*/
-int configure_bt848(struct pci_dev *dev, int bttv_num)
+static void __init bttv_remove(struct pci_dev *pci_dev)
+{
+ u8 command;
+ int j;
+ struct bttv *btv = pci_dev->driver_data;
+
+ /* unregister i2c_bus */
+ 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 __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
{
int result;
unsigned char command;
@@ -3642,6 +3776,8 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
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;
@@ -3657,15 +3793,15 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
btv->vbip=VBIBUF_SIZE;
init_waitqueue_head(&btv->gpioq);
+ btv->s_lock = SPIN_LOCK_UNLOCKED;
btv->shutdown=0;
btv->id=dev->device;
btv->irq=dev->irq;
- btv->bt848_adr=pci_resource_start(dev, 0);
-
+ btv->bt848_adr=pci_resource_start(dev, 0);
if (pci_enable_device(dev))
return -EIO;
- if (!request_mem_region(pci_resource_start(dev,0),
+ if (!request_mem_region(btv->bt848_adr,
pci_resource_len(dev,0),
"bttv")) {
return -EBUSY;
@@ -3689,29 +3825,7 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
cmd = (cmd | PCI_COMMAND_MEMORY );
pci_write_config_dword(dev, PCI_COMMAND, cmd);
#endif
-
- btv->pll.pll_crystal = 0;
- btv->pll.pll_ifreq = 0;
- btv->pll.pll_ofreq = 0;
- btv->pll.pll_current = 0;
- if (!(btv->id==848 && btv->revision==0x11)) {
- switch (pll[btv->nr]) {
- case 0:
- /* off */
- break;
- case 1:
- /* 28 MHz crystal installed */
- btv->pll.pll_ifreq=28636363;
- btv->pll.pll_crystal=BT848_IFORM_XT0;
- break;
- case 2:
- /* 35 MHz crystal installed */
- btv->pll.pll_ifreq=35468950;
- btv->pll.pll_crystal=BT848_IFORM_XT1;
- break;
- }
- }
-
+
#ifdef __sparc__
btv->bt848_mem=(unsigned char *)btv->bt848_adr;
#else
@@ -3751,119 +3865,53 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
if (!(command&BT878_EN_TBFX))
{
printk("bttv: 430FX compatibility could not be enabled\n");
+ free_irq(btv->irq,btv);
result = -1;
goto fail;
}
}
+
+ dev->driver_data = 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),
+ release_mem_region(btv->bt848_adr,
pci_resource_len(btv->dev,0));
return result;
}
-static int find_bt848(void)
-{
- struct pci_dev *dev;
- int result=0;
-
- bttv_num=0;
-
- pci_for_each_dev(dev) {
- if (dev->vendor == PCI_VENDOR_ID_BROOKTREE)
- if ((dev->device == PCI_DEVICE_ID_BT848)||
- (dev->device == PCI_DEVICE_ID_BT849)||
- (dev->device == PCI_DEVICE_ID_BT878)||
- (dev->device == PCI_DEVICE_ID_BT879))
- result=configure_bt848(dev,bttv_num++);
- if (result)
- return result;
- }
- if(bttv_num)
- printk(KERN_INFO "bttv: %d Bt8xx card(s) found.\n", bttv_num);
- return bttv_num;
-}
-
-static void release_bttv(void)
-{
- u8 command;
- int i,j;
- struct bttv *btv;
-
- for (i=0;i<bttv_num; i++)
- {
- btv=&bttvs[i];
-
- /* unregister i2c_bus */
- 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(0xffffffffUL,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);
+static struct pci_device_id bttv_pci_tbl[] __initdata = {
+ {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,}
+};
- 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);
+MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
- release_mem_region(pci_resource_start(btv->dev,0),
- 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);
- }
-}
+static struct pci_driver bttv_pci_driver = {
+ name:"bttv",
+ id_table:bttv_pci_tbl,
+ probe:bttv_probe,
+ remove:bttv_remove,
+};
-#ifdef MODULE
-int init_module(void)
-#else
-int init_bttv_cards(struct video_init *unused)
-#endif
+static int __init bttv_init_module(void)
{
- int i;
+ bttv_num = 0;
printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
(BTTV_VERSION_CODE >> 16) & 0xff,
@@ -3878,31 +3926,18 @@ int init_bttv_cards(struct video_init *unused)
gbuffers,gbufsize/1024,gbuffers*gbufsize/1024);
handle_chipset();
- if (find_bt848()<=0)
- return -EIO;
- /* initialize Bt848s */
- for (i=0; i<bttv_num; i++)
- {
- if (init_bt848(i)<0)
- {
- release_bttv();
- return -EIO;
- }
- }
-
- return 0;
+ return pci_module_init(&bttv_pci_driver);
}
-
-#ifdef MODULE
-
-void cleanup_module(void)
+static void __exit bttv_cleanup_module(void)
{
- release_bttv();
+ pci_unregister_driver(&bttv_pci_driver);
+ return;
}
-#endif
+module_init(bttv_init_module);
+module_exit(bttv_cleanup_module);
/*
* Local variables:
diff --git a/drivers/char/bttv.h b/drivers/char/bttv.h
index be929c6c9..3f4229fe8 100644
--- a/drivers/char/bttv.h
+++ b/drivers/char/bttv.h
@@ -1,4 +1,4 @@
-/*
+/*
bttv - Bt848 frame grabber driver
Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
@@ -21,7 +21,7 @@
#ifndef _BTTV_H_
#define _BTTV_H_
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,25)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,28)
#include <linux/types.h>
#include <linux/wait.h>
@@ -143,6 +143,8 @@ struct bttv {
int tuner_type;
int channel;
+
+ spinlock_t s_lock;
unsigned int nr;
unsigned short id;
@@ -183,7 +185,7 @@ struct bttv {
struct bttv_gbuf *gbuf;
int gqueue[MAX_GBUFFERS];
- int gq_in,gq_out,gq_grab;
+ int gq_in,gq_out,gq_grab,gq_start;
char *fbuffer;
struct bttv_pll_info pll;
@@ -272,7 +274,13 @@ extern __inline__ void io_st_le32(volatile unsigned *addr, unsigned val)
#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 PLL_NONE 0
+#define PLL_28 1
+#define PLL_35 2
#define AUDIO_TUNER 0x00
#define AUDIO_RADIO 0x01
@@ -289,9 +297,11 @@ extern __inline__ void io_st_le32(volatile unsigned *addr, unsigned val)
#define TEA6300 0x04
#define I2C_TSA5522 0xc2
+#define I2C_TDA7432 0x8a
+#define I2C_TDA8425 0x82
#define I2C_TDA9840 0x84
#define I2C_TDA9850 0xb6
-#define I2C_TDA8425 0x82
+#define I2C_TDA9875 0xb0
#define I2C_HAUPEE 0xa0
#define I2C_STBEE 0xae
#define I2C_VHX 0xc0
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index dd94223bc..9238ae3eb 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -4080,9 +4080,10 @@ static struct pci_device_id epca_pci_tbl[] __initdata = {
{ PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem },
{ PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx },
{ PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj },
- { 0, }, /* terminate list */
+ { 0, }
};
+MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
int __init init_PCI (void)
{ /* Begin init_PCI */
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 212525df7..dfe89b970 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -52,6 +52,10 @@ int gs_debug = 0;
#define RS_EVENT_WRITE_WAKEUP 1
+#ifdef MODULE
+MODULE_PARM(gs_debug, "i");
+#endif
+
#ifdef DEBUG
static void my_hd (unsigned char *addr, int len)
{
@@ -209,12 +213,9 @@ int gs_write(struct tty_struct * tty, int from_user,
if (!port || !port->xmit_buf || !tmp_buf)
return -EIO;
- /* printk ("from_user = %d.\n", from_user); */
save_flags(flags);
if (from_user) {
- /* printk ("Going into the semaphore\n"); */
down(&tmp_buf_sem);
- /* printk ("got out of the semaphore\n"); */
while (1) {
c = count;
@@ -363,19 +364,14 @@ static int gs_wait_tx_flushed (void * ptr, int timeout)
func_exit();
return -EINVAL; /* This is an error which we don't know how to handle. */
}
- gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 1\n");
rcib = gs_real_chars_in_buffer(port->tty);
- gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 2\n");
-
if(rcib <= 0) {
gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
func_exit();
return rv;
}
- gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 3\n");
-
/* stop trying: now + twice the time it would normally take + seconds */
end_jiffies = jiffies;
if (timeout != MAX_SCHEDULE_TIMEOUT)
@@ -520,11 +516,10 @@ void gs_hangup(struct tty_struct *tty)
func_enter ();
tty = port->tty;
- if (!tty) return;
+ if (!tty)
+ return;
gs_shutdown_port (port);
-
- /* gs_flush_buffer (tty); */
port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE |GS_ACTIVE);
port->tty = NULL;
port->count = 0;
@@ -576,7 +571,6 @@ int block_til_ready(void *port_, struct file * filp)
else
return -ERESTARTSYS;
}
-
gs_dprintk (GS_DEBUG_BTR, "after hung up\n");
/*
@@ -599,7 +593,6 @@ 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.
@@ -613,7 +606,6 @@ 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;
@@ -622,8 +614,7 @@ int block_til_ready(void *port_, struct file * filp)
do_clocal = 1;
}
- gs_dprintk (GS_DEBUG_BTR, "after clocal check.\n");
-
+ 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
@@ -632,10 +623,10 @@ 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))
port->count--;
@@ -667,7 +658,7 @@ int block_til_ready(void *port_, struct file * filp)
}
gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n",
port->blocked_open);
- current->state = TASK_RUNNING;
+ set_current_state (TASK_RUNNING);
remove_wait_queue(&port->open_wait, &wait);
if (!tty_hung_up_p(filp))
port->count++;
@@ -687,10 +678,8 @@ void gs_close(struct tty_struct * tty, struct file * filp)
struct gs_port *port;
func_enter ();
- port = (struct gs_port *) tty->driver_data;
- gs_dprintk (GS_DEBUG_CLOSE, "tty=%p, port=%p port->tty=%p\n",
- tty, port, port->tty);
+ port = (struct gs_port *) tty->driver_data;
if(! port) {
func_exit();
@@ -703,9 +692,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
port->tty = tty;
}
-
save_flags(flags); cli();
-
if (tty_hung_up_p(filp)) {
restore_flags(flags);
port->rd->hungup (port);
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index fcf0644ff..90f034396 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -146,13 +146,6 @@ struct lp_struct lp_table[LP_NO];
static unsigned int lp_count = 0;
-/* Test if printer is ready */
-#define LP_READY(status) ((status) & LP_PBUSY)
-/* Test if the printer is not acking the strobe */
-#define LP_NO_ACKING(status) ((status) & LP_PACK)
-/* Test if the printer has error conditions */
-#define LP_NO_ERROR(status) ((status) & LP_PERRORP)
-
#undef LP_DEBUG
/* --- low-level port access ----------------------------------- */
@@ -265,6 +258,7 @@ static ssize_t lp_write(struct file * file, const char * buf,
parport_set_timeout (lp_table[minor].dev,
lp_table[minor].timeout);
+ if ((retv = lp_check_status (minor)) == 0)
do {
/* Write the data. */
written = parport_write (port, kbuf, copy_size);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 755c3b318..40e6c7ba6 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -231,9 +231,10 @@ static ssize_t read_kmem(struct file *file, char *buf,
{
unsigned long p = *ppos;
ssize_t read = 0;
- ssize_t virtr;
+ ssize_t virtr = 0;
+ char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
- if (p < (unsigned long) high_memory) {
+ if (p < (unsigned long) high_memory) {
read = count;
if (count > (unsigned long) high_memory - p)
read = (unsigned long) high_memory - p;
@@ -258,11 +259,27 @@ static ssize_t read_kmem(struct file *file, char *buf,
count -= read;
}
- virtr = vread(buf, (char *)p, count);
- if (virtr < 0)
- return virtr;
- *ppos += p + virtr;
- return virtr + read;
+ kbuf = (char *)__get_free_page(GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+ len = vread(kbuf, (char *)p, len);
+ if (len && copy_to_user(buf, kbuf, len)) {
+ free_page((unsigned long)kbuf);
+ return -EFAULT;
+ }
+ count -= len;
+ buf += len;
+ virtr += len;
+ p += len;
+ }
+ free_page((unsigned long)kbuf);
+ *ppos = p;
+ return virtr + read;
}
/*
diff --git a/drivers/char/msp3400.c b/drivers/char/msp3400.c
index 6b86db95b..f4252a071 100644
--- a/drivers/char/msp3400.c
+++ b/drivers/char/msp3400.c
@@ -871,7 +871,7 @@ static int msp3400c_thread(void *data)
/* unmute */
msp3400c_setvolume(client, msp->left, msp->right);
- if (msp->watch_stereo)
+ if (msp->watch_stereo)
mod_timer(&msp->wake_stereo, jiffies+5*HZ);
if (debug)
@@ -1086,7 +1086,7 @@ static int msp3410d_thread(void *data)
msp3400c_settreble(client, msp->treble);
msp3400c_setvolume(client, msp->left, msp->right);
- if (msp->watch_stereo)
+ if (msp->watch_stereo)
mod_timer(&msp->wake_stereo, jiffies+HZ);
msp->active = 0;
@@ -1236,7 +1236,7 @@ static int
msp3400c_mixer_open(struct inode *inode, struct file *file)
{
int minor = MINOR(inode->i_rdev);
- struct i2c_client *client = NULL;
+ struct i2c_client *client;
struct msp3400c *msp;
int i;
@@ -1246,12 +1246,12 @@ msp3400c_mixer_open(struct inode *inode, struct file *file)
if (msp->mixer_num == minor) {
client = msps[i];
file->private_data = client;
- goto match;
+ break;
}
}
- return -ENODEV;
+ if (MSP3400_MAX == i)
+ return -ENODEV;
-match:
/* lock bttv in memory while the mixer is in use */
if (client->adapter->inc_use)
client->adapter->inc_use(client->adapter);
@@ -1265,8 +1265,8 @@ msp3400c_mixer_release(struct inode *inode, struct file *file)
{
struct i2c_client *client = file->private_data;
- if (client->adapter->inc_use)
- client->adapter->inc_use(client->adapter);
+ if (client->adapter->dec_use)
+ client->adapter->dec_use(client->adapter);
MOD_DEC_USE_COUNT;
return 0;
}
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
index f51eeb0bb..3cf72f3e4 100644
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -168,4 +168,6 @@ extern int rio_minor (kdev_t device);
extern int rio_ismodem (kdev_t device);
extern void rio_udelay (int usecs);
+extern void rio_start_card_running (struct Host * HostP);
+
#endif /* __func_h_def */
diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h
index 6a155c1a6..12c47eae2 100644
--- a/drivers/char/rio/host.h
+++ b/drivers/char/rio/host.h
@@ -56,16 +56,16 @@ struct Host
uchar Mode; /* Control stuff */
uchar Slot; /* Slot */
volatile caddr_t Caddr; /* KV address of DPRAM */
- volatile struct DpRam *CardP; /* KV address of DPRAM, with overlay */
+ volatile struct DpRam *CardP; /* KV address of DPRAM, with overlay */
paddr_t PaddrP; /* Phys. address of DPRAM */
char Name[MAX_NAME_LEN]; /* The name of the host */
uint UniqueNum; /* host unique number */
- spinlock_t HostLock; /* Lock structure for MPX */
- /*struct pci_devinfo PciDevInfo; *//* PCI Bus/Device/Function stuff */
+ spinlock_t HostLock; /* Lock structure for MPX */
+ /*struct pci_devinfo PciDevInfo; *//* PCI Bus/Device/Function stuff */
/*struct lockb HostLock; *//* Lock structure for MPX */
uint WorkToBeDone; /* set to true each interrupt */
uint InIntr; /* Being serviced? */
- uint IntSrvDone; /* host's interrupt has been serviced */
+ uint IntSrvDone;/* host's interrupt has been serviced */
int (*Copy)( caddr_t, caddr_t, int ); /* copy func */
struct timer_list timer;
/*
diff --git a/drivers/char/rio/linux_compat.h b/drivers/char/rio/linux_compat.h
index 5a4ae63c1..3b6d2f3b1 100644
--- a/drivers/char/rio/linux_compat.h
+++ b/drivers/char/rio/linux_compat.h
@@ -47,7 +47,6 @@ struct ttystatics {
#define SEM_SIGIGNORE 0x1234
-
#ifdef DEBUG_SEM
#define swait(a,b) printk ("waiting: " __FILE__ " line %d\n", __LINE__)
#define ssignal(sem) printk ("signalling: " __FILE__ " line %d\n", __LINE__)
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 0adc6efed..625f7022b 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -109,108 +109,6 @@ of boards in rio.h. You'll have to allocate more majors if you need
more than 512 ports.... */
-/* ************************************************************** */
-/* * This section can be removed when 2.0 becomes outdated.... * */
-/* ************************************************************** */
-
-#if LINUX_VERSION_CODE < 0x020100 /* Less than 2.1.0 */
-#define TWO_ZERO
-#else
-#if LINUX_VERSION_CODE < 0x020209 /* less than 2.2.x */
-#warning "Please use a recent 2.2.x kernel. "
-#endif
-#endif
-
-
-#ifdef TWO_ZERO
-
-/* Here is the section that makes the 2.2 compatible driver source
- work for 2.0 too! We mostly try to adopt the "new thingies" from 2.2,
- and provide for compatibility stuff here if possible. */
-
-#include <linux/bios32.h>
-
-#define Get_user(a,b) a = get_user(b)
-#define Put_user(a,b) 0,put_user(a,b)
-#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
-
-static inline int copy_from_user(void *to,const void *from, int c)
-{
- memcpy_fromfs(to, from, c);
- return 0;
-}
-
-#define pci_present pcibios_present
-#define pci_read_config_word pcibios_read_config_word
-#define pci_read_config_dword pcibios_read_config_dword
-
-static inline unsigned char get_irq (unsigned char bus, unsigned char fn)
-{
- unsigned char t;
- pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &t);
- return t;
-}
-
-static inline void *ioremap(unsigned long base, long length)
-{
- if (base < 0x100000) return (void *)base;
- return vremap (base, length);
-}
-
-#define my_iounmap(x, b) (((long)x<0x100000)?0:vfree ((void*)x))
-
-#define capable(x) suser()
-
-#define queue_task queue_task_irq_off
-#define tty_flip_buffer_push(tty) queue_task(&tty->flip.tqueue, &tq_timer)
-#define signal_pending(current) (current->signal & ~current->blocked)
-#define schedule_timeout(to) do {current->timeout = jiffies + (to);schedule ();} while (0)
-#define time_after(t1,t2) (((long)t1-t2) > 0)
-
-
-#define test_and_set_bit(nr, addr) set_bit(nr, addr)
-#define test_and_clear_bit(nr, addr) clear_bit(nr, addr)
-
-/* Not yet implemented on 2.0 */
-#define ASYNC_SPD_SHI -1
-#define ASYNC_SPD_WARP -1
-
-
-/* Ugly hack: the driver_name doesn't exist in 2.0.x . So we define it
- to the "name" field that does exist. As long as the assignments are
- done in the right order, there is nothing to worry about. */
-#define driver_name name
-
-/* Should be in a header somewhere. They are in tty.h on 2.2 */
-#define TTY_HW_COOK_OUT 14 /* Flag to tell ntty what we can handle */
-#define TTY_HW_COOK_IN 15 /* in hardware - output and input */
-
-/* The return type of a "close" routine. */
-#define INT void
-#define NO_ERROR /* Nothing */
-
-#else
-
-/* The 2.2.x compatibility section. */
-#include <asm/uaccess.h>
-
-#define Get_user(a,b) get_user(a,b)
-#define Put_user(a,b) put_user(a,b)
-#define get_irq(pdev) pdev->irq
-
-#define INT int
-#define NO_ERROR 0
-
-#define my_iounmap(x,b) (iounmap((char *)(b)))
-
-#endif
-
-/* ************************************************************** */
-/* * End of compatibility section.. * */
-/* ************************************************************** */
-
-
-
/* Why the hell am I defining these here? */
#define RIO_TYPE_NORMAL 1
#define RIO_TYPE_CALLOUT 2
@@ -373,55 +271,15 @@ static struct real_driver rio_real_driver = {
NULL
};
-
-/*
- This driver can spew a whole lot of debugging output at you. If you
- need maximum performance, you should disable the DEBUG define. To
- aid in debugging in the field, I'm leaving the compile-time debug
- features enabled, and disable them "runtime". That allows me to
- instruct people with problems to enable debugging without requiring
- them to recompile...
-*/
-#define DEBUG
-
-#ifdef DEBUG
-#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
-#else
-#define rio_dprintk(f, str...) /* nothing */
-#endif
-
-
-#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__ \
- "(port %d)\n", port->line)
-
-
-
-
/*
* Firmware loader driver specific routines
*
*/
static struct file_operations rio_fw_fops = {
- NULL, /* lseek */
- NULL, /* read */
- NULL, /* write */
- NULL, /* readdir */
- NULL, /* select */
- rio_fw_ioctl,
- NULL, /* mmap */
- rio_fw_open,
-#ifndef TWO_ZERO
- NULL, /* flush */
-#endif
- rio_fw_release,
- NULL, /* fsync */
- NULL, /* fasync */
- NULL, /* check_media_change */
- NULL, /* revalidate */
+ ioctl: rio_fw_ioctl,
+ open: rio_fw_open,
+ release: rio_fw_release,
};
struct miscdevice rio_fw_device = {
@@ -446,11 +304,11 @@ static inline int rio_paranoia_check(struct rio_port const * port,
KERN_ERR "rio: Warning: null rio port for device %s in %s\n";
if (!port) {
- printk(badinfo, kdevname(device), routine);
+ printk (badinfo, kdevname(device), routine);
return 1;
}
if (port->magic != RIO_MAGIC) {
- printk(badmagic, kdevname(device), routine);
+ printk (badmagic, kdevname(device), routine);
return 1;
}
@@ -468,15 +326,15 @@ void my_hd (void *ad, int len)
unsigned char *addr = ad;
for (i=0;i<len;i+=16) {
- printk ("%08x ", (int) addr+i);
+ rio_dprintk (RIO_DEBUG_PARAM, "%08x ", (int) addr+i);
for (j=0;j<16;j++) {
- printk ("%02x %s", addr[j+i], (j==7)?" ":"");
+ rio_dprintk (RIO_DEBUG_PARAM, "%02x %s", addr[j+i], (j==7)?" ":"");
}
for (j=0;j<16;j++) {
ch = addr[j+i];
- printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
+ rio_dprintk (RIO_DEBUG_PARAM, "%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
}
- printk ("\n");
+ rio_dprintk (RIO_DEBUG_PARAM, "\n");
}
}
#else
@@ -568,21 +426,26 @@ static int rio_set_real_termios (void *ptr)
void rio_reset_interrupt (struct Host *HostP)
{
+ func_enter();
+
switch( HostP->Type ) {
case RIO_AT:
case RIO_MCA:
case RIO_PCI:
WBYTE(HostP->ResetInt , 0xff);
}
+
+ func_exit();
}
static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
{
struct Host *HostP;
+ func_enter ();
- HostP = &p->RIOHosts[(long)ptr];
- /* func_enter (); */
+ HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */
+
rio_dprintk (RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n",
irq, HostP->Ivec);
@@ -627,7 +490,7 @@ static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
}
}
#endif
-
+ rio_dprintk (RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n");
if (HostP->Ivec == irq) {
/* Tell the card we've noticed the interrupt. */
rio_reset_interrupt (HostP);
@@ -649,7 +512,7 @@ static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks);
rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n",
irq, HostP->Ivec);
- /* func_exit (); */
+ func_exit ();
}
@@ -657,7 +520,7 @@ static void rio_pollfunc (unsigned long data)
{
func_enter ();
- rio_interrupt (0, (void *)data, NULL);
+ rio_interrupt (0, &p->RIOHosts[data], NULL);
p->RIOHosts[data].timer.expires = jiffies + rio_poll;
add_timer (&p->RIOHosts[data].timer);
@@ -756,11 +619,11 @@ static void rio_shutdown_port (void * ptr)
#if 0
port->gs.flags &= ~ GS_ACTIVE;
if (!port->gs.tty) {
- printk ("No tty.\n");
+ rio_dprintk (RIO_DBUG_TTY, "No tty.\n");
return;
}
if (!port->gs.tty->termios) {
- printk ("No termios.\n");
+ rio_dprintk (RIO_DEBUG_TTY, "No termios.\n");
return;
}
if (port->gs.tty->termios->c_cflag & HUPCL) {
@@ -1000,6 +863,8 @@ struct vpd_prom *get_VPD_PROM (struct Host *hp)
if (rio_debug & RIO_DEBUG_PROBE)
my_hd ((char *)&vpdp, 0x20);
+
+ func_exit();
return &vpdp;
}
@@ -1099,7 +964,7 @@ static int rio_init_datastructures (void)
/* However, the RIO driver allows users to configure their first
RTA as the ports numbered 504-511. We therefore need to allocate
the whole range. :-( -- REW */
-
+
#define RI_SZ sizeof(struct rio_info)
#define HOST_SZ sizeof(struct Host)
#define PORT_SZ sizeof(struct Port *)
@@ -1138,11 +1003,20 @@ static int rio_init_datastructures (void)
port->gs.close_delay = HZ/2;
port->gs.closing_wait = 30 * HZ;
port->gs.rd = &rio_real_driver;
+
+ /*
+ * Initializing wait queue
+ */
+ init_waitqueue_head(&port->gs.open_wait);
+ init_waitqueue_head(&port->gs.close_wait);
+
}
#else
/* We could postpone initializing them to when they are configured. */
#endif
+
+
if (rio_debug & RIO_DEBUG_INIT) {
my_hd (&rio_real_driver, sizeof (rio_real_driver));
}
@@ -1166,7 +1040,6 @@ static int rio_init_datastructures (void)
}
-#ifdef MODULE
static void rio_release_drivers(void)
{
func_enter();
@@ -1176,7 +1049,6 @@ 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
@@ -1213,7 +1085,7 @@ void fix_rio_pci (PDEV)
unsigned int t;
#define CNTRL_REG_OFFSET 0x50
-#define CNTRL_REG_GOODVALUE 0x00260000
+#define CNTRL_REG_GOODVALUE 0x18260000
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
@@ -1294,7 +1166,6 @@ int rio_init(void)
pci_read_config_dword (pdev, 0x2c, &tint);
tshort = (tint >> 16) & 0xffff;
rio_dprintk (RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
- /* rio_dprintk (RIO_DEBUG_PROBE, "pdev = %d/%d (%x)\n", pdev, tint); */
if (tshort != 0x0100) {
rio_dprintk (RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n",
tshort);
@@ -1307,49 +1178,51 @@ int rio_init(void)
hp = &p->RIOHosts[p->RIONumHosts];
hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK;
hp->Ivec = get_irq (pdev);
- if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+ if (((1 << hp->Ivec) & rio_irqmask) == 0)
+ hp->Ivec = 0;
hp->CardP = (struct DpRam *)
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
hp->Type = RIO_PCI;
hp->Copy = rio_pcicopy;
- hp->Mode = RIO_PCI_DEFAULT_MODE;
-
+ hp->Mode = RIO_PCI_BOOT_FROM_RAM;
+ rio_reset_interrupt (hp);
+ rio_start_card_running (hp);
+
rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
(void *)p->RIOHosts[p->RIONumHosts].PaddrP,
p->RIOHosts[p->RIONumHosts].Caddr);
if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
p->RIOHosts[p->RIONumHosts].Caddr,
RIO_PCI, 0 ) == RIO_SUCCESS) {
- WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
- p->RIOHosts[p->RIONumHosts].UniqueNum =
- ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
- ((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_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
- p->RIOHosts[p->RIONumHosts].UniqueNum);
-
-#if 1
- fix_rio_pci (pdev);
-#endif
- p->RIOLastPCISearch = RIO_SUCCESS;
- p->RIONumHosts++;
- found++;
+ rio_dprintk (RIO_DEBUG_INIT, "Done RIOBoardTest\n");
+ WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
+ p->RIOHosts[p->RIONumHosts].UniqueNum =
+ ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
+ ((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_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
+ p->RIOHosts[p->RIONumHosts].UniqueNum);
+
+ fix_rio_pci (pdev);
+ p->RIOLastPCISearch = RIO_SUCCESS;
+ p->RIONumHosts++;
+ found++;
} else {
- my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP,
- p->RIOHosts[p->RIONumHosts].Caddr);
+ my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP,
+ p->RIOHosts[p->RIONumHosts].Caddr);
}
-
+
#ifdef TWO_ZERO
} /* We have two variants with the opening brace, so to prevent */
#else
} /* Emacs from getting confused we have two closing braces too. */
#endif
-
/* Then look for the older PCI card.... : */
#ifndef TWO_ZERO
+
/* These older PCI cards have problems (only byte-mode access is
supported), which makes them a bit awkward to support.
They also have problems sharing interrupts. Be careful.
@@ -1374,15 +1247,21 @@ int rio_init(void)
hp = &p->RIOHosts[p->RIONumHosts];
hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK;
hp->Ivec = get_irq (pdev);
- if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+ if (((1 << hp->Ivec) & rio_irqmask) == 0)
+ hp->Ivec = 0;
hp->Ivec |= 0x8000; /* Mark as non-sharable */
hp->CardP = (struct DpRam *)
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
hp->Type = RIO_PCI;
hp->Copy = rio_pcicopy;
- hp->Mode = RIO_PCI_DEFAULT_MODE;
-
- rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
+ hp->Mode = RIO_PCI_BOOT_FROM_RAM;
+
+ rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec);
+ rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode);
+
+ rio_reset_interrupt (hp);
+ rio_start_card_running (hp);
+ rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
(void *)p->RIOHosts[p->RIONumHosts].PaddrP,
p->RIOHosts[p->RIONumHosts].Caddr);
if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
@@ -1425,11 +1304,15 @@ int rio_init(void)
hp->CardP = (struct DpRam *)
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
hp->Type = RIO_AT;
- hp->Copy = rio_pcicopy;
+ hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL
+ * -- YES! this is now a normal copy. Only the
+ * old PCI card uses the special PCI copy.
+ * Moreover, the ISA card will work with the
+ * special PCI copy anyway. -- REW */
hp->Mode = 0;
vpdp = get_VPD_PROM (hp);
-
+ rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n");
okboard = 0;
if ((strncmp (vpdp->identifier, RIO_ISA_IDENT, 16) == 0) ||
(strncmp (vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) ||
@@ -1460,11 +1343,21 @@ int rio_init(void)
if (hp->Ivec) {
int mode = SA_SHIRQ;
if (hp->Ivec & 0x8000) {mode = 0; hp->Ivec &= 0x7fff;}
- if (request_irq (hp->Ivec, rio_interrupt, mode, "rio", (void *)i)) {
- printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
- hp->Ivec = 0;
+ rio_dprintk (RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp,hp->Ivec, hp->Mode);
+ retval = request_irq (hp->Ivec, rio_interrupt, mode, "rio", hp);
+ rio_dprintk (RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval);
+ if (retval) {
+ printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
+ hp->Ivec = 0;
}
rio_dprintk (RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec);
+ if (hp->Ivec != 0){
+ rio_dprintk (RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n");
+ hp->Mode |= RIO_PCI_INT_ENABLE;
+ } else
+ hp->Mode &= !RIO_PCI_INT_ENABLE;
+ rio_dprintk (RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode);
+ rio_start_card_running (hp);
}
/* Init the timer "always" to make sure that it can safely be
deleted when we unload... */
@@ -1481,7 +1374,7 @@ int rio_init(void)
}
if (found) {
- printk (KERN_INFO "rio: total of %d boards detected.\n", found);
+ rio_dprintk (RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found);
if (misc_register(&rio_fw_device) < 0) {
printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n");
@@ -1506,7 +1399,7 @@ void cleanup_module(void)
for (i=0,hp=p->RIOHosts;i<p->RIONumHosts;i++, hp++) {
RIOHostReset (hp->Type, hp->CardP, hp->Slot);
if (hp->Ivec) {
- free_irq (hp->Ivec, (void *)i);
+ free_irq (hp->Ivec, hp);
rio_dprintk (RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec);
}
/* It is safe/allowed to del_timer a non-active timer */
diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h
index 5141355ea..c8b72bdce 100644
--- a/drivers/char/rio/rio_linux.h
+++ b/drivers/char/rio/rio_linux.h
@@ -23,13 +23,13 @@
* Version 1.0 -- July, 1999.
*
*/
+#include <linux/config.h>
#define RIO_NBOARDS 4
#define RIO_PORTSPERBOARD 128
#define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD)
#ifdef __KERNEL__
-#include <linux/config.h>
#define RIO_MAGIC 0x12345678
@@ -160,3 +160,28 @@ static inline void *rio_memcpy_fromio (void *dest, void *source, int n)
#define rio_memcpy_fromio memcpy_fromio
#endif
+#define DEBUG
+
+
+/*
+ This driver can spew a whole lot of debugging output at you. If you
+ need maximum performance, you should disable the DEBUG define. To
+ aid in debugging in the field, I'm leaving the compile-time debug
+ features enabled, and disable them "runtime". That allows me to
+ instruct people with problems to enable debugging without requiring
+ them to recompile...
+*/
+
+#ifdef DEBUG
+#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
+#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__ \
+ "(port %d)\n", port->line)
+#else
+#define rio_dprintk(f, str...) /* nothing */
+#define func_enter()
+#define func_exit()
+#define func_enter2()
+#endif
+
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
index 7a06b0dc9..8168f2133 100644
--- a/drivers/char/rio/rioboot.c
+++ b/drivers/char/rio/rioboot.c
@@ -81,7 +81,6 @@ static char *_rioboot_c_sccs_ = "@(#)rioboot.c 1.3";
#include "cmdblk.h"
#include "route.h"
-
static uchar
RIOAtVec2Ctrl[] =
{
@@ -113,6 +112,8 @@ struct DownLoad * rbp;
{
int offset;
+ func_enter ();
+
/* Linux doesn't allow you to disable interrupts during a
"copyin". (Crash when a pagefault occurs). */
/* disable(oldspl); */
@@ -126,6 +127,7 @@ struct DownLoad * rbp;
rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code Too Large!\n"));
p->RIOError.Error = HOST_FILE_TOO_LARGE;
/* restore(oldspl); */
+ func_exit ();
return ENOMEM;
}
@@ -133,6 +135,7 @@ struct DownLoad * rbp;
rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code : BUSY BUSY BUSY!\n"));
p->RIOError.Error = BOOT_IN_PROGRESS;
/* restore(oldspl); */
+ func_exit ();
return EBUSY;
}
@@ -160,6 +163,7 @@ struct DownLoad * rbp;
rio_dprint(RIO_DEBUG_BOOT, ("Bad data copy from user space\n"));
p->RIOError.Error = COPYIN_FAILED;
/* restore(oldspl); */
+ func_exit ();
return EFAULT;
}
@@ -171,9 +175,61 @@ struct DownLoad * rbp;
p->RIOBootCount = rbp->Count;
/* restore(oldspl); */
+ func_exit();
return 0;
}
+void rio_start_card_running (struct Host * HostP)
+{
+ func_enter ();
+
+ switch ( HostP->Type ) {
+ case RIO_AT:
+ rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
+ WBYTE(HostP->Control,
+ BOOT_FROM_RAM | EXTERNAL_BUS_ON
+ | HostP->Mode
+ | RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
+ break;
+
+#ifdef FUTURE_RELEASE
+ case RIO_MCA:
+ /*
+ ** MCA handles IRQ vectors differently, so we don't write
+ ** them to this register.
+ */
+ rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
+ WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
+ break;
+
+ case RIO_EISA:
+ /*
+ ** EISA is totally different and expects OUTBZs to turn it on.
+ */
+ rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"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
+
+ case RIO_PCI:
+ /*
+ ** PCI is much the same as MCA. Everything is once again memory
+ ** mapped, so we are writing to memory registers instead of io
+ ** ports.
+ */
+ rio_dprint(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));
+ break;
+ }
+/*
+ printk (KERN_INFO "Done with starting the card\n");
+ func_exit ();
+*/
+ return;
+}
/*
** Load in the host boot code - load it directly onto all halted hosts
@@ -206,6 +262,10 @@ register struct DownLoad *rbp;
for ( host=0; host<p->RIONumHosts; host++ ) {
rio_dprint(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 ) );
+
if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) {
rio_dprint(RIO_DEBUG_BOOT, ("%s %d already running\n","Host",host));
@@ -233,6 +293,7 @@ register struct DownLoad *rbp;
if ( p->RIOConf.HostLoadBase < rbp->Count ) {
rio_dprint(RIO_DEBUG_BOOT, ("Bin too large\n"));
p->RIOError.Error = HOST_FILE_TOO_LARGE;
+ func_exit ();
return EFBIG;
}
/*
@@ -259,6 +320,7 @@ register struct DownLoad *rbp;
if ( !DownCode ) {
rio_dprint(RIO_DEBUG_BOOT, ("No system memory available\n"));
p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY;
+ func_exit ();
return ENOMEM;
}
bzero(DownCode, rbp->Count);
@@ -266,6 +328,7 @@ register struct DownLoad *rbp;
if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) {
rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
p->RIOError.Error = COPYIN_FAILED;
+ func_exit ();
return EFAULT;
}
@@ -276,6 +339,7 @@ register struct DownLoad *rbp;
else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) {
rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
p->RIOError.Error = COPYIN_FAILED;
+ func_exit ();
return EFAULT;
}
@@ -405,47 +469,8 @@ register struct DownLoad *rbp;
rio_dprint(RIO_DEBUG_BOOT, ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
HostP->Type, HostP->Mode, HostP->Ivec ) );
- switch ( HostP->Type ) {
- case RIO_AT:
- rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
- WBYTE(HostP->Control,
- BOOT_FROM_RAM | EXTERNAL_BUS_ON
- | HostP->Mode
- | RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
- break;
+ rio_start_card_running(HostP);
-#ifdef FUTURE_RELEASE
- case RIO_MCA:
- /*
- ** MCA handles IRQ vectors differently, so we don't write
- ** them to this register.
- */
- rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
- WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
- break;
-
- case RIO_EISA:
- /*
- ** EISA is totally different and expects OUTBZs to turn it on.
- */
- rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"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
-
- case RIO_PCI:
- /*
- ** PCI is much the same as MCA. Everything is once again memory
- ** mapped, so we are writing to memory registers instead of io
- ** ports.
- */
- rio_dprint(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));
- break;
- }
rio_dprint(RIO_DEBUG_BOOT, ("Set control port\n"));
/*
@@ -453,9 +478,10 @@ register struct DownLoad *rbp;
** pointer:
*/
for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&
- (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
+ (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
rio_dprint(RIO_DEBUG_BOOT, ("Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)));
delay(HostP, HUNDRED_MS);
+
}
/*
@@ -613,6 +639,7 @@ register struct DownLoad *rbp;
p->RIOSystemUp++;
rio_dprint(RIO_DEBUG_BOOT, ("Done everything %x\n", HostP->Ivec));
+ func_exit ();
return 0;
}
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 6f2e43da0..835d815d3 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -43,7 +43,6 @@ static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2";
#include <asm/string.h>
#include <asm/semaphore.h>
-
#include <linux/termios.h>
#include <linux/serial.h>
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index 27b46398a..fa68646d5 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -201,6 +201,8 @@ int su;
int retval = 0;
unsigned long flags;
+ func_enter ();
+
/* Confuse teh compiler to think that we've initialized these */
Host=0;
PortP = NULL;
@@ -1776,6 +1778,8 @@ RIO_DEBUG_CTRL, if (su)
}
rio_dprint(RIO_DEBUG_CTRL, ("INVALID DAEMON IOCTL 0x%x\n",cmd));
p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
+
+ func_exit ();
return EINVAL;
}
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index 72e8632cd..59cfdedd5 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -1414,7 +1414,7 @@ struct rio_info * p;
(int)p->RIOHosts, sizeof(struct Host) ) );
for( host=0; host<RIO_HOSTS; host++ ) {
- p->RIOHosts[host].HostLock = SPIN_LOCK_UNLOCKED; /* Let the first guy takes it */
+ spin_lock_init (&p->RIOHosts[host].HostLock);
p->RIOHosts[host].timeout_id = 0; /* Let the first guy takes it */
}
/*
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index 3e7236b19..cda417f3f 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -89,7 +89,6 @@ static char *_riotty_c_sccs_ = "@(#)riotty.c 1.3";
#include "list.h"
#include "sam.h"
-
#if 0
static void ttyseth_pv(struct Port *, struct ttystatics *,
struct termios *sg, int);
@@ -154,13 +153,21 @@ riotopen(struct tty_struct * tty, struct file * filp)
unsigned long flags;
int retval = 0;
+ func_enter ();
+
+ /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
+ is going to oops.
+ */
+ tty->driver_data = NULL;
+
SysPort = rio_minor (tty->device);
Modem = rio_ismodem (tty->device);
if ( p->RIOFailed ) {
rio_dprint(RIO_DEBUG_TTY, ("System initialisation failed\n"));
pseterr(ENXIO);
- return 0;
+ func_exit ();
+ return -ENXIO;
}
rio_dprint(RIO_DEBUG_TTY, ("port open SysPort %d (%s) (mapped:%d)\n",
@@ -176,22 +183,24 @@ riotopen(struct tty_struct * tty, struct file * filp)
if (SysPort >= RIO_PORTS) { /* out of range ? */
rio_dprint(RIO_DEBUG_TTY, ("Illegal port number %d\n",SysPort));
pseterr(ENXIO);
- return 0;
+ func_exit();
+ return -ENXIO;
}
/*
** Grab pointer to the port stucture
*/
PortP = p->RIOPortp[SysPort]; /* Get control struc */
-
+ rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP);
if ( !PortP->Mapped ) { /* we aren't mapped yet! */
/*
** The system doesn't know which RTA this port
** corresponds to.
*/
rio_dprint(RIO_DEBUG_TTY, ("port not mapped into system\n"));
+ func_exit ();
pseterr(ENXIO);
- return 0;
+ return -ENXIO;
}
tty->driver_data = PortP;
@@ -209,7 +218,8 @@ riotopen(struct tty_struct * tty, struct file * filp)
if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
rio_dprint(RIO_DEBUG_TTY, ("Host not running\n"));
pseterr(ENXIO);
- return 0;
+ func_exit ();
+ return -ENXIO;
}
/*
@@ -224,12 +234,14 @@ riotopen(struct tty_struct * tty, struct file * filp)
do {
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
rio_dprint(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"));
RIOPreemptiveCmd(p, PortP, FCLOSE );
pseterr(EINTR);
+ func_exit ();
return -EIO;
}
} while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
@@ -237,6 +249,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
} else {
rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
pseterr(ENXIO);
+ func_exit ();
return 0;
}
}
@@ -249,6 +262,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
if (!PortP->WaitUntilBooted) {
rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+ func_exit ();
return -ENXIO;
}
@@ -258,10 +272,12 @@ riotopen(struct tty_struct * tty, struct file * filp)
*/
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
rio_dprint(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"));
+ func_exit ();
return -EIO;
}
}
@@ -276,8 +292,10 @@ riotopen(struct tty_struct * tty, struct file * filp)
}
#if 0
retval = gs_init_port(&PortP->gs);
- if (retval)
- return retval;
+ if (retval){
+ func_exit ();
+ return retval;
+ }
#endif
/*
@@ -306,6 +324,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
rio_dprint(RIO_DEBUG_TTY, ("Port unmapped while closing!\n"));
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
retval = -ENXIO;
+ func_exit ();
return retval;
}
@@ -375,6 +394,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish broken by signal\n"));
RIOPreemptiveCmd(p, PortP, FCLOSE );
+ func_exit ();
return -EINTR;
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
@@ -425,6 +445,7 @@ bombout:
tp->tm.c_state &= ~WOPEN;
PortP->State &= ~RIO_WOPEN;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+ func_exit ();
return -EINTR;
}
}
@@ -462,6 +483,7 @@ bombout:
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
rio_dprint(RIO_DEBUG_TTY, ("Returning from open\n"));
+ func_exit ();
return 0;
}
diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h
index 13821a982..eddf86278 100644
--- a/drivers/char/rio/unixrup.h
+++ b/drivers/char/rio/unixrup.h
@@ -49,7 +49,7 @@ struct UnixRup
uint Id; /* Id number */
uint BaseSysPort; /* SysPort of first tty on this RTA */
uint ModTypes; /* Modules on this RTA */
- spinlock_t RupLock; /* Lock structure for MPX */
+ spinlock_t RupLock; /* Lock structure for MPX */
/* struct lockb RupLock; */ /* Lock structure for MPX */
};
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index bb9da9018..bfe700219 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -762,7 +762,7 @@ EXPORT_NO_SYMBOLS;
static void rtc_dropped_irq(unsigned long data)
{
- printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", rtc_freq);
+ unsigned long freq;
spin_lock_irq (&rtc_lock);
@@ -773,8 +773,13 @@ static void rtc_dropped_irq(unsigned long data)
rtc_irq_data += ((rtc_freq/HZ)<<8);
rtc_irq_data &= ~0xff;
rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */
+
+ freq = rtc_freq;
+
spin_unlock_irq(&rtc_lock);
+ printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", freq);
+
/* Now we have new data */
wake_up_interruptible(&rtc_wait);
diff --git a/drivers/char/sh-sci.c b/drivers/char/sh-sci.c
index 8ab735cdc..05bfcb607 100644
--- a/drivers/char/sh-sci.c
+++ b/drivers/char/sh-sci.c
@@ -189,10 +189,35 @@ static void sci_set_termios_cflag(struct sci_port *port)
ctrl_out(smr_val, SCSMR);
#if defined(CONFIG_SH_SCIF_SERIAL)
+#if defined(__sh3__)
+ { /* For SH7709, SH7709A, SH7729 */
+ unsigned short data;
+
+ /* We need to set SCPCR to enable RTS/CTS */
+ data = ctrl_inw(SCPCR);
+ /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
+ ctrl_outw(data&0x0fcf, SCPCR);
+ }
+#endif
if (C_CRTSCTS(port->gs.tty))
fcr_val |= 0x08;
- else
+ else {
+#if defined(__sh3__)
+ unsigned short data;
+
+ /* We need to set SCPCR to enable RTS/CTS */
+ data = ctrl_inw(SCPCR);
+ /* Clear out SCP7MD1,0, SCP4MD1,0,
+ Set SCP6MD1,0 = {01} (output) */
+ ctrl_outw((data&0x0fcf)|0x1000, SCPCR);
+
+ data = ctrl_inb(SCPDR);
+ /* Set /RTS2 (bit6) = 0 */
+ ctrl_outb(data&0xbf, SCPDR);
+#elif defined(__SH4__)
ctrl_outw(0x0080, SCSPTR); /* Set RTS = 1 */
+#endif
+ }
ctrl_out(fcr_val, SCFCR);
#endif
@@ -721,7 +746,7 @@ int __init sci_init(void)
int i;
for (i=SCI_ERI_IRQ; i<SCI_IRQ_END; i++)
- set_ipr_data(i, SCI_IPR_OFFSET, SCI_PRIORITY);
+ set_ipr_data(i, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
port = &sci_ports[0];
@@ -789,6 +814,7 @@ static inline void put_char(char c)
while (!(status & SCI_TD_E));
ctrl_outb(c, SC_TDR);
+ ctrl_in(SC_SR); /* Dummy read */
ctrl_out(SCI_TD_E_CLEAR, SC_SR);
restore_flags(flags);
@@ -817,6 +843,7 @@ static inline int get_char(void)
}
} while (!(status & SCI_RD_F));
c = ctrl_inb(SC_RDR);
+ ctrl_in(SC_SR); /* Dummy read */
ctrl_out(SCI_RDRF_CLEAR, SC_SR);
restore_flags(flags);
diff --git a/drivers/char/sh-sci.h b/drivers/char/sh-sci.h
index 2a736f4c9..f501951ec 100644
--- a/drivers/char/sh-sci.h
+++ b/drivers/char/sh-sci.h
@@ -56,7 +56,8 @@
#define SCI_TEI_IRQ 26
#define SCI_IRQ_END 27
-#define SCI_IPR_OFFSET (16+4)
+#define SCI_IPR_ADDR INTC_IPRB
+#define SCI_IPR_POS 1
#endif
#if defined(CONFIG_SH_SCIF_SERIAL)
@@ -69,12 +70,16 @@
#define SC_RDR 0xA400015A
#define SCFCR (volatile unsigned char *)0xA400015C
#define SCFDR 0xA400015E
-#undef SCSPTR /* Is there any register for RTS?? */
+
+#undef SCSPTR /* SH7709 doesn't have SCSPTR */
+#define SCPCR 0xA4000116 /* Instead, it has SCPCR and SCPDR */
+#define SCPDR 0xA4000136
#undef SCLSR
#define SCSCR_INIT 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
/* 0x33 when external clock is used */
-#define SCI_IPR_OFFSET (64+4)
+#define SCI_IPR_ADDR INTC_IPRE
+#define SCI_IPR_POS 1
#elif defined(__SH4__)
#define SCSMR (volatile unsigned short *)0xFFE80000
@@ -89,7 +94,8 @@
#define SCLSR 0xFFE80024
#define SCSCR_INIT 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
-#define SCI_IPR_OFFSET (32+4)
+#define SCI_IPR_ADDR INTC_IPRC
+#define SCI_IPR_POS 1
#endif
@@ -187,8 +193,17 @@ struct sci_port {
* -- Greg Banks 27Feb2000
*/
+/*
+ * XXX: Well, this is not relevant...
+ * Should we have config option for peripheral clock?
+ * Or we get the value from time.c.
+ */
#if defined(__sh3__)
-#define PCLK 14745600
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+#define PCLK 33333333
+#else
+#define PCLK 14745600 /* Isn't it 15MHz? */
+#endif
#elif defined(__SH4__)
#define PCLK 33333333
#endif
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index adfe3c69d..24a4948b5 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1079,7 +1079,7 @@ inline void sx_receive_chars (struct sx_port *port)
struct tty_struct *tty;
int copied=0;
- /* func_enter2 (); */
+ func_enter2 ();
tty = port->gs.tty;
while (1) {
rx_op = sx_read_channel_byte (port, hi_rxopos);
@@ -1134,7 +1134,7 @@ inline void sx_receive_chars (struct sx_port *port)
/* tty_schedule_flip (tty); */
}
- /* func_exit (); */
+ func_exit ();
}
/* Inlined: it is called only once. Remove the inline if you add another
@@ -2343,6 +2343,12 @@ static int sx_init_portstructs (int nboards, int nports)
#ifdef NEW_WRITE_LOCKING
port->gs.port_write_sem = MUTEX;
#endif
+ /*
+ * Initializing wait queue
+ */
+ init_waitqueue_head(&port->gs.open_wait);
+ init_waitqueue_head(&port->gs.close_wait);
+
port++;
}
}
diff --git a/drivers/char/tda7432.c b/drivers/char/tda7432.c
new file mode 100644
index 000000000..488091310
--- /dev/null
+++ b/drivers/char/tda7432.c
@@ -0,0 +1,505 @@
+/*
+ * 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
index 73df0b4ac..a1dec22eb 100644
--- a/drivers/char/tda8425.c
+++ b/drivers/char/tda8425.c
@@ -31,7 +31,6 @@
#include "audiochip.h"
/* Addresses to scan */
-#define I2C_TDA8425 0x82
static unsigned short normal_i2c[] = {
I2C_TDA8425 >> 1,
I2C_CLIENT_END};
diff --git a/drivers/char/tda985x.c b/drivers/char/tda985x.c
index 62bcf15ba..73fb9bd52 100644
--- a/drivers/char/tda985x.c
+++ b/drivers/char/tda985x.c
@@ -13,6 +13,7 @@
*
* 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:
@@ -20,7 +21,8 @@
* 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
@@ -55,9 +57,10 @@ static int chip = 9855; /* insmod parameter */
#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};
+ 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 };
@@ -84,6 +87,7 @@ 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
@@ -154,9 +158,9 @@ static struct i2c_client client_template;
#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 */
+ /* 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) */
@@ -213,8 +217,8 @@ static struct i2c_client client_template;
static int tda985x_write(struct i2c_client *client, int subaddr, int val)
{
unsigned char buffer[2];
- dprintk("In tda985x_write\n");
- dprintk("Writing %d 0x%x\n", subaddr, val);
+ 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)) {
@@ -228,12 +232,12 @@ static int tda985x_write(struct i2c_client *client, int subaddr, int val)
static int tda985x_read(struct i2c_client *client)
{
unsigned char buffer;
- dprintk("In tda985x_read\n");
+ 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("Read 0x%02x\n", buffer);
+ dprintk("tda985x: Read 0x%02x\n", buffer);
return buffer;
}
@@ -241,12 +245,12 @@ static int tda985x_set(struct i2c_client *client)
{
struct tda985x *t = client->data;
unsigned char buf[16];
- dprintk("In tda985x_set\n");
+ d2printk("tda985x: In tda985x_set\n");
if (chip == 9855)
{
dprintk(KERN_INFO
- "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",
+ "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;
@@ -262,7 +266,7 @@ static int tda985x_set(struct i2c_client *client)
buf[10] = t->a2;
buf[11] = t->a3;
if (12 != i2c_master_send(client,buf,12)) {
- printk(KERN_WARNING "tda9855: I/O error, trying tda985x_set\n");
+ printk(KERN_WARNING "tda985x: I/O error, trying tda985x_set\n");
return -1;
}
}
@@ -270,7 +274,7 @@ static int tda985x_set(struct i2c_client *client)
else if (chip == 9850)
{
dprintk(KERN_INFO
- "tda985x_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
+ "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;
@@ -281,7 +285,7 @@ static int tda985x_set(struct i2c_client *client)
buf[6] = t->a2;
buf[7] = t->a3;
if (8 != i2c_master_send(client,buf,8)) {
- printk(KERN_WARNING "tda9850: I/O error, trying tda985x_set\n");
+ printk(KERN_WARNING "tda985x: I/O error, trying tda985x_set\n");
return -1;
}
}
@@ -292,11 +296,11 @@ static int tda985x_set(struct i2c_client *client)
static void do_tda985x_init(struct i2c_client *client)
{
struct tda985x *t = client->data;
- dprintk("In tda985x_init\n");
+ d2printk("tda985x: In tda985x_init\n");
if (chip == 9855)
{
- printk("Using tda9855 options\n");
+ printk("tda985x: Using tda9855 options\n");
t->rvol = 0x6f; /* 0dB */
t->lvol = 0x6f; /* 0dB */
t->bass = 0x0e; /* 0dB */
@@ -313,7 +317,7 @@ static void do_tda985x_init(struct i2c_client *client)
else if (chip == 9850)
{
- printk("Using tda9850 options\n");
+ 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 */
@@ -337,7 +341,7 @@ static int tda985x_attach(struct i2c_adapter *adap, int addr,
{
struct tda985x *t;
struct i2c_client *client;
- dprintk("In tda985x_attach\n");
+ d2printk("tda985x: In tda985x_attach\n");
client = kmalloc(sizeof *client,GFP_KERNEL);
if (!client)
return -ENOMEM;
@@ -382,7 +386,7 @@ static int tda985x_command(struct i2c_client *client,
unsigned int cmd, void *arg)
{
struct tda985x *t = client->data;
- dprintk("In tda985x_command...\n");
+ d2printk("tda985x: In tda985x_command\n");
#if 0
__u16 *sarg = arg;
#endif
@@ -394,7 +398,7 @@ static int tda985x_command(struct i2c_client *client,
case VIDIOCGAUDIO:
{
struct video_audio *va = arg;
- dprintk("VIDIOCGAUDIO\n");
+ dprintk("tda985x: VIDIOCGAUDIO\n");
if (chip == 9855)
{
int left,right;
@@ -430,7 +434,7 @@ static int tda985x_command(struct i2c_client *client,
case VIDIOCSAUDIO:
{
struct video_audio *va = arg;
- dprintk("VIDEOCSAUDIO...\n");
+ dprintk("tda985x: VIDEOCSAUDIO\n");
if (chip == 9855)
{
int left,right;
@@ -453,17 +457,17 @@ static int tda985x_command(struct i2c_client *client,
switch (va->mode) {
case VIDEO_SOUND_MONO:
- dprintk("VIDEO_SOUND_MONO\n");
+ 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("VIDEO_SOUND_STEREO\n");
+ 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("VIDEO_SOUND_LANG1\n");
+ dprintk("tda985x: VIDEO_SOUND_LANG1\n");
t->c6= TDA985x_SAP | (t->c6 & 0x3f);
tda985x_write(client,TDA985x_C6,t->c6);
break;
@@ -476,7 +480,7 @@ static int tda985x_command(struct i2c_client *client,
default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
/* nothing */
- dprintk("Default\n");
+ d2printk("tda985x: Default\n");
} /* end of (cmd) switch */
diff --git a/drivers/char/tda9875.c b/drivers/char/tda9875.c
new file mode 100644
index 000000000..da3ceebfe
--- /dev/null
+++ b/drivers/char/tda9875.c
@@ -0,0 +1,371 @@
+/*
+ * 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 Guillamue 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, int 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;
+
+ dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n",tda->lvol,tda->rvol,tda->bass,tda->treble);
+ tda9875_write(client, TDA9875_MVL, tda->lvol / 600 - 84);
+ tda9875_write(client, TDA9875_MVR, tda->rvol / 600 -84);
+ tda9875_write(client, TDA9875_MBA, tda->bass / 2340 -12);
+ tda9875_write(client, TDA9875_MTR, tda->treble / 2621 -12);
+}
+
+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_MUTE;
+ t->lvol=t->rvol =51000; /* 0dB */
+ t->bass=30420; /* 0dB */
+ t->treble=34073; /* 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+85)*600;
+ right = (t->rvol+85)*600;
+ 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+13)*2340; /* min -12 max +15 */
+ va->treble = (t->treble+13)*2621;/* 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/600-84;
+ t->rvol = right/600-84;
+ t->bass = va->bass/2340-12;
+ t->treble = va->treble/2621-12;
+ 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/tea6420.c b/drivers/char/tea6420.c
new file mode 100644
index 000000000..231ed9e4e
--- /dev/null
+++ b/drivers/char/tea6420.c
@@ -0,0 +1,268 @@
+/*
+ * 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 f922c7b71..1516d985e 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -146,8 +146,8 @@ extern long vme_scc_console_init(void);
extern int serial167_init(void);
extern long serial167_console_init(void);
#endif
-#ifdef CONFIG_8xx
-extern console_8xx_init(void);
+#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
+extern void console_8xx_init(void);
extern int rs_8xx_init(void);
#endif /* CONFIG_8xx */
#ifdef CONFIG_SGI_SERIAL
@@ -2197,7 +2197,7 @@ void __init console_init(void)
con_init();
#endif
#ifdef CONFIG_SERIAL_CONSOLE
-#ifdef CONFIG_8xx
+#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
console_8xx_init();
#elif defined(CONFIG_SERIAL)
serial_console_init();
@@ -2346,7 +2346,7 @@ void __init tty_init(void)
#ifdef CONFIG_RIO
rio_init();
#endif
-#ifdef CONFIG_8xx
+#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
rs_8xx_init();
#endif /* CONFIG_8xx */
pty_init();
diff --git a/drivers/char/videodev.c b/drivers/char/videodev.c
index 364ae8e69..618f02f85 100644
--- a/drivers/char/videodev.c
+++ b/drivers/char/videodev.c
@@ -41,7 +41,6 @@
static struct video_device *video_device[VIDEO_NUM_DEVICES];
#ifdef CONFIG_VIDEO_BT848
-extern int init_bttv_cards(struct video_init *);
extern int i2c_tuner_init(struct video_init *);
#endif
#ifdef CONFIG_VIDEO_BWQCAM
@@ -59,9 +58,8 @@ extern int init_zoran_cards(struct video_init *);
static struct video_init video_init_list[]={
#ifdef CONFIG_VIDEO_BT848
- {"i2c-tuner", i2c_tuner_init},
- {"bttv", init_bttv_cards},
-#endif
+ {"i2c-tuner", i2c_tuner_init},
+#endif
#ifdef CONFIG_VIDEO_BWQCAM
{"bw-qcam", init_bw_qcams},
#endif