patch-2.3.99-pre9 linux/drivers/char/bttv.c
Next file: linux/drivers/char/bttv.h
Previous file: linux/drivers/char/Makefile
Back to the patch index
Back to the overall index
- Lines: 1238
- Date:
Mon May 22 09:50:53 2000
- Orig file:
v2.3.99-pre8/linux/drivers/char/bttv.c
- Orig date:
Thu May 11 15:30:06 2000
diff -u --recursive --new-file v2.3.99-pre8/linux/drivers/char/bttv.c linux/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 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 @@
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 @@
}
/* 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 @@
}
/* 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 @@
}
/* 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 @@
int id;
char *name;
}
-hauppauge_tuner[] =
+hauppauge_tuner[] __initdata =
{
{ TUNER_ABSENT, "" },
{ TUNER_ABSENT, "External" },
@@ -612,8 +606,7 @@
{ 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 @@
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 @@
/* 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 @@
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 @@
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 @@
/* 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 @@
}
}
-static int
-idcard_eeprom(struct bttv *btv)
+static int __init idcard_eeprom(struct bttv *btv)
{
unsigned id;
int i,n;
@@ -1477,6 +1493,10 @@
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 @@
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 @@
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 @@
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 @@
{
unsigned int *ro, *re;
unsigned int *vbuf;
+ unsigned long flags;
if(btv->fbuffer==NULL)
{
@@ -1870,7 +1890,7 @@
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 @@
#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 @@
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 @@
else
return count-todo;
}
- }
+ } else
+ spin_unlock_irqrestore(&btv->s_lock, flags);
}
if (todo)
{
@@ -1958,7 +1982,7 @@
{
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 @@
int i,ret;
ret = -EBUSY;
+
+ MOD_INC_USE_COUNT;
down(&btv->lock);
if (btv->user)
goto out_unlock;
@@ -2005,11 +2031,11 @@
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 @@
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 @@
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 @@
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 @@
else
return count-todo;
}
- }
+ } else
+ spin_unlock_irqrestore(&btv->s_lock, flags);
}
if (todo)
{
@@ -2784,6 +2814,8 @@
{
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 @@
bt848_set_risc_jmps(btv,-1);
up(&btv->lock);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2864,6 +2895,7 @@
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 @@
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 @@
#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 @@
/* 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 @@
/* 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 @@
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 @@
}
/* 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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
* 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 @@
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 @@
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 @@
}
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 @@
{
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 @@
* 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 @@
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 @@
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 @@
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 @@
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);
+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->risc_scr_odd)
- kfree((void *) btv->risc_scr_odd);
-
- if (btv->risc_scr_even)
- kfree((void *) btv->risc_scr_even);
+MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
- 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(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 @@
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:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)