patch-2.4.0-test2 linux/drivers/char/bttv.c
Next file: linux/drivers/char/bttv.h
Previous file: linux/drivers/char/atixlmouse.c
Back to the patch index
Back to the overall index
- Lines: 1066
- Date:
Tue Jun 20 07:32:13 2000
- Orig file:
v2.4.0-test1/linux/drivers/char/bttv.c
- Orig date:
Mon Jun 19 16:31:59 2000
diff -u --recursive --new-file v2.4.0-test1/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
@@ -64,7 +64,6 @@
/* insmod args */
MODULE_PARM(triton1,"i");
-MODULE_PARM(remap,"1-4i");
MODULE_PARM(radio,"1-4i");
MODULE_PARM(card,"1-4i");
MODULE_PARM(pll,"1-4i");
@@ -76,6 +75,7 @@
MODULE_PARM(gbuffers,"i");
MODULE_PARM(gbufsize,"i");
+EXPORT_SYMBOL(bttv_get_cardinfo);
EXPORT_SYMBOL(bttv_get_id);
EXPORT_SYMBOL(bttv_gpio_enable);
EXPORT_SYMBOL(bttv_read_gpio);
@@ -91,7 +91,6 @@
static unsigned int bigendian=0;
#endif
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] = { -1, -1, -1, -1};
@@ -123,8 +122,19 @@
/* gpio ports (IR for example) */
/* see bttv.h for comments */
+int bttv_get_cardinfo(unsigned int card, int *type, int *cardid)
+{
+ if (card >= bttv_num) {
+ return -1;
+ }
+ *type = bttvs[card].type;
+ *cardid = bttvs[card].cardid;
+ return 0;
+}
+
int bttv_get_id(unsigned int card)
{
+ printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n");
if (card >= bttv_num) {
return -1;
}
@@ -180,7 +190,7 @@
return 0;
}
-WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card)
+wait_queue_head_t* bttv_get_gpio_queue(unsigned int card)
{
struct bttv *btv;
@@ -467,7 +477,7 @@
NULL
};
-static int __init init_bttv_i2c(struct bttv *btv)
+static int __devinit init_bttv_i2c(struct bttv *btv)
{
/* i2c bit_adapter */
memcpy(&btv->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter));
@@ -489,7 +499,7 @@
}
/* read I2C */
-static int __init I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
+static int I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
{
unsigned char buffer = 0;
@@ -514,7 +524,7 @@
}
/* write I2C */
-static int __init I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
+static int I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
unsigned char b2, int both)
{
unsigned char buffer[2];
@@ -531,7 +541,7 @@
}
/* read EEPROM */
-static void __init readee(struct bttv *btv, unsigned char *eedata, int addr)
+static void __devinit readee(struct bttv *btv, unsigned char *eedata, int addr)
{
int i;
@@ -558,7 +568,7 @@
int id;
char *name;
}
-hauppauge_tuner[] __initdata =
+hauppauge_tuner[] __devinitdata =
{
{ TUNER_ABSENT, "" },
{ TUNER_ABSENT, "External" },
@@ -606,7 +616,7 @@
{ TUNER_ABSENT, "Temic 4046FM5" },
};
-static void __init hauppauge_eeprom(struct bttv *btv)
+static void __devinit hauppauge_eeprom(struct bttv *btv)
{
if (eeprom_data[9] < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER))
{
@@ -615,11 +625,9 @@
printk("bttv%d: Hauppauge eeprom: tuner=%s (%d)\n",btv->nr,
hauppauge_tuner[eeprom_data[9]].name,btv->tuner_type);
}
-
- return;
}
-static void __init hauppauge_boot_msp34xx(struct bttv *btv)
+static void __devinit hauppauge_boot_msp34xx(struct bttv *btv)
{
int i;
@@ -655,7 +663,7 @@
/* This is basically the same procedure as
* used by Alessandro Rubini in his pxc200
* driver, but using BTTV functions */
-static void __init init_PXC200(struct bttv *btv)
+static void __devinit init_PXC200(struct bttv *btv)
{
static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
@@ -705,7 +713,7 @@
unsigned id;
int cardnr;
char *name;
-} cards[] __initdata = {
+} cards[] __devinitdata = {
{ 0x00011002, BTTV_HAUPPAUGE878, "ATI TV Wonder" },
{ 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
{ 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
@@ -813,7 +821,7 @@
/* 0x10 */
{ "Pixelview PlayTV (bt878)",
- 3, 1, 0, 2, 0x01fe00, { 2, 0, 1, 1},
+ 3, 1, 0, 2, 0x01fe00, { 2, 3, 1, 1},
{ 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },0,
1,1,1,1,0,0,0,1, PLL_28, -1 },
{ "Leadtek WinView 601",
@@ -910,10 +918,18 @@
{ "ProVideo PV951", /* pic16c54 */
3, 1, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0},0,
0,0,0,0,0,0,0,0, PLL_28, 1 },
+ { "Little OnAir TV",
+ 3, 1, 0, 2, 0xe00b, {2, 3, 1, 1},
+ {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},0,
+ 0,0,0,0,0,0,0,0, PLL_NONE, -1 },
+
+ { "Sigma TVII-FM",
+ 2, 1, 0, -1, 3, {2, 3, 1, 1}, {1, 1, 0, 2, 3},0,
+ 0,0,0,0,0,0,0,0, PLL_NONE, -1 },
};
#define TVCARDS (sizeof(tvcards)/sizeof(struct tvcard))
-static void __init dump_eeprom(struct bttv *btv,int addr)
+static void __devinit dump_eeprom(struct bttv *btv,int addr)
{
int i;
@@ -930,7 +946,7 @@
}
}
-static int __init idcard_eeprom(struct bttv *btv)
+static int __devinit idcard_eeprom(struct bttv *btv)
{
unsigned id;
int i,n;
@@ -943,6 +959,7 @@
return -1;
/* look for the card */
+ btv->cardid = id;
for (n = -1, i = 0; cards[i].id != 0; i++)
if (cards[i].id == id)
n = i;
@@ -1203,7 +1220,7 @@
unsigned int *po=(unsigned int *) btv->vbi_odd;
unsigned int *pe=(unsigned int *) btv->vbi_even;
- if (debug)
+ if (debug > 1)
printk("bttv%d: vbi1: po=%08lx pe=%08lx\n",
btv->nr,virt_to_bus(po), virt_to_bus(pe));
@@ -1225,7 +1242,7 @@
*(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16));
*(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
- if (debug)
+ if (debug > 1)
printk("bttv%d: vbi2: po=%08lx pe=%08lx\n",
btv->nr,virt_to_bus(po), virt_to_bus(pe));
}
@@ -1302,7 +1319,7 @@
unsigned long vadr=(unsigned long) vbuf;
int shift, csize;
- if (debug)
+ if (debug > 1)
printk("bttv%d: prisc1: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1399,7 +1416,7 @@
*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
*(re++)=cpu_to_le32(btv->bus_vbi_odd);
- if (debug)
+ if (debug > 1)
printk("bttv%d: prisc2: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1424,7 +1441,7 @@
if (palette>=VIDEO_PALETTE_PLANAR)
return make_prisctab(btv, ro, re, vbuf, width, height, palette);
- if (debug)
+ if (debug > 1)
printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1476,7 +1493,7 @@
*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
*(re++)=cpu_to_le32(btv->bus_vbi_odd);
- if (debug)
+ if (debug > 1)
printk("bttv%d: vrisc2: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1494,7 +1511,7 @@
int W, l, r;
int i;
- if (debug)
+ if (debug > 1)
printk("bttv clip: %dx%d+%d+%d\n",w,h,x,y);
/* bitmap is fixed width, 128 bytes (1024 pixels represented) */
@@ -1559,7 +1576,7 @@
inter=(btv->win.interlace&1)^1;
width=btv->win.width;
height=btv->win.height;
- if (debug)
+ if (debug > 1)
printk("bttv%d: clip1: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
btv->nr,btv->picture.palette,width,height,bpl,bpp);
if(width > 1023)
@@ -1573,7 +1590,7 @@
printk("bttv%d: clip: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
- if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) {
+ if ((clipmap=vmalloc_32(VIDEO_CLIPMAP_SIZE))==NULL) {
/* can't clip, don't generate any risc code */
*(ro++)=cpu_to_le32(BT848_RISC_JUMP);
*(ro++)=cpu_to_le32(btv->bus_vbi_even);
@@ -1668,7 +1685,7 @@
*(re++)=cpu_to_le32(BT848_RISC_JUMP);
*(re++)=cpu_to_le32(btv->bus_vbi_odd);
- if (debug)
+ if (debug > 1)
printk("bttv%d: clip2: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
btv->nr,btv->picture.palette,width,height,bpl,bpp);
}
@@ -1734,9 +1751,6 @@
u16 ewidth, eheight, owidth, oheight;
u16 format, bswap;
struct tvnorm *tvn;
- unsigned long flags;
-
- spin_lock_irqsave(&btv->s_lock, flags);
tvn=&tvnorms[btv->win.norm];
@@ -1789,8 +1803,6 @@
btwrite(format, BT848_COLOR_FMT);
btwrite(bswap | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
-
- spin_unlock_irqrestore(&btv->s_lock, flags);
}
@@ -1847,7 +1859,6 @@
/*
* Grab into virtual memory.
- * Currently only does double buffering. Do we need more?
*/
static int vgrab(struct bttv *btv, struct video_mmap *mp)
@@ -1904,16 +1915,16 @@
btv->gbuf[mp->frame].ro = 0;
#endif
- if (btv->gq_in == btv->gq_out) {
+ if (-1 == btv->gq_grab && btv->gq_in == btv->gq_out) {
btv->gq_start = 1;
btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ);
}
btv->gqueue[btv->gq_in++] = mp->frame;
btv->gq_in = btv->gq_in % MAX_GBUFFERS;
- spin_unlock_irqrestore(&btv->s_lock, flags);
btor(3, BT848_CAP_CTL);
btor(3, BT848_GPIO_DMA_CTL);
+ spin_unlock_irqrestore(&btv->s_lock, flags);
return 0;
}
@@ -1927,39 +1938,43 @@
{
struct bttv *btv= (struct bttv *)v;
int q,todo;
+ DECLARE_WAITQUEUE(wait, current);
/* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
- unsigned long flags;
-
if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
return -EFAULT;
todo-=q;
buf+=q;
- spin_lock_irqsave(&btv->s_lock, flags);
+ add_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_INTERRUPTIBLE;
if (todo && q==VBIBUF_SIZE-btv->vbip)
{
if(nonblock)
{
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
if(count==todo)
return -EWOULDBLOCK;
return count-todo;
}
- spin_unlock_irqrestore(&btv->s_lock, flags);
- interruptible_sleep_on(&btv->vbiq);
+ schedule();
if(signal_pending(current))
{
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
+
if(todo==count)
return -EINTR;
else
return count-todo;
}
- } else
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ }
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
}
if (todo)
{
@@ -1980,9 +1995,11 @@
static void bt848_restart(struct bttv *btv)
{
+ unsigned long irq_flags;
+
if (verbose)
printk("bttv%d: resetting chip\n",btv->nr);
- btwrite(~0x0UL, BT848_INT_STAT);
+ btwrite(0xfffffUL, BT848_INT_STAT);
btand(~15, BT848_GPIO_DMA_CTL);
btwrite(0, BT848_SRESET);
btwrite(virt_to_bus(btv->risc_jmp+2),
@@ -1994,8 +2011,10 @@
btv->errors = 0;
btv->needs_restart = 0;
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_geo(btv,0);
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
/*
@@ -2042,13 +2061,16 @@
static void bttv_close(struct video_device *dev)
{
struct bttv *btv=(struct bttv *)dev;
+ unsigned long irq_flags;
down(&btv->lock);
btv->user--;
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->scr_on = 0;
btv->risc_cap_odd = 0;
btv->risc_cap_even = 0;
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
/*
* A word of warning. At this point the chip
@@ -2133,9 +2155,11 @@
static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
{
struct bttv *btv=(struct bttv *)dev;
+ unsigned long irq_flags;
int i,ret = 0;
- if (debug) printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd);
+ if (debug > 1)
+ printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd);
switch (cmd) {
case VIDIOCGCAP:
@@ -2206,7 +2230,9 @@
if (btv->win.norm != v.norm) {
btv->win.norm = v.norm;
make_vbitab(btv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_winsize(btv);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
up(&btv->lock);
return 0;
@@ -2248,7 +2274,9 @@
down(&btv->lock);
set_pll(btv);
make_vbitab(btv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_winsize(btv);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
up(&btv->lock);
}
return 0;
@@ -2289,12 +2317,13 @@
if(copy_from_user(&vw,arg,sizeof(vw)))
return -EFAULT;
+ down(&btv->lock);
if(vw.flags || vw.width < 16 || vw.height < 16)
{
- down(&btv->lock);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->scr_on = 0;
bt848_set_risc_jmps(btv,-1);
- up(&btv->lock);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
return -EINVAL;
}
if (btv->win.bpp < 4)
@@ -2302,18 +2331,17 @@
vw.x = (vw.x + 3) & ~3;
vw.width &= ~3;
}
- down(&btv->lock);
if (btv->needs_restart)
bt848_restart(btv);
btv->win.x=vw.x;
btv->win.y=vw.y;
btv->win.width=vw.width;
btv->win.height=vw.height;
-
+
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_risc_jmps(btv,0);
-
bt848_set_winsize(btv);
- up(&btv->lock);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
/*
* Do any clips.
@@ -2337,11 +2365,12 @@
return -EFAULT;
}
}
- down(&btv->lock);
make_clip_tab(btv, vcp, vw.clipcount);
if (vw.clipcount != 0)
vfree(vcp);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
up(&btv->lock);
return 0;
}
@@ -2370,13 +2399,13 @@
return -EINVAL;
if (btv->win.width==0 || btv->win.height==0)
return -EINVAL;
- down(&btv->lock);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
if (v == 1 && btv->win.vidadr != 0)
btv->scr_on = 1;
if (v == 0)
btv->scr_on = 0;
bt848_set_risc_jmps(btv,-1);
- up(&btv->lock);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
return 0;
}
case VIDIOCGFBUF:
@@ -2500,9 +2529,7 @@
if(!(v.flags&VIDEO_AUDIO_MUTE))
audio(btv, AUDIO_UNMUTE, 1);
- up(&btv->lock);
call_i2c_clients(btv,cmd,&v);
- down(&btv->lock);
if (btv->type == BTTV_TERRATV) {
unsigned int con = 0;
@@ -2554,6 +2581,9 @@
}
case VIDIOCSYNC:
+ {
+ DECLARE_WAITQUEUE(wait, current);
+
if(copy_from_user((void *)&i,arg,sizeof(int)))
return -EFAULT;
if (i < 0 || i >= gbuffers)
@@ -2563,13 +2593,20 @@
ret = -EINVAL;
break;
case GBUFFER_GRABBING:
+ add_wait_queue(&btv->capq, &wait);
+ current->state = TASK_INTERRUPTIBLE;
while(btv->gbuf[i].stat==GBUFFER_GRABBING) {
if (debug)
printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i);
- interruptible_sleep_on(&btv->capq);
- if(signal_pending(current))
+ schedule();
+ if(signal_pending(current)) {
+ remove_wait_queue(&btv->capq, &wait);
+ current->state = TASK_RUNNING;
return -EINTR;
+ }
}
+ remove_wait_queue(&btv->capq, &wait);
+ current->state = TASK_RUNNING;
/* fall throuth */
case GBUFFER_DONE:
case GBUFFER_ERROR:
@@ -2584,6 +2621,7 @@
up(&btv->lock);
}
return ret;
+ }
case BTTV_FIELDNR:
if(copy_to_user((void *) arg, (void *) &btv->last_field,
@@ -2602,7 +2640,6 @@
btv->pll.pll_ofreq = p.pll_ofreq;
btv->pll.pll_crystal = p.pll_crystal;
up(&btv->lock);
-
break;
}
@@ -2749,12 +2786,11 @@
{
struct bttv *btv=(struct bttv *)(v-2);
int q,todo;
+ DECLARE_WAITQUEUE(wait, current);
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
- unsigned long flags;
-
if (btv->needs_restart) {
down(&btv->lock);
bt848_restart(btv);
@@ -2765,27 +2801,31 @@
todo-=q;
buf+=q;
- spin_lock_irqsave(&btv->s_lock, flags);
+ add_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_INTERRUPTIBLE;
if (todo && q==VBIBUF_SIZE-btv->vbip)
{
if(nonblock)
{
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
if(count==todo)
return -EWOULDBLOCK;
return count-todo;
}
- spin_unlock_irqrestore(&btv->s_lock, flags);
- interruptible_sleep_on(&btv->vbiq);
+ schedule();
if(signal_pending(current))
{
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
if(todo==count)
return -EINTR;
else
return count-todo;
}
- } else
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ }
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
}
if (todo)
{
@@ -2813,15 +2853,18 @@
static int vbi_open(struct video_device *dev, int flags)
{
struct bttv *btv=(struct bttv *)(dev-2);
+ unsigned long irq_flags;
MOD_INC_USE_COUNT;
-
down(&btv->lock);
if (btv->needs_restart)
bt848_restart(btv);
+ set_pll(btv);
btv->vbip=VBIBUF_SIZE;
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->vbi_on = 1;
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
up(&btv->lock);
return 0;
@@ -2830,12 +2873,12 @@
static void vbi_close(struct video_device *dev)
{
struct bttv *btv=(struct bttv *)(dev-2);
+ unsigned long irq_flags;
- down(&btv->lock);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->vbi_on = 0;
bt848_set_risc_jmps(btv,-1);
- up(&btv->lock);
-
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
MOD_DEC_USE_COUNT;
}
@@ -3018,7 +3061,7 @@
#define TRITON_PEER_CONCURRENCY (1<<3)
-static void __init handle_chipset(void)
+static void __devinit handle_chipset(void)
{
struct pci_dev *dev = NULL;
@@ -3050,7 +3093,7 @@
/* can tda9855.c handle this too maybe? */
-static void __init init_tda9840(struct bttv *btv)
+static void __devinit init_tda9840(struct bttv *btv)
{
/* Horrible Hack */
I2CWrite(btv, I2C_TDA9840, TDA9840_SW, 0x2a, 1); /* sound mode switching */
@@ -3066,12 +3109,11 @@
/* Figure out card and tuner type */
-static void __init idcard(struct bttv *btv)
+static void __devinit idcard(struct bttv *btv)
{
int type,eeprom = 0;
btwrite(0, BT848_GPIO_OUT_EN);
- 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[btv->nr] >= 0 && card[btv->nr] < TVCARDS)
@@ -3114,7 +3156,6 @@
(btv->id==848 && btv->revision==0x12) ? "A" : "",
tvcards[btv->type].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) {
@@ -3228,10 +3269,6 @@
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;
@@ -3241,8 +3278,9 @@
flags |= 0x0c;
}
- if (debug) printk("bttv%d: set_risc_jmp %08lx:",
- btv->nr,virt_to_bus(btv->risc_jmp));
+ if (debug > 1)
+ printk("bttv%d: set_risc_jmp %08lx:",
+ btv->nr,virt_to_bus(btv->risc_jmp));
/* Sync to start of odd field */
btv->risc_jmp[0]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC
@@ -3252,24 +3290,29 @@
/* Jump to odd vbi sub */
btv->risc_jmp[2]=cpu_to_le32(BT848_RISC_JUMP|(0xd<<20));
if (flags&8) {
- if (debug) printk(" ev=%08lx",virt_to_bus(btv->vbi_odd));
+ if (debug > 1)
+ printk(" ev=%08lx",virt_to_bus(btv->vbi_odd));
btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->vbi_odd));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
}
/* Jump to odd sub */
btv->risc_jmp[4]=cpu_to_le32(BT848_RISC_JUMP|(0xe<<20));
if (0 != btv->risc_cap_odd) {
- if (debug) printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd);
+ if (debug > 1)
+ printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd);
flags |= 3;
btv->risc_jmp[5]=cpu_to_le32(btv->risc_cap_odd);
} else if (flags&2) {
- if (debug) printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd));
+ if (debug > 1)
+ printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd));
btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_scr_odd));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_jmp+6));
}
@@ -3282,24 +3325,29 @@
/* Jump to even vbi sub */
btv->risc_jmp[8]=cpu_to_le32(BT848_RISC_JUMP);
if (flags&4) {
- if (debug) printk(" ov=%08lx",virt_to_bus(btv->vbi_even));
+ if (debug > 1)
+ printk(" ov=%08lx",virt_to_bus(btv->vbi_even));
btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->vbi_even));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
}
/* Jump to even sub */
btv->risc_jmp[10]=cpu_to_le32(BT848_RISC_JUMP|(8<<20));
if (0 != btv->risc_cap_even) {
- if (debug) printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even);
+ if (debug > 1)
+ printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even);
flags |= 3;
btv->risc_jmp[11]=cpu_to_le32(btv->risc_cap_even);
} else if (flags&1) {
- if (debug) printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even));
+ if (debug > 1)
+ printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even));
btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_scr_even));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12));
}
@@ -3311,18 +3359,17 @@
btv->risc_jmp[13]=cpu_to_le32(virt_to_bus(btv->risc_jmp));
/* enable cpaturing and DMA */
- if (debug) printk(" flags=0x%x dma=%s\n",
- flags,(flags&0x0f) ? "on" : "off");
+ if (debug > 1)
+ printk(" flags=0x%x dma=%s\n",
+ flags,(flags&0x0f) ? "on" : "off");
btaor(flags, ~0x0f, BT848_CAP_CTL);
if (flags&0x0f)
bt848_dma(btv, 3);
else
bt848_dma(btv, 0);
-
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
-static int __init init_video_dev(struct bttv *btv)
+static int __devinit init_video_dev(struct bttv *btv)
{
memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template));
memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template));
@@ -3349,9 +3396,10 @@
return 1;
}
-static int __init init_bt848(struct bttv *btv)
+static int __devinit init_bt848(struct bttv *btv)
{
int j;
+ unsigned long irq_flags;
btv->user=0;
init_MUTEX(&btv->lock);
@@ -3412,14 +3460,13 @@
return -1;
if (!(btv->risc_jmp =(unsigned int *) kmalloc(2048, GFP_KERNEL)))
return -1;
- DEBUG(printk(KERN_DEBUG "risc_jmp: %p\n",btv->risc_jmp));
btv->vbi_odd=btv->risc_jmp+16;
btv->vbi_even=btv->vbi_odd+256;
btv->bus_vbi_odd=virt_to_bus(btv->risc_jmp+12);
btv->bus_vbi_even=virt_to_bus(btv->risc_jmp+6);
btwrite(virt_to_bus(btv->risc_jmp+2), BT848_RISC_STRT_ADD);
- btv->vbibuf=(unsigned char *) vmalloc(VBIBUF_SIZE);
+ btv->vbibuf=(unsigned char *) vmalloc_32(VBIBUF_SIZE);
if (!btv->vbibuf)
return -1;
if (!(btv->gbuf = kmalloc(sizeof(struct bttv_gbuf)*gbuffers,GFP_KERNEL)))
@@ -3475,7 +3522,7 @@
btwrite(0x00, BT848_O_SCLOOP);
/* clear interrupt status */
- btwrite(~0x0UL, BT848_INT_STAT);
+ btwrite(0xfffffUL, BT848_INT_STAT);
/* set interrupt mask */
btwrite(btv->triton1|
@@ -3489,8 +3536,10 @@
BT848_INT_MASK);
make_vbitab(btv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_risc_jmps(btv,-1);
-
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
+
/*
* Now add the template and register the device unit.
*/
@@ -3505,7 +3554,8 @@
u32 dstat;
int count,i;
struct bttv *btv;
-
+ unsigned long irq_flags;
+
btv=(struct bttv *)dev_id;
count=0;
while (1)
@@ -3515,6 +3565,7 @@
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));
@@ -3550,15 +3601,18 @@
btread(BT848_RISC_COUNT));
btv->errors++;
if (btv->errors < BTTV_ERRORS) {
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btand(~15, BT848_GPIO_DMA_CTL);
btwrite(virt_to_bus(btv->risc_jmp+2),
BT848_RISC_STRT_ADD);
bt848_set_geo(btv,0);
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
} else {
if (verbose)
printk("bttv%d: aiee: error loops\n",btv->nr);
/* cancel all outstanding grab requests */
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->gq_in = 0;
btv->gq_out = 0;
btv->gq_grab = -1;
@@ -3569,8 +3623,9 @@
btv->risc_cap_odd = 0;
btv->risc_cap_even = 0;
bt848_set_risc_jmps(btv,0);
-
btv->needs_restart = 1;
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
+
wake_up_interruptible(&btv->vbiq);
wake_up_interruptible(&btv->capq);
}
@@ -3596,6 +3651,7 @@
if (debug)
printk("bttv%d: cap irq: done %d\n",btv->nr,btv->gq_grab);
do_gettimeofday(&btv->gbuf[btv->gq_grab].tv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->gbuf[btv->gq_grab].stat = GBUFFER_DONE;
btv->gq_grab = -1;
if (btv->gq_in != btv->gq_out)
@@ -3618,22 +3674,25 @@
btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA,
BT848_COLOR_CTL);
}
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
wake_up_interruptible(&btv->capq);
break;
}
if (stat&(8<<28))
{
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->gq_start = 0;
btv->gq_grab = btv->gqueue[btv->gq_out++];
btv->gq_out = btv->gq_out % MAX_GBUFFERS;
if (debug)
- printk("bttv%d: cap irq: capture %d\n",btv->nr,btv->gq_grab);
+ printk("bttv%d: cap irq: capture %d [start]\n",btv->nr,btv->gq_grab);
btv->risc_cap_odd = btv->gbuf[btv->gq_grab].ro;
btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
bt848_set_risc_jmps(btv,-1);
bt848_set_geo(btv,0);
btwrite(BT848_COLOR_CTL_GAMMA,
BT848_COLOR_CTL);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
}
if (astat&BT848_INT_OCERR)
@@ -3676,9 +3735,6 @@
{
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",
@@ -3698,11 +3754,11 @@
* Scan for a Bt848 card, request the irq and map the io memory
*/
-static void __init bttv_remove(struct pci_dev *pci_dev)
+static void __devinit bttv_remove(struct pci_dev *pci_dev)
{
u8 command;
int j;
- struct bttv *btv = pci_dev->driver_data;
+ struct bttv *btv = PCI_GET_DRIVER_DATA(pci_dev);
/* unregister i2c_bus */
i2c_bit_del_bus(&btv->i2c_adap);
@@ -3767,7 +3823,7 @@
}
-static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
+static int __devinit bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
{
int result;
unsigned char command;
@@ -3788,20 +3844,17 @@
btv->vbi_even=NULL;
init_waitqueue_head(&btv->vbiq);
init_waitqueue_head(&btv->capq);
- init_waitqueue_head(&btv->capqo);
- init_waitqueue_head(&btv->capqe);
btv->vbip=VBIBUF_SIZE;
-
- init_waitqueue_head(&btv->gpioq);
btv->s_lock = SPIN_LOCK_UNLOCKED;
+ init_waitqueue_head(&btv->gpioq);
btv->shutdown=0;
btv->id=dev->device;
btv->irq=dev->irq;
- btv->bt848_adr=pci_resource_start(dev, 0);
+ btv->bt848_adr=pci_resource_start(dev,0);
if (pci_enable_device(dev))
return -EIO;
- if (!request_mem_region(btv->bt848_adr,
+ if (!request_mem_region(pci_resource_start(dev,0),
pci_resource_len(dev,0),
"bttv")) {
return -EBUSY;
@@ -3871,24 +3924,23 @@
}
}
- dev->driver_data = btv;
+ PCI_SET_DRIVER_DATA(dev,btv);
if(init_bt848(btv) < 0) {
bttv_remove(dev);
return -EIO;
}
-
bttv_num++;
return 0;
fail:
- release_mem_region(btv->bt848_adr,
+ release_mem_region(pci_resource_start(btv->dev,0),
pci_resource_len(btv->dev,0));
return result;
}
-static struct pci_device_id bttv_pci_tbl[] __initdata = {
+static struct pci_device_id bttv_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
@@ -3903,13 +3955,13 @@
MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
static struct pci_driver bttv_pci_driver = {
- name:"bttv",
- id_table:bttv_pci_tbl,
- probe:bttv_probe,
- remove:bttv_remove,
+ name: "bttv",
+ id_table: bttv_pci_tbl,
+ probe: bttv_probe,
+ remove: bttv_remove,
};
-static int __init bttv_init_module(void)
+int bttv_init_module(void)
{
bttv_num = 0;
@@ -3930,10 +3982,10 @@
return pci_module_init(&bttv_pci_driver);
}
-static void __exit bttv_cleanup_module(void)
+void bttv_cleanup_module(void)
{
pci_unregister_driver(&bttv_pci_driver);
- return;
+ return;
}
module_init(bttv_init_module);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)