aboutsummaryrefslogtreecommitdiffstats
path: root/bttv/driver
diff options
context:
space:
mode:
Diffstat (limited to 'bttv/driver')
-rw-r--r--bttv/driver/bt848.h6
-rw-r--r--bttv/driver/bttv.c496
-rw-r--r--bttv/driver/bttv.h4
-rw-r--r--bttv/driver/i2c.c541
-rw-r--r--bttv/driver/i2c.h81
-rw-r--r--bttv/driver/linux-2.0.33.diff10
-rw-r--r--bttv/driver/msp3400.c93
-rw-r--r--bttv/driver/tuner.c172
-rw-r--r--bttv/driver/update4
-rw-r--r--bttv/driver/videodev.c57
-rw-r--r--bttv/driver/videodev.h8
11 files changed, 772 insertions, 700 deletions
diff --git a/bttv/driver/bt848.h b/bttv/driver/bt848.h
index a50e31a..0956360 100644
--- a/bttv/driver/bt848.h
+++ b/bttv/driver/bt848.h
@@ -30,6 +30,12 @@
#ifndef PCI_DEVICE_ID_BT849
#define PCI_DEVICE_ID_BT849 0x351
#endif
+#ifndef PCI_DEVICE_ID_BT878
+#define PCI_DEVICE_ID_BT878 0x36e
+#endif
+#ifndef PCI_DEVICE_ID_BT879
+#define PCI_DEVICE_ID_BT879 0x36f
+#endif
/* Brooktree 848 registers */
diff --git a/bttv/driver/bttv.c b/bttv/driver/bttv.c
index d858dcd..7d1185b 100644
--- a/bttv/driver/bttv.c
+++ b/bttv/driver/bttv.c
@@ -30,9 +30,12 @@
* mmap VBI data?
* use new PCI routines
* fix RAW Composite grabbing for NTSC
- * allow for different VDELAY in RAW grabbing?
+ * allow for different VDELAYs
+ (larger to get Videodat in VBI and smaller to get the whole
+ picture in RAW grabbing)
* extra modules for tda9850, tda8425, any volunteers???
- * support 15bpp
+ * right border clipping is still buggy
+ (decide which clipping code to use and throw the other out ...)
*/
#include <linux/module.h>
@@ -86,13 +89,6 @@ copy_from_user(void *to, const void *from, unsigned long n)
#define DEBUG(x) /* Debug driver */
#define IDEBUG(x) /* Debug interrupt handler */
-static unsigned int remap=0; /* remap Bt848 */
-static unsigned int vidmem=0; /* manually set video mem address */
-static int triton1=0;
-static int radio=0;
-
-static unsigned int card=CARD_DEFAULT;
-
#if LINUX_VERSION_CODE >= 0x020117
MODULE_PARM(remap,"i");
MODULE_PARM(vidmem,"i");
@@ -107,6 +103,13 @@ static void bt848_set_risc_jmps(struct bttv *btv);
/* Anybody who uses more than four? */
#define BTTV_MAX 4
+static unsigned int vidmem=0; /* manually set video mem address */
+static int triton1=0;
+
+static unsigned int remap[BTTV_MAX]; /* remap Bt848 */
+static unsigned int radio[BTTV_MAX];
+static unsigned int card[BTTV_MAX] = { CARD_DEFAULT };
+
static int bttv_num; /* number of Bt848s in use */
static struct bttv bttvs[BTTV_MAX];
@@ -221,7 +224,8 @@ static int fbuffer_alloc(struct bttv *btv)
if(!btv->fbuffer)
btv->fbuffer=(unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
else
- printk(KERN_ERR "bttv: Double alloc of fbuffer!\n");
+ printk(KERN_ERR "bttv%d: Double alloc of fbuffer!\n",
+ btv->nr);
if(!btv->fbuffer)
return -ENOBUFS;
return 0;
@@ -268,12 +272,17 @@ static int I2CRead(struct i2c_bus *bus, unsigned char addr)
stat=btread(BT848_INT_STAT);
if (stat & BT848_INT_I2CDONE)
break;
+#if LINUX_VERSION_CODE >= 0x020199
+ mdelay(1);
+#else
udelay(1000);
+#endif
}
if (!i)
{
- printk(KERN_DEBUG "bttv: I2CRead timeout\n");
+ printk(KERN_DEBUG "bttv%d: I2CRead timeout\n",
+ btv->nr);
return -1;
}
if (!(stat & BT848_INT_RACK))
@@ -310,12 +319,17 @@ static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
stat=btread(BT848_INT_STAT);
if (stat & BT848_INT_I2CDONE)
break;
+#if LINUX_VERSION_CODE >= 0x020199
+ mdelay(1);
+#else
udelay(1000);
+#endif
}
if (!i)
{
- printk(KERN_DEBUG "bttv: I2CWrite timeout\n");
+ printk(KERN_DEBUG "bttv%d: I2CWrite timeout\n",
+ btv->nr);
return -1;
}
if (!(stat & BT848_INT_RACK))
@@ -430,7 +444,7 @@ struct tvcard
u32 gpiomask;
u32 muxsel[8];
u32 audiomux[6]; /* Tuner, Radio, internal, external, mute, stereo */
-
+ u32 gpiomask2; /* GPIO MUX mask */
};
static struct tvcard tvcards[] =
@@ -450,34 +464,18 @@ static struct tvcard tvcards[] =
/* AVerMedia TVPhone */
{ 3, 0, 2,15, { 2, 3, 1, 1}, {12, 0,11,11, 0}},
/* Matrix Vision MV-Delta */
- { 5,-1, 4, 0, { 2, 3, 1, 0, 0}},
+ { 5,-1, 3, 0, { 2, 3, 1, 0, 0}},
/* Fly Video II */
{ 3, 0, 2, 0xc00, { 2, 3, 1, 1},
{0, 0xc00, 0x800, 0x400, 0xc00, 0}},
};
#define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
-/*
- * Tuner, Radio, internal, external and mute
- */
-
-static unsigned char audiomuxs[][5] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00}, /* unknown */
- { 0x02, 0x00, 0x00, 0x00, 0x0a}, /* MIRO */
- { 0x00, 0x01, 0x02, 0x03, 0x04}, /* Hauppauge */
- { 0x04, 0x00, 0x02, 0x03, 0x01}, /* STB */
- { 0x00, 0x01, 0x02, 0x03, 0x04}, /* Intel??? */
- { 0x00, 0x01, 0x00, 0x01, 0x03}, /* Diamond DTV2000 */
- { 0x0c, 0x00, 0x0b, 0x0b, 0x00}, /* AVerMedia TVPhone */
-};
-
static void audio(struct bttv *btv, int mode)
{
btaor(tvcards[btv->type].gpiomask, ~tvcards[btv->type].gpiomask,
BT848_GPIO_OUT_EN);
-
switch (mode)
{
case AUDIO_MUTE:
@@ -499,8 +497,12 @@ static void audio(struct bttv *btv, int mode)
break;
}
/* if audio mute or not in H-lock, turn audio off */
- if ((btv->audio&AUDIO_MUTE) ||
- (!btv->radio && !(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)))
+ if ((btv->audio&AUDIO_MUTE)
+#if 0
+ ||
+ (!btv->radio && !(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC))
+#endif
+ )
mode=AUDIO_OFF;
if ((mode == 0) && (btv->radio))
mode = 1;
@@ -561,6 +563,7 @@ static int set_pll(struct bttv *btv)
btwrite(0xdc,BT848_PLL_F_HI);
btwrite(0x8e,BT848_PLL_XCI);
+ /* Ugh ugh ugh .. schedule ? */
udelay(100000);
for (i=0; i<100; i++)
{
@@ -572,14 +575,19 @@ static int set_pll(struct bttv *btv)
btv->pll|=2;
return 1;
}
+#if LINUX_VERSION_CODE >= 0x020199
+ mdelay(10);
+#else
udelay(10000);
+#endif
}
return -1;
}
static void bt848_muxsel(struct bttv *btv, unsigned int input)
{
- btwrite(tvcards[btv->type].gpiomask, BT848_GPIO_OUT_EN);
+ btaor(tvcards[btv->type].gpiomask2,~tvcards[btv->type].gpiomask2,
+ BT848_GPIO_OUT_EN);
/* This seems to get rid of some synchronization problems */
btand(~(3<<5), BT848_IFORM);
@@ -601,24 +609,7 @@ static void bt848_muxsel(struct bttv *btv, unsigned int input)
audio(btv, (input!=tvcards[btv->type].tuner) ?
AUDIO_EXTERN : AUDIO_TUNER);
btaor(tvcards[btv->type].muxsel[input]>>4,
- ~tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
-
-/*
- if (input==3)
- {
- btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
- btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
- }
- else
- {
- btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
- btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
- }
- if (input==2)
- input=3;
- btaor(((input+2)&3)<<5, ~(3<<5), BT848_IFORM);
- audio(btv, input ? AUDIO_EXTERN : AUDIO_TUNER);
-*/
+ ~tvcards[btv->type].gpiomask2, BT848_GPIO_DATA);
}
@@ -681,14 +672,15 @@ static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
unsigned int *re, unsigned int *vbuf)
{
unsigned long line;
- unsigned long bpl=1024;
+ unsigned long bpl=1024; /* bytes per line */
unsigned long vadr=(unsigned long) vbuf;
*(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
/* In PAL 650 blocks of 256 DWORDs are sampled, but only if VDELAY
- is 2. We'll have to handle this inside the IRQ handler ... */
+ is 2 and without separate VBI grabbing.
+ We'll have to handle this inside the IRQ handler ... */
for (line=0; line < 640; line++)
{
@@ -894,77 +886,77 @@ static void make_clip_tab(struct bttv *btv, struct cliprec *cr, int count)
*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
/* loop through all lines */
- for (yy=0; yy<(height<<inter); yy++) {
- y=yy>>inter;
- rp= (yy&1) ? &re : &ro;
+ for (yy=0; yy<(height<<inter); yy++)
+ {
+ y=yy>>inter;
+ rp= (yy&1) ? &re : &ro;
- /* remove rects with y2 > y */
- if ((cur=first2.next))
- {
- prev=&first2;
- do
- {
- if (cur->y2 < y)
- prev->next=cur->next;
- else
- prev=cur;
- }
- while ((cur=cur->next));
- }
-
- /* add rect to second (x-sorted) list if rect.y == y */
- if ((cur=first.next))
- {
- while ((cur) && (cur->y == y))
- {
- first.next=cur->next;
- cur2=&first2;
- while ((nx2=cur2->next) && (cur->x > cur2->next->x))
- cur2=nx2;
- cur2->next=cur;
- cur->next=nx2;
- cur=first.next;
- }
- }
- x=0;
- if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight))
- write_risc_segment(rp, adr, BT848_RISC_SKIP, &x,
- width, bpp, width);
- else
- {
- dx=cx;
- for (cur2=first2.next; cur2; cur2=cur2->next)
- {
- if (x+dx < cur2->x)
- {
- write_risc_segment(rp, adr, BT848_RISC_SKIP,
- &x, dx, bpp, width);
- dx=cur2->x-x;
- write_risc_segment(rp, adr, BT848_RISC_WRITEC,
- &x, dx, bpp, width);
- dx=cur2->x2-x+1;
- }
- else
- if (x+dx < cur2->x2)
- dx=cur2->x2-x+1;
- }
- if (cx2<width)
- {
- write_risc_segment(rp, adr, BT848_RISC_SKIP,
- &x, dx, bpp, width);
- write_risc_segment(rp, adr, BT848_RISC_WRITEC,
- &x, cx2-x, bpp, width);
- dx=width-x;
- }
- write_risc_segment(rp, adr, BT848_RISC_SKIP,
- &x, dx, bpp, width);
- write_risc_segment(rp, adr, BT848_RISC_WRITEC,
- &x, width-x, bpp, width);
- }
- if ((!inter)||(yy&1))
- adr+=bpl;
+ /* remove rects with y2 > y */
+ if ((cur=first2.next))
+ {
+ prev=&first2;
+ do
+ {
+ if (cur->y2 < y)
+ prev->next=cur->next;
+ else
+ prev=cur;
+ }
+ while ((cur=cur->next));
+ }
+
+ /* add rect to second (x-sorted) list if rect.y == y */
+ if ((cur=first.next))
+ {
+ while ((cur) && (cur->y == y))
+ {
+ first.next=cur->next;
+ cur2=&first2;
+ while ((nx2=cur2->next) && (cur->x > cur2->next->x))
+ cur2=nx2;
+ cur2->next=cur;
+ cur->next=nx2;
+ cur=first.next;
+ }
+ }
+ x=0;
+ if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight))
+ write_risc_segment(rp, adr, BT848_RISC_SKIP, &x,
+ width, bpp, width);
+ else
+ {
+ dx=cx;
+ for (cur2=first2.next; cur2; cur2=cur2->next)
+ {
+ if (x+dx < cur2->x)
+ {
+ write_risc_segment(rp, adr, BT848_RISC_SKIP,
+ &x, dx, bpp, width);
+ dx=cur2->x-x;
+ write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+ &x, dx, bpp, width);
+ dx=cur2->x2-x+1;
+ }
+ else if (x+dx < cur2->x2)
+ dx=cur2->x2-x+1;
+ }
+ if (cx2<width)
+ {
+ write_risc_segment(rp, adr, BT848_RISC_SKIP,
+ &x, dx, bpp, width);
+ write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+ &x, cx2-x, bpp, width);
+ dx=width-x;
+ }
+ write_risc_segment(rp, adr, BT848_RISC_SKIP,
+ &x, dx, bpp, width);
+ write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+ &x, width-x, bpp, width);
+ }
+ if ((!inter)||(yy&1))
+ adr+=bpl;
}
-
+
*(ro++)=BT848_RISC_JUMP;
*(ro++)=btv->bus_vbi_even;
*(re++)=BT848_RISC_JUMP;
@@ -982,7 +974,7 @@ static void make_clip_tab(struct bttv *btv, struct cliprec *cr, int count)
struct tvnorm
{
- u16 cropwidth, cropheight;
+ u16 swidth, sheight; /* scaled standard width, height */
u16 totalwidth;
u8 adelay, bdelay, iform;
u32 scaledtwidth;
@@ -992,8 +984,15 @@ struct tvnorm
static struct tvnorm tvnorms[] = {
/* PAL-BDGHI */
+ //{ 1024, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+ // 1135, 100, 1024, 0x20},
+
+ { 914, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+ 1135, 186+16, 914, 0x20},
+/*
{ 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
944, 186, 922, 0x20},
+*/
/* NTSC */
{ 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
780, 135, 754, 0x16},
@@ -1059,6 +1058,10 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
tvn=&tvnorms[btv->win.norm];
+ btv->win.cropheight=tvn->sheight;
+ btv->win.cropwidth=tvn->swidth;
+
+/*
if (btv->win.cropwidth>tvn->cropwidth)
btv->win.cropwidth=tvn->cropwidth;
if (btv->win.cropheight>tvn->cropheight)
@@ -1068,7 +1071,7 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
width=btv->win.cropwidth;
if (height>btv->win.cropheight)
height=btv->win.cropheight;
-
+*/
btwrite(tvn->adelay, BT848_ADELAY);
btwrite(tvn->bdelay, BT848_BDELAY);
btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
@@ -1115,35 +1118,23 @@ int bpp2fmt[4] = {
static void bt848_set_winsize(struct bttv *btv)
{
unsigned short format;
- int bpp;
- btv->win.color_fmt=format= (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
- bpp2fmt[(btv->win.bpp-1)&3];
-/*
- bpp=fmtbppx2[btv->win.color_fmt&0x0f]/2;
- if (btv->win.bpp == 0)
- {
- btv->win.bpp=bpp;
- format=btv->win.color_fmt;
- }
- else if (btv->win.bpp!=bpp)
- btv->win.color_fmt=format=bpp2fmt[(btv->win.bpp-1)&3];
- else
- format=btv->win.color_fmt;
-*/
+ btv->win.color_fmt = format =
+ (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
+ bpp2fmt[(btv->win.bpp-1)&3];
+
/* RGB8 seems to be a 9x5x5 GRB color cube starting at
* color 16. Why the h... can't they even mention this in the
* datasheet??? [AC - because its a standard format so I guess
* it never occured them]
* Enable dithering in this mode
*/
-/*
if (format==BT848_COLOR_FMT_RGB8)
- btand(~0x10, BT848_CAP_CTL);
+ btand(~BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
else
- btor(0x10, BT848_CAP_CTL);
-*/
- bt848_set_geo(btv,btv->win.width, btv->win.height, format);
+ btor(BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
+
+ bt848_set_geo(btv, btv->win.width, btv->win.height, format);
}
/*
@@ -1709,7 +1700,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
v.flags=VIDEO_VC_AUDIO;
v.tuners=0;
v.type=VIDEO_TYPE_CAMERA;
+#if 0
v.mode = btv->win.norm;
+#endif
switch(v.channel)
{
case 0:
@@ -1739,15 +1732,11 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
*/
case VIDIOCSCHAN:
{
- struct video_channel v;
+ int v;
if(copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- bt848_muxsel(btv, v.channel);
- lastchan=v.channel;
-#if 0
- btv->win.norm = v.mode;
- bt848_set_winsize(btv);
-#endif
+ bt848_muxsel(btv, v);
+ lastchan=v;
return 0;
}
case VIDIOCGTUNER:
@@ -1760,8 +1749,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
strcpy(v.name, "Television");
v.rangelow=0;
v.rangehigh=0xFFFFFFFF;
- v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|
- VIDEO_TUNER_SECAM;
+ v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC;
v.mode = btv->win.norm;
if(copy_to_user(arg,&v,sizeof(v)))
return -EFAULT;
@@ -1770,18 +1758,19 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
/* We have but tuner 0 */
case VIDIOCSTUNER:
{
+ /* FIXME: norm should be in video_channel struct
+ composite source can have different norms too
+ */
+
struct video_tuner v;
if(copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- /* Only channel 0 has a tuner */
- if(v.tuner!=0 || lastchan)
- return -EINVAL;
+ /* Only 1 channel has a tuner */
+ /*if(v.tuner!=tvcards[btv->type].tuner || lastchan)
+ return -EINVAL;*/
if(v.mode!=VIDEO_MODE_PAL&&v.mode!=VIDEO_MODE_NTSC
&&v.mode!=VIDEO_MODE_SECAM)
return -EOPNOTSUPP;
- /* FIXME: norm should be in video_channel struct
- composite source can have different norms too
- */
btv->win.norm = v.mode;
bt848_set_winsize(btv);
return 0;
@@ -1819,7 +1808,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
bt848_hue(btv, (p.hue>>8)-128);
/* 0-511 */
bt848_contrast(btv, p.contrast>>7);
- btv->picture=p;
+ btv->picture = p;
/* set palette if bpp matches */
if (p.palette < sizeof(palette2fmt)/sizeof(int)) {
@@ -1941,23 +1930,33 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
case VIDIOCSFBUF:
{
struct video_buffer v;
+#if LINUX_VERSION_CODE >= 0x020100
+ if(!capable(CAP_SYS_ADMIN))
+#else
if(!suser())
+#endif
return -EPERM;
if(copy_from_user(&v, arg,sizeof(v)))
return -EFAULT;
if(v.depth!=8 && v.depth!=16 && v.depth!=15
&& v.depth!=24 && v.depth!=32)
return -EINVAL;
- if (v.base)
+ if (v.base)
+ {
/* also handle virtual base addresses */
if ((unsigned int)v.base>=0xe0000000UL)
btv->win.vidadr=(uint)v.base;
else
- btv->win.vidadr=PAGE_OFFSET|
- uvirt_to_bus((uint)v.base);
+ btv->win.vidadr=
+#if LINUX_VERSION_CODE >= 0x020199
+ __va(uvirt_to_bus((uint)v.base));
+#else
+ PAGE_OFFSET|uvirt_to_bus((uint)v.base);
+#endif
+ }
btv->win.sheight=v.height;
btv->win.swidth=v.width;
- btv->win.bpp=((v.depth+1)&0x18)/8;
+ btv->win.bpp=((v.depth+7)&0x38)/8;
btv->win.depth=v.depth;
btv->win.bpl=v.bytesperline;
@@ -2023,11 +2022,12 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
struct video_audio v;
if(copy_from_user(&v,arg, sizeof(v)))
return -EFAULT;
- if(v.audio<0||v.audio>2)
- return -EINVAL;
- bt848_muxsel(btv,v.audio);
if(v.flags&VIDEO_AUDIO_MUTE)
audio(btv, AUDIO_MUTE);
+ /* One audio source per tuner */
+ if(v.audio!=0)
+ return -EINVAL;
+ bt848_muxsel(btv,v.audio);
if(!(v.flags&VIDEO_AUDIO_MUTE))
audio(btv, AUDIO_UNMUTE);
if (btv->have_msp3400)
@@ -2073,7 +2073,11 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return 0;
case BTTV_WRITEE:
+#if LINUX_VERSION_CODE >= 0x020100
+ if(!capable(CAP_SYS_ADMIN))
+#else
if(!suser())
+#endif
return -EPERM;
if(copy_from_user((void *) eedata, (void *) arg, 256))
return -EFAULT;
@@ -2081,13 +2085,23 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return 0;
case BTTV_READEE:
+#if LINUX_VERSION_CODE >= 0x020100
+ if(!capable(CAP_SYS_ADMIN))
+#else
if(!suser())
+#endif
return -EPERM;
readee(&(btv->i2c), eedata);
if(copy_to_user((void *) arg, (void *) eedata, 256))
return -EFAULT;
break;
+ case BTTV_FIELDNR:
+ if(copy_to_user((void *) arg, (void *) &btv->last_field,
+ sizeof(btv->last_field)))
+ return -EFAULT;
+ break;
+
case VIDIOCMCAPTURE:
{
struct video_mmap vm;
@@ -2358,7 +2372,6 @@ static struct vidbases vbs[] = {
/* This id is not defined in pci.h but this entry was mailed to me?!?
{ PCI_VENDOR_ID_ALLIANCE, PCI_DEVICE_ID_ALLIANCE_AT25,
"Alliance AT25", PCI_BASE_ADDRESS_0},
-
*/
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_210888GX,
"ATI MACH64 Winturbo", PCI_BASE_ADDRESS_0},
@@ -2372,6 +2385,8 @@ static struct vidbases vbs[] = {
{ PCI_VENDOR_ID_MATROX, 0x051a, "Matrox Mystique", PCI_BASE_ADDRESS_1},
{ PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128,
"Number Nine Imagine 128", PCI_BASE_ADDRESS_0},
+ { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128_2,
+ "Number Nine Imagine 128 Series 2", PCI_BASE_ADDRESS_0},
{ PCI_VENDOR_ID_S3, 0, "S3", PCI_BASE_ADDRESS_0},
{ PCI_VENDOR_ID_TSENG, 0, "TSENG", PCI_BASE_ADDRESS_0},
};
@@ -2429,6 +2444,8 @@ static int find_vga(void)
break;
}
}
+ if (NR_CARDS == i)
+ printk("UNKNOWN.\n");
if (!badr)
{
printk(KERN_ERR "bttv: Unknown video memory base address.\n");
@@ -2444,7 +2461,7 @@ static int find_vga(void)
vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
if (!vidadr)
{
- printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!");
+ printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!\n");
continue;
}
@@ -2468,7 +2485,10 @@ static int find_vga(void)
if (vidmem)
{
- vidadr=vidmem<<20;
+ if (vidmem < 0x1000)
+ vidadr=vidmem<<20;
+ else
+ vidadr=vidmem;
printk(KERN_INFO "bttv: Video memory override: 0x%08x\n", vidadr);
found=1;
}
@@ -2562,7 +2582,8 @@ static void handle_chipset(void)
}
-static void init_tda8425(struct i2c_bus *bus) {
+static void init_tda8425(struct i2c_bus *bus)
+{
I2CWrite(bus, I2C_TDA8425, TDA8425_VL, 0xFC, 1); /* volume left 0dB */
I2CWrite(bus, I2C_TDA8425, TDA8425_VR, 0xFC, 1); /* volume right 0dB */
I2CWrite(bus, I2C_TDA8425, TDA8425_BA, 0xF6, 1); /* bass 0dB */
@@ -2587,14 +2608,16 @@ static void init_tda9850(struct i2c_bus *bus)
/* Figure out card and tuner type */
-static void idcard(struct bttv *btv)
+static void idcard(int i)
{
+ struct bttv *btv = &bttvs[i];
+
int tunertype;
btwrite(0, BT848_GPIO_OUT_EN);
- DEBUG(printk(KERN_DEBUG "bttv: GPIO: 0x%08x\n", btread(BT848_GPIO_DATA)));
+ DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", i, btread(BT848_GPIO_DATA)));
/* Default the card to the user-selected one. */
- btv->type=card;
+ btv->type=card[i];
/* If we were asked to auto-detect, then do so!
Right now this will only recognize Miro, Hauppauge or STB
@@ -2612,28 +2635,28 @@ static void idcard(struct bttv *btv)
if (I2CRead(&(btv->i2c), I2C_TDA9850) >=0)
{
- btv->audio_chip = TDA9850;
- printk("bttv: audio chip: TDA9850\n");
+ btv->audio_chip = TDA9850;
+ printk(KERN_INFO "bttv%d: audio chip: TDA9850\n",btv->nr);
}
if (I2CRead(&(btv->i2c), I2C_TDA8425) >=0)
{
- btv->audio_chip = TDA8425;
- printk("bttv: audio chip: TDA8425\n");
+ btv->audio_chip = TDA8425;
+ printk(KERN_INFO "bttv%d: audio chip: TDA8425\n",btv->nr);
}
switch(btv->audio_chip)
{
case TDA9850:
init_tda9850(&(btv->i2c));
- break;
+ break;
case TDA8425:
init_tda8425(&(btv->i2c));
break;
}
-
+
/* How do I detect the tuner type for other cards but Miro ??? */
- printk(KERN_INFO "bttv: model: ");
+ printk(KERN_INFO "bttv%d: model: ",btv->nr);
switch (btv->type)
{
case BTTV_MIRO:
@@ -2729,8 +2752,6 @@ static void bt848_set_risc_jmps(struct bttv *btv)
bt848_dma(btv, 0);
}
-
-
static int init_bt848(int i)
{
struct bttv *btv = &bttvs[i];
@@ -2739,15 +2760,9 @@ static int init_bt848(int i)
/* reset the bt848 */
btwrite(0, BT848_SRESET);
-
-
- //set_pll(btv);
-
- DEBUG(printk(KERN_DEBUG "bttv: bt848_mem: 0x%08x\n",(unsigned int) btv->bt848_mem));
-
+ DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%08x\n",i,(unsigned int) btv->bt848_mem));
/* default setup for max. PAL size in a 1024xXXX hicolor framebuffer */
-
btv->win.norm=0; /* change this to 1 for NTSC, 2 for SECAM */
btv->win.interlace=1;
btv->win.x=0;
@@ -2776,6 +2791,7 @@ static int init_bt848(int i)
btv->grabcount=0;
btv->grab=0;
btv->lastgrab=0;
+ btv->field=btv->last_field=0;
/* i2c */
memcpy(&(btv->i2c),&bttv_i2c_bus_template,sizeof(struct i2c_bus));
@@ -2825,8 +2841,8 @@ static int init_bt848(int i)
btwrite(0xd8, BT848_CONTRAST_LO);
bt848_bright(btv, 0x10);
- btwrite(0x60, BT848_E_VSCALE_HI);
- btwrite(0x60, BT848_O_VSCALE_HI);
+ btwrite(0x20, BT848_E_VSCALE_HI);
+ btwrite(0x20, BT848_O_VSCALE_HI);
btwrite(/*BT848_ADC_SYNC_T|*/
BT848_ADC_RESERVED|BT848_ADC_CRUSH, BT848_ADC);
@@ -2846,11 +2862,12 @@ static int init_bt848(int i)
/* set interrupt mask */
btwrite(triton1|
-/* BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
- BT848_INT_FDSR|BT848_INT_FTRGT|BT848_INT_FBUS|*/
+ /*BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
+ BT848_INT_FDSR|BT848_INT_FTRGT|eBT848_INT_FBUS|*/
+ BT848_INT_VSYNC|
BT848_INT_SCERR|
BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
- BT848_INT_FMTCHG|BT848_INT_HLOCK,
+ BT848_INT_FMTCHG|BT848_INT_HLOCK,
BT848_INT_MASK);
make_vbitab(btv);
@@ -2863,7 +2880,7 @@ static int init_bt848(int i)
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(btv);
+ idcard(i);
if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER)<0)
return -1;
@@ -2903,28 +2920,29 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
if (!astat)
return;
btwrite(astat,BT848_INT_STAT);
- IDEBUG(printk ("bttv: astat %08x\n",astat));
- IDEBUG(printk ("bttv: stat %08x\n",stat));
+ IDEBUG(printk ("bttv%d: astat %08x\n", btv->nr,astat));
+ IDEBUG(printk ("bttv%d: stat %08x\n", btv->nr,stat));
/* get device status bits */
dstat=btread(BT848_DSTATUS);
if (astat&BT848_INT_FMTCHG)
{
- IDEBUG(printk ("bttv: IRQ_FMTCHG\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FMTCHG\n", btv->nr));
/*btv->win.norm&=
(dstat&BT848_DSTATUS_NUML) ? (~1) : (~0); */
}
if (astat&BT848_INT_VPRES)
{
- IDEBUG(printk ("bttv: IRQ_VPRES\n"));
+ IDEBUG(printk ("bttv%d: IRQ_VPRES\n", btv->nr));
}
if (astat&BT848_INT_VSYNC)
{
- IDEBUG(printk ("bttv: IRQ_VSYNC\n"));
+ IDEBUG(printk ("bttv%d: IRQ_VSYNC\n",btv->nr));
+ btv->field++;
}
if (astat&BT848_INT_SCERR) {
- IDEBUG(printk ("bttv: IRQ_SCERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_SCERR\n", btv->nr));
bt848_dma(btv, 0);
bt848_dma(btv, 1);
wake_up_interruptible(&btv->vbiq);
@@ -2933,7 +2951,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
}
if (astat&BT848_INT_RISCI)
{
- IDEBUG(printk ("bttv: IRQ_RISCI\n"));
+ IDEBUG(printk ("bttv%d: IRQ_RISCI\n", btv->nr));
/* captured VBI frame */
if (stat&(1<<28))
@@ -2945,6 +2963,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
/* captured full frame */
if (stat&(2<<28))
{
+ btv->last_field=btv->field;
btv->grab++;
btv->frame_stat[btv->grf] = GBUFFER_DONE;
if ((--btv->grabbing))
@@ -2977,31 +2996,31 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
}
if (astat&BT848_INT_OCERR)
{
- IDEBUG(printk ("bttv: IRQ_OCERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_OCERR\n", btv->nr));
}
if (astat&BT848_INT_PABORT)
{
- IDEBUG(printk ("bttv: IRQ_PABORT\n"));
+ IDEBUG(printk ("bttv%d: IRQ_PABORT\n", btv->nr));
}
if (astat&BT848_INT_RIPERR)
{
- IDEBUG(printk ("bttv: IRQ_RIPERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_RIPERR\n", btv->nr));
}
if (astat&BT848_INT_PPERR)
{
- IDEBUG(printk ("bttv: IRQ_PPERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_PPERR\n", btv->nr));
}
if (astat&BT848_INT_FDSR)
{
- IDEBUG(printk ("bttv: IRQ_FDSR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FDSR\n", btv->nr));
}
if (astat&BT848_INT_FTRGT)
{
- IDEBUG(printk ("bttv: IRQ_FTRGT\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FTRGT\n", btv->nr));
}
if (astat&BT848_INT_FBUS)
{
- IDEBUG(printk ("bttv: IRQ_FBUS\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FBUS\n", btv->nr));
}
if (astat&BT848_INT_HLOCK)
{
@@ -3017,12 +3036,14 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
count++;
if (count > 10)
- printk (KERN_WARNING "bttv: irq loop %d\n", count);
+ printk (KERN_WARNING "bttv%d: irq loop %d\n",
+ btv->nr,count);
if (count > 20)
{
btwrite(0, BT848_INT_MASK);
printk(KERN_ERR
- "bttv: IRQ lockup, cleared int mask\n");
+ "bttv%d: IRQ lockup, cleared int mask\n",
+ btv->nr);
}
}
}
@@ -3045,18 +3066,23 @@ static int find_bt848(void)
if (!pcibios_present())
{
- DEBUG(printk(KERN_DEBUG "bttv: PCI-BIOS not present or not accessable!\n"));
+ DEBUG(printk(KERN_DEBUG "bttv%d: PCI-BIOS not present or not accessable!\n",bttv_num));
return 0;
}
for (pci_index = 0;
!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
- pci_index, &bus, &devfn)
- ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
- pci_index, &bus, &devfn);
- ++pci_index)
+ pci_index, &bus, &devfn)
+ ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
+ pci_index, &bus, &devfn)
+ ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
+ pci_index, &bus, &devfn)
+ ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
+ pci_index, &bus, &devfn);
+ ++pci_index)
{
btv=&bttvs[bttv_num];
+ btv->nr = bttv_num;
btv->bus=bus;
btv->devfn=devfn;
btv->bt848_mem=NULL;
@@ -3078,14 +3104,16 @@ static int find_bt848(void)
pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
&btv->bt848_adr);
- if (remap&&(!bttv_num))
- {
- remap<<=20;
- remap&=PCI_BASE_ADDRESS_MEM_MASK;
- printk(KERN_INFO "Remapping to : 0x%08x.\n", remap);
- remap|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
+ if (remap[bttv_num])
+ {
+ if (remap[bttv_num] < 0x1000)
+ remap[bttv_num]<<=20;
+ remap[bttv_num]&=PCI_BASE_ADDRESS_MEM_MASK;
+ printk(KERN_INFO "bttv%d: remapping to : 0x%08x.\n",
+ bttv_num,remap[bttv_num]);
+ remap[bttv_num]|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
pcibios_write_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
- remap);
+ remap[bttv_num]);
pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
&btv->bt848_adr);
}
@@ -3093,18 +3121,18 @@ static int find_bt848(void)
btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
pcibios_read_config_byte(btv->bus, btv->devfn, PCI_CLASS_REVISION,
&btv->revision);
- printk(KERN_INFO "bttv: Brooktree Bt%d (rev %d) ",
- btv->id, btv->revision);
+ printk(KERN_INFO "bttv%d: Brooktree Bt%d (rev %d) ",
+ bttv_num,btv->id, btv->revision);
printk("bus: %d, devfn: %d, ",
- btv->bus, btv->devfn);
+ btv->bus, btv->devfn);
printk("irq: %d, ",btv->irq);
printk("memory: 0x%08x.\n", btv->bt848_adr);
btv->pll=0;
#ifdef USE_PLL
- if (btv->id==849 || (btv->id==848 && btv->revision==0x12))
+ if (!(btv->id==848 && btv->revision==0x11))
{
- printk("bttv: internal PLL, single crystal operation enabled\n");
+ printk(KERN_INFO "bttv%d: internal PLL, single crystal operation enabled\n",bttv_num);
btv->pll=1;
}
#endif
@@ -3115,12 +3143,13 @@ static int find_bt848(void)
SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
if (result==-EINVAL)
{
- printk(KERN_ERR "bttv: Bad irq number or handler\n");
+ printk(KERN_ERR "bttv%d: Bad irq number or handler\n",
+ bttv_num);
return -EINVAL;
}
if (result==-EBUSY)
{
- printk(KERN_ERR "bttv: IRQ %d busy, change your PnP config in BIOS\n",btv->irq);
+ printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
return result;
}
if (result < 0)
@@ -3133,7 +3162,7 @@ static int find_bt848(void)
pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
if (!(command&PCI_COMMAND_MASTER))
{
- printk(KERN_ERR "bttv: PCI bus-mastering could not be enabled\n");
+ printk(KERN_ERR "bttv%d: PCI bus-mastering could not be enabled\n",bttv_num);
return -1;
}
pcibios_read_config_byte(btv->bus, btv->devfn, PCI_LATENCY_TIMER,
@@ -3144,7 +3173,8 @@ static int find_bt848(void)
pcibios_write_config_byte(btv->bus, btv->devfn,
PCI_LATENCY_TIMER, latency);
}
- DEBUG(printk(KERN_DEBUG "bttv: latency: %02x\n", latency));
+ DEBUG(printk(KERN_DEBUG "bttv%d: latency: %02x\n",
+ bttv_num, latency));
bttv_num++;
}
if(bttv_num)
diff --git a/bttv/driver/bttv.h b/bttv/driver/bttv.h
index c202f5e..73bdcf0 100644
--- a/bttv/driver/bttv.h
+++ b/bttv/driver/bttv.h
@@ -77,6 +77,7 @@ struct bttv
int have_msp3400;
int have_tuner;
+ unsigned int nr;
unsigned short id;
unsigned char bus; /* PCI bus the Bt848 is on */
unsigned char devfn;
@@ -136,6 +137,8 @@ struct bttv
int grabcount;
int pll;
+ unsigned int field;
+ unsigned int last_field; /* number of last grabbed field */
};
#endif
@@ -160,6 +163,7 @@ struct bttv
#define BTTV_READEE _IOW('v', BASE_VIDIOCPRIVATE+0, char [256])
#define BTTV_WRITEE _IOR('v', BASE_VIDIOCPRIVATE+1, char [256])
#define BTTV_GRAB _IOR('v' , BASE_VIDIOCPRIVATE+2, struct gbuf)
+#define BTTV_FIELDNR _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)
#define BTTV_UNKNOWN 0x00
diff --git a/bttv/driver/i2c.c b/bttv/driver/i2c.c
index 736ddc5..f8c8d55 100644
--- a/bttv/driver/i2c.c
+++ b/bttv/driver/i2c.c
@@ -1,7 +1,7 @@
/*
- * Generic i2c interface for linux
+ * Generic i2c interface for linux
*
- * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
*
*/
@@ -23,6 +23,7 @@
static int scan = 0;
static int verbose = 1;
static int i2c_debug = 0;
+
#if LINUX_VERSION_CODE >= 0x020117
MODULE_PARM(scan,"i");
MODULE_PARM(verbose,"i");
@@ -37,221 +38,238 @@ static int bus_count = 0, driver_count = 0;
int i2c_init(void)
{
- printk(KERN_INFO "i2c: initialized%s\n",
- scan ? " (i2c bus scan enabled)" : "");
- /* anything to do here ? */
- return 0;
+ printk(KERN_INFO "i2c: initialized%s\n",
+ scan ? " (i2c bus scan enabled)" : "");
+ /* anything to do here ? */
+ return 0;
}
/* ----------------------------------------------------------------------- */
static void i2c_attach_device(struct i2c_bus *bus, struct i2c_driver *driver)
{
- unsigned long flags;
- struct i2c_device *device;
- int i,j,ack=1;
- unsigned char addr;
+ unsigned long flags;
+ struct i2c_device *device;
+ int i,j,ack=1;
+ unsigned char addr;
- /* probe for device */
- LOCK_I2C_BUS(bus);
- for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2) {
- i2c_start(bus);
- ack = i2c_sendbyte(bus,addr,0);
- i2c_stop(bus);
- if (!ack)
- break;
- }
- UNLOCK_I2C_BUS(bus);
- if (ack)
- return;
-
- /* got answer */
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (NULL == driver->devices[i])
- break;
- if (I2C_DEVICE_MAX == i)
- return;
-
- for (j = 0; j < I2C_DEVICE_MAX; j++)
- if (NULL == bus->devices[j])
- break;
- if (I2C_DEVICE_MAX == j)
- return;
-
- if (NULL == (device = kmalloc(sizeof(struct i2c_device),GFP_KERNEL)))
- return;
- device->bus = bus;
- device->driver = driver;
- device->addr = addr;
-
- /* attach */
- if (0 != driver->attach(device)) {
- kfree(device);
- return;
- }
- driver->devices[i] = device;
- driver->devcount++;
- bus->devices[j] = device;
- bus->devcount++;
-
- if (bus->attach_inform)
- bus->attach_inform(bus,driver->id);
- REGPRINT(printk("i2c: device attached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,addr,bus->name,driver->name));
+ /* probe for device */
+ LOCK_I2C_BUS(bus);
+ for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2)
+ {
+ i2c_start(bus);
+ ack = i2c_sendbyte(bus,addr,0);
+ i2c_stop(bus);
+ if (!ack)
+ break;
+ }
+ UNLOCK_I2C_BUS(bus);
+ if (ack)
+ return;
+
+ /* got answer */
+ for (i = 0; i < I2C_DEVICE_MAX; i++)
+ if (NULL == driver->devices[i])
+ break;
+ if (I2C_DEVICE_MAX == i)
+ return;
+
+ for (j = 0; j < I2C_DEVICE_MAX; j++)
+ if (NULL == bus->devices[j])
+ break;
+ if (I2C_DEVICE_MAX == j)
+ return;
+
+ if (NULL == (device = kmalloc(sizeof(struct i2c_device),GFP_KERNEL)))
+ return;
+ device->bus = bus;
+ device->driver = driver;
+ device->addr = addr;
+
+ /* Attach */
+
+ if (driver->attach(device)!=0)
+ {
+ kfree(device);
+ return;
+ }
+ driver->devices[i] = device;
+ driver->devcount++;
+ bus->devices[j] = device;
+ bus->devcount++;
+
+ if (bus->attach_inform)
+ bus->attach_inform(bus,driver->id);
+ REGPRINT(printk("i2c: device attached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,addr,bus->name,driver->name));
}
static void i2c_detach_device(struct i2c_device *device)
{
- int i;
-
- if (device->bus->detach_inform)
- device->bus->detach_inform(device->bus,device->driver->id);
- device->driver->detach(device);
-
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (device == device->driver->devices[i])
- break;
- if (I2C_DEVICE_MAX == i) {
- printk(KERN_WARNING "i2c: detach_device #1: device not found: %s\n",
- device->name);
- return;
- }
- device->driver->devices[i] = NULL;
- device->driver->devcount--;
-
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (device == device->bus->devices[i])
- break;
- if (I2C_DEVICE_MAX == i) {
- printk(KERN_WARNING "i2c: detach_device #2: device not found: %s\n",
- device->name);
- return;
- }
- device->bus->devices[i] = NULL;
- device->bus->devcount--;
-
- REGPRINT(printk("i2c: device detached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,device->addr,device->bus->name,device->driver->name));
- kfree(device);
+ int i;
+
+ if (device->bus->detach_inform)
+ device->bus->detach_inform(device->bus,device->driver->id);
+ device->driver->detach(device);
+
+ for (i = 0; i < I2C_DEVICE_MAX; i++)
+ if (device == device->driver->devices[i])
+ break;
+ if (I2C_DEVICE_MAX == i)
+ {
+ printk(KERN_WARNING "i2c: detach_device #1: device not found: %s\n",
+ device->name);
+ return;
+ }
+ device->driver->devices[i] = NULL;
+ device->driver->devcount--;
+
+ for (i = 0; i < I2C_DEVICE_MAX; i++)
+ if (device == device->bus->devices[i])
+ break;
+ if (I2C_DEVICE_MAX == i)
+ {
+ printk(KERN_WARNING "i2c: detach_device #2: device not found: %s\n",
+ device->name);
+ return;
+ }
+ device->bus->devices[i] = NULL;
+ device->bus->devcount--;
+
+ REGPRINT(printk("i2c: device detached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,device->addr,device->bus->name,device->driver->name));
+ kfree(device);
}
/* ----------------------------------------------------------------------- */
int i2c_register_bus(struct i2c_bus *bus)
{
- unsigned long flags;
- int i,ack;
-
- memset(bus->devices,0,sizeof(bus->devices));
- bus->devcount = 0;
-
- for (i = 0; i < I2C_BUS_MAX; i++)
- if (NULL == busses[i])
- break;
- if (I2C_BUS_MAX == i)
- return -ENOMEM;
-
- busses[i] = bus;
- bus_count++;
- REGPRINT(printk("i2c: bus registered: %s\n",bus->name));
-
- LOCK_I2C_BUS(bus);
- i2c_reset(bus);
- if (scan) {
- /* scan whole i2c bus */
- for (i = 0; i < 256; i+=2) {
- i2c_start(bus);
- ack = i2c_sendbyte(bus,i,0);
- i2c_stop(bus);
- if (!ack) {
- printk("i2c: scanning bus %s: found device at addr=0x%02x\n",
- bus->name,i);
- }
+ unsigned long flags;
+ int i,ack;
+
+ memset(bus->devices,0,sizeof(bus->devices));
+ bus->devcount = 0;
+
+ for (i = 0; i < I2C_BUS_MAX; i++)
+ if (NULL == busses[i])
+ break;
+ if (I2C_BUS_MAX == i)
+ return -ENOMEM;
+
+ busses[i] = bus;
+ bus_count++;
+ REGPRINT(printk("i2c: bus registered: %s\n",bus->name));
+
+ MOD_INC_USE_COUNT;
+
+ if (scan)
+ {
+ /* scan whole i2c bus */
+ LOCK_I2C_BUS(bus);
+ for (i = 0; i < 256; i+=2)
+ {
+ i2c_start(bus);
+ ack = i2c_sendbyte(bus,i,0);
+ i2c_stop(bus);
+ if (!ack)
+ {
+ printk(KERN_INFO "i2c: scanning bus %s: found device at addr=0x%02x\n",
+ bus->name,i);
+ }
+ }
+ UNLOCK_I2C_BUS(bus);
}
- }
- UNLOCK_I2C_BUS(bus);
-
- /* probe available drivers */
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (drivers[i])
- i2c_attach_device(bus,drivers[i]);
- return 0;
+ /* probe available drivers */
+ for (i = 0; i < I2C_DRIVER_MAX; i++)
+ if (drivers[i])
+ i2c_attach_device(bus,drivers[i]);
+ return 0;
}
int i2c_unregister_bus(struct i2c_bus *bus)
{
- int i;
-
- /* detach devices */
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (bus->devices[i])
- i2c_detach_device(bus->devices[i]);
-
- for (i = 0; i < I2C_BUS_MAX; i++)
- if (bus == busses[i])
- break;
- if (I2C_BUS_MAX == i) {
- printk(KERN_WARNING "i2c: unregister_bus #1: bus not found: %s\n",
- bus->name);
- return -ENODEV;
- }
-
- busses[i] = NULL;
- bus_count--;
- REGPRINT(printk("i2c: bus unregistered: %s\n",bus->name));
-
- return 0;
+ int i;
+
+ /* detach devices */
+ for (i = 0; i < I2C_DEVICE_MAX; i++)
+ if (bus->devices[i])
+ i2c_detach_device(bus->devices[i]);
+
+ for (i = 0; i < I2C_BUS_MAX; i++)
+ if (bus == busses[i])
+ break;
+ if (I2C_BUS_MAX == i)
+ {
+ printk(KERN_WARNING "i2c: unregister_bus #1: bus not found: %s\n",
+ bus->name);
+ return -ENODEV;
+ }
+
+ MOD_DEC_USE_COUNT;
+
+ busses[i] = NULL;
+ bus_count--;
+ REGPRINT(printk("i2c: bus unregistered: %s\n",bus->name));
+
+ return 0;
}
/* ----------------------------------------------------------------------- */
int i2c_register_driver(struct i2c_driver *driver)
{
- int i;
-
- memset(driver->devices,0,sizeof(driver->devices));
- driver->devcount = 0;
-
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (NULL == drivers[i])
- break;
- if (I2C_DRIVER_MAX == i)
- return -ENOMEM;
-
- drivers[i] = driver;
- driver_count++;
- REGPRINT(printk("i2c: driver registered: %s\n",driver->name));
-
- /* probe available busses */
- for (i = 0; i < I2C_BUS_MAX; i++)
- if (busses[i])
- i2c_attach_device(busses[i],driver);
-
- return 0;
+ int i;
+
+ memset(driver->devices,0,sizeof(driver->devices));
+ driver->devcount = 0;
+
+ for (i = 0; i < I2C_DRIVER_MAX; i++)
+ if (NULL == drivers[i])
+ break;
+ if (I2C_DRIVER_MAX == i)
+ return -ENOMEM;
+
+ drivers[i] = driver;
+ driver_count++;
+
+ MOD_INC_USE_COUNT;
+
+ REGPRINT(printk("i2c: driver registered: %s\n",driver->name));
+
+ /* Probe available busses */
+ for (i = 0; i < I2C_BUS_MAX; i++)
+ if (busses[i])
+ i2c_attach_device(busses[i],driver);
+
+ return 0;
}
int i2c_unregister_driver(struct i2c_driver *driver)
{
- int i;
-
- /* detach devices */
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (driver->devices[i])
- i2c_detach_device(driver->devices[i]);
-
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (driver == drivers[i])
- break;
- if (I2C_DRIVER_MAX == i) {
- printk(KERN_WARNING "i2c: unregister_driver: driver not found: %s\n",
- driver->name);
- return -ENODEV;
- }
-
- drivers[i] = NULL;
- driver_count--;
- REGPRINT(printk("i2c: driver unregistered: %s\n",driver->name));
-
- return 0;
+ int i;
+
+ /* detach devices */
+ for (i = 0; i < I2C_DEVICE_MAX; i++)
+ if (driver->devices[i])
+ i2c_detach_device(driver->devices[i]);
+
+ for (i = 0; i < I2C_DRIVER_MAX; i++)
+ if (driver == drivers[i])
+ break;
+ if (I2C_DRIVER_MAX == i)
+ {
+ printk(KERN_WARNING "i2c: unregister_driver: driver not found: %s\n",
+ driver->name);
+ return -ENODEV;
+ }
+
+ MOD_DEC_USE_COUNT;
+
+ drivers[i] = NULL;
+ driver_count--;
+ REGPRINT(printk("i2c: driver unregistered: %s\n",driver->name));
+
+ return 0;
}
/* ----------------------------------------------------------------------- */
@@ -259,16 +277,16 @@ int i2c_unregister_driver(struct i2c_driver *driver)
int i2c_control_device(struct i2c_bus *bus, int id,
unsigned int cmd, void *arg)
{
- int i;
-
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (bus->devices[i] && bus->devices[i]->driver->id == id)
- break;
- if (i == I2C_DEVICE_MAX)
- return -ENODEV;
- if (NULL == bus->devices[i]->driver->command)
- return -ENODEV;
- return bus->devices[i]->driver->command(bus->devices[i],cmd,arg);
+ int i;
+
+ for (i = 0; i < I2C_DEVICE_MAX; i++)
+ if (bus->devices[i] && bus->devices[i]->driver->id == id)
+ break;
+ if (i == I2C_DEVICE_MAX)
+ return -ENODEV;
+ if (NULL == bus->devices[i]->driver->command)
+ return -ENODEV;
+ return bus->devices[i]->driver->command(bus->devices[i],cmd,arg);
}
/* ----------------------------------------------------------------------- */
@@ -276,116 +294,111 @@ int i2c_control_device(struct i2c_bus *bus, int id,
#define I2C_SET(bus,ctrl,data) (bus->i2c_setlines(bus,ctrl,data))
#define I2C_GET(bus) (bus->i2c_getdataline(bus))
-void i2c_reset(struct i2c_bus *bus)
-{
- I2C_SET(bus,1,1);
- I2C_DEBUG(printk("%s: bus reset",bus->name));
-}
-
void i2c_start(struct i2c_bus *bus)
{
- I2C_SET(bus,0,1);
- I2C_SET(bus,1,1);
- I2C_SET(bus,1,0);
- I2C_SET(bus,0,0);
- I2C_DEBUG(printk("%s: < ",bus->name));
+ I2C_SET(bus,0,1);
+ I2C_SET(bus,1,1);
+ I2C_SET(bus,1,0);
+ I2C_SET(bus,0,0);
+ I2C_DEBUG(printk("%s: < ",bus->name));
}
void i2c_stop(struct i2c_bus *bus)
{
- I2C_SET(bus,0,0);
- I2C_SET(bus,1,0);
- I2C_SET(bus,1,1);
- I2C_DEBUG(printk(">\n"));
+ I2C_SET(bus,0,0);
+ I2C_SET(bus,1,0);
+ I2C_SET(bus,1,1);
+ I2C_DEBUG(printk(">\n"));
}
void i2c_one(struct i2c_bus *bus)
{
- I2C_SET(bus,0,1);
- I2C_SET(bus,1,1);
- I2C_SET(bus,0,1);
+ I2C_SET(bus,0,1);
+ I2C_SET(bus,1,1);
+ I2C_SET(bus,0,1);
}
void i2c_zero(struct i2c_bus *bus)
{
- I2C_SET(bus,0,0);
- I2C_SET(bus,1,0);
- I2C_SET(bus,0,0);
+ I2C_SET(bus,0,0);
+ I2C_SET(bus,1,0);
+ I2C_SET(bus,0,0);
}
int i2c_ack(struct i2c_bus *bus)
{
- int ack;
+ int ack;
- I2C_SET(bus,0,1);
- I2C_SET(bus,1,1);
- ack = I2C_GET(bus);
- I2C_SET(bus,0,1);
- return ack;
+ I2C_SET(bus,0,1);
+ I2C_SET(bus,1,1);
+ ack = I2C_GET(bus);
+ I2C_SET(bus,0,1);
+ return ack;
}
int i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack)
{
- int i, ack;
+ int i, ack;
- I2C_SET(bus,0,0);
- for (i=7; i>=0; i--)
- (data&(1<<i)) ? i2c_one(bus) : i2c_zero(bus);
- if (wait_for_ack)
- udelay(wait_for_ack);
- ack=i2c_ack(bus);
- I2C_DEBUG(printk("%02x%c ",(int)data,ack?'-':'+'));
- return ack;
+ I2C_SET(bus,0,0);
+ for (i=7; i>=0; i--)
+ (data&(1<<i)) ? i2c_one(bus) : i2c_zero(bus);
+ if (wait_for_ack)
+ udelay(wait_for_ack);
+ ack=i2c_ack(bus);
+ I2C_DEBUG(printk("%02x%c ",(int)data,ack?'-':'+'));
+ return ack;
}
unsigned char i2c_readbyte(struct i2c_bus *bus,int last)
{
- int i;
- unsigned char data=0;
+ int i;
+ unsigned char data=0;
- I2C_SET(bus,0,1);
- for (i=7; i>=0; i--) {
- I2C_SET(bus,1,1);
- if (I2C_GET(bus))
- data |= (1<<i);
I2C_SET(bus,0,1);
- }
- last ? i2c_one(bus) : i2c_zero(bus);
- I2C_DEBUG(printk("=%02x%c ",(int)data,last?'-':'+'));
- return data;
+ for (i=7; i>=0; i--)
+ {
+ I2C_SET(bus,1,1);
+ if (I2C_GET(bus))
+ data |= (1<<i);
+ I2C_SET(bus,0,1);
+ }
+ last ? i2c_one(bus) : i2c_zero(bus);
+ I2C_DEBUG(printk("=%02x%c ",(int)data,last?'-':'+'));
+ return data;
}
/* ----------------------------------------------------------------------- */
int i2c_read(struct i2c_bus *bus, unsigned char addr)
{
- int ret;
+ int ret;
- if (bus->i2c_read)
- return bus->i2c_read(bus, addr);
-
- i2c_start(bus);
- i2c_sendbyte(bus,addr,0);
- ret = i2c_readbyte(bus,1);
- i2c_stop(bus);
- return ret;
+ if (bus->i2c_read)
+ return bus->i2c_read(bus, addr);
+
+ i2c_start(bus);
+ i2c_sendbyte(bus,addr,0);
+ ret = i2c_readbyte(bus,1);
+ i2c_stop(bus);
+ return ret;
}
int i2c_write(struct i2c_bus *bus, unsigned char addr,
unsigned char data1, unsigned char data2, int both)
{
- int ack;
-
- if (bus->i2c_write)
- return bus->i2c_write(bus, addr, data1, data2, both);
-
- i2c_start(bus);
- i2c_sendbyte(bus,addr,0);
- ack = i2c_sendbyte(bus,data1,0);
- if (both)
- ack = i2c_sendbyte(bus,data2,0);
- i2c_stop(bus);
- return ack ? -1 : 0 ;
+ int ack;
+
+ if (bus->i2c_write)
+ return bus->i2c_write(bus, addr, data1, data2, both);
+
+ i2c_start(bus);
+ i2c_sendbyte(bus,addr,0);
+ ack = i2c_sendbyte(bus,data1,0);
+ if (both)
+ ack = i2c_sendbyte(bus,data2,0);
+ i2c_stop(bus);
+ return ack ? -1 : 0 ;
}
/* ----------------------------------------------------------------------- */
@@ -398,7 +411,6 @@ EXPORT_SYMBOL(i2c_unregister_bus);
EXPORT_SYMBOL(i2c_register_driver);
EXPORT_SYMBOL(i2c_unregister_driver);
EXPORT_SYMBOL(i2c_control_device);
-EXPORT_SYMBOL(i2c_reset);
EXPORT_SYMBOL(i2c_start);
EXPORT_SYMBOL(i2c_stop);
EXPORT_SYMBOL(i2c_one);
@@ -412,11 +424,10 @@ EXPORT_SYMBOL(i2c_write);
int init_module(void)
{
- return i2c_init();
+ return i2c_init();
}
void cleanup_module(void)
{
}
-
#endif
diff --git a/bttv/driver/i2c.h b/bttv/driver/i2c.h
index 6bdba73..e2e6f21 100644
--- a/bttv/driver/i2c.h
+++ b/bttv/driver/i2c.h
@@ -10,7 +10,7 @@
* chip driver a driver for a chip connected
* to a i2c bus (cdrom/hd driver)
*
- * a devices will be attached to one bus and one chip driver. Every chip
+ * A device will be attached to one bus and one chip driver. Every chip
* driver gets a unique ID.
*
* A chip driver can provide a ioctl-like callback for the
@@ -32,10 +32,9 @@ struct i2c_device;
#define I2C_DRIVERID_MSP3400 1
#define I2C_DRIVERID_TUNER 2
-#define I2C_DRIVERID_VIDEOTEXT 3
-#define I2C_DRIVERID_CHARDEV 4
+#define I2C_DRIVERID_VIDEOTEXT 3
-#define I2C_BUSID_BT848 1
+#define I2C_BUSID_BT848 1 /* I2C bus on a BT848 */
/*
* struct for a driver for a i2c chip (tuner, soundprocessor,
@@ -54,15 +53,15 @@ struct i2c_device;
*
*/
-struct i2c_driver {
+struct i2c_driver
+{
char name[32]; /* some useful label */
int id; /* device type ID */
unsigned char addr_l, addr_h; /* address range of the chip */
int (*attach)(struct i2c_device *device);
int (*detach)(struct i2c_device *device);
- int (*command)(struct i2c_device *device,
- unsigned int cmd, void *arg);
+ int (*command)(struct i2c_device *device,unsigned int cmd, void *arg);
/* i2c internal */
struct i2c_device *devices[I2C_DEVICE_MAX];
@@ -77,7 +76,7 @@ struct i2c_driver {
* the i2c module. This struct provides functions to access the i2c bus.
*
* One must hold the spinlock to access the i2c bus (XXX: is the irqsave
- * required? Maybe better use a semaphore?).
+ * required? Maybe better use a semaphore?).
* [-AC-] having a spinlock_irqsave is only needed if we have drivers wishing
* to bang their i2c bus from an interrupt.
*
@@ -87,6 +86,7 @@ struct i2c_driver {
*/
/* needed: unsigned long flags */
+
#if LINUX_VERSION_CODE >= 0x020100
#define LOCK_I2C_BUS(bus) spin_lock_irqsave(&(bus->bus_lock),flags);
#define UNLOCK_I2C_BUS(bus) spin_unlock_irqrestore(&(bus->bus_lock),flags);
@@ -95,47 +95,48 @@ struct i2c_driver {
#define UNLOCK_I2C_BUS(bus) { restore_flags(flags); }
#endif
-struct i2c_bus {
- char name[32]; /* some useful label */
- int id;
- void *data; /* free for use by the bus driver */
+struct i2c_bus
+{
+ char name[32]; /* some useful label */
+ int id;
+ void *data; /* free for use by the bus driver */
#if LINUX_VERSION_CODE >= 0x020100
- spinlock_t bus_lock;
+ spinlock_t bus_lock;
#endif
- /* attach/detach inform callbacks */
- void (*attach_inform)(struct i2c_bus *bus, int id);
- void (*detach_inform)(struct i2c_bus *bus, int id);
+ /* attach/detach inform callbacks */
+ void (*attach_inform)(struct i2c_bus *bus, int id);
+ void (*detach_inform)(struct i2c_bus *bus, int id);
- /* Software I2C */
- void (*i2c_setlines)(struct i2c_bus *bus, int ctrl, int data);
- int (*i2c_getdataline)(struct i2c_bus *bus);
+ /* Software I2C */
+ void (*i2c_setlines)(struct i2c_bus *bus, int ctrl, int data);
+ int (*i2c_getdataline)(struct i2c_bus *bus);
- /* Hardware I2C */
- int (*i2c_read)(struct i2c_bus *bus, unsigned char addr);
- int (*i2c_write)(struct i2c_bus *bus, unsigned char addr,
+ /* Hardware I2C */
+ int (*i2c_read)(struct i2c_bus *bus, unsigned char addr);
+ int (*i2c_write)(struct i2c_bus *bus, unsigned char addr,
unsigned char b1, unsigned char b2, int both);
- /* internal data for i2c module */
- struct i2c_device *devices[I2C_DEVICE_MAX];
- int devcount;
+ /* internal data for i2c module */
+ struct i2c_device *devices[I2C_DEVICE_MAX];
+ int devcount;
};
/*
- * this holds per-device data for a i2c device
- *
+ * This holds per-device data for a i2c device
*/
-struct i2c_device {
- char name[32]; /* some useful label */
- void *data; /* free for use by the chip driver */
- unsigned char addr; /* chip addr */
+struct i2c_device
+{
+ char name[32]; /* some useful label */
+ void *data; /* free for use by the chip driver */
+ unsigned char addr; /* chip addr */
- /* i2c internal */
- struct i2c_bus *bus;
- struct i2c_driver *driver;
+ /* i2c internal */
+ struct i2c_bus *bus;
+ struct i2c_driver *driver;
};
@@ -155,7 +156,6 @@ int i2c_control_device(struct i2c_bus *bus, int id,
unsigned int cmd, void *arg);
/* i2c bus access functions */
-void i2c_reset(struct i2c_bus *bus);
void i2c_start(struct i2c_bus *bus);
void i2c_stop(struct i2c_bus *bus);
void i2c_one(struct i2c_bus *bus);
@@ -170,15 +170,4 @@ int i2c_read(struct i2c_bus *bus, unsigned char addr);
int i2c_write(struct i2c_bus *bus, unsigned char addr,
unsigned char b1, unsigned char b2, int both);
-/* ------------------------------------------------------------------------ */
-/* this allows i2c bus access from userspace */
-
-/* ioctls */
-#define I2C_SLAVE 0x0706
-#define I2C_WRITE_SIZE 0x0712
-#define I2C_WRITE_BUF 0x0713
-#define I2C_RESET 0x07fd
-
-#define I2C_BUFFER_SIZE 64 /* buffer size for write b4 read */
-
#endif /* I2C_H */
diff --git a/bttv/driver/linux-2.0.33.diff b/bttv/driver/linux-2.0.33.diff
deleted file mode 100644
index 39431cb..0000000
--- a/bttv/driver/linux-2.0.33.diff
+++ /dev/null
@@ -1,10 +0,0 @@
---- linux/kernel/ksyms.c-orig Mon Apr 6 23:46:19 1998
-+++ linux/kernel/ksyms.c Mon Apr 6 23:46:09 1998
-@@ -87,6 +87,7 @@
-
- /* stackable module support */
- X(register_symtab_from),
-+ X(request_module),
- #ifdef CONFIG_KERNELD
- X(kerneld_send),
- #endif
diff --git a/bttv/driver/msp3400.c b/bttv/driver/msp3400.c
index a5db7cf..d8e1e9d 100644
--- a/bttv/driver/msp3400.c
+++ b/bttv/driver/msp3400.c
@@ -3,10 +3,10 @@
*
* (c) 1997,1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
*
- * what works and what does'nt:
+ * what works and what doesn't:
*
* AM-Mono
- * probably does'nt (untested)
+ * probably doesn't (untested)
*
* FM-Mono
* should work. The stereo modes are backward compatible to FM-mono,
@@ -19,7 +19,7 @@
* should work, no autodetect (i.e. default is mono, but you can
* switch to stereo -- untested)
*
- * NICAM (B/G, used in Scandinavia and Spain)
+ * NICAM (B/G, used in UK, Scandinavia and Spain)
* should work, with autodetect. Support for NICAM was added by
* Pekka Pietikainen <pp@netppl.fi>
*
@@ -93,8 +93,8 @@ struct msp3400c {
/* 2.0.x */
#define signal_pending(current) (current->signal & ~current->blocked)
#define sigfillset(set)
+#define mdelay(x) udelay(1000*x)
#else
-/* 2.1.x */
MODULE_PARM(debug,"i");
#endif
@@ -107,29 +107,28 @@ MODULE_PARM(debug,"i");
/* ----------------------------------------------------------------------- */
/* functions for talking to the MSP3400C Sound processor */
-static int
-msp3400c_reset(struct i2c_bus *bus)
+static int msp3400c_reset(struct i2c_bus *bus)
{
int ret = 0;
- udelay(2000);
+ mdelay(2);
i2c_start(bus);
i2c_sendbyte(bus, I2C_MSP3400C,2000);
i2c_sendbyte(bus, 0x00,0);
i2c_sendbyte(bus, 0x80,0);
i2c_sendbyte(bus, 0x00,0);
i2c_stop(bus);
- udelay(2000);
+ mdelay(2);
i2c_start(bus);
if (0 != i2c_sendbyte(bus, I2C_MSP3400C,2000) ||
0 != i2c_sendbyte(bus, 0x00,0) ||
0 != i2c_sendbyte(bus, 0x00,0) ||
0 != i2c_sendbyte(bus, 0x00,0)) {
ret = -1;
- printk("msp3400: chip reset failed, penguin on i2c bus?\n");
+ printk(KERN_ERR "msp3400: chip reset failed, penguin on i2c bus?\n");
}
i2c_stop(bus);
- udelay(2000);
+ mdelay(2);
return ret;
}
@@ -155,7 +154,7 @@ msp3400c_read(struct i2c_bus *bus, int dev, int addr)
}
i2c_stop(bus);
if (-1 == ret) {
- printk("msp3400: I/O error, trying reset (read %s 0x%x)\n",
+ printk(KERN_WARNING "msp3400: I/O error, trying reset (read %s 0x%x)\n",
(dev == I2C_MSP3400C_DEM) ? "Demod" : "Audio", addr);
msp3400c_reset(bus);
}
@@ -177,7 +176,7 @@ msp3400c_write(struct i2c_bus *bus, int dev, int addr, int val)
ret = -1;
i2c_stop(bus);
if (-1 == ret) {
- printk("msp3400: I/O error, trying reset (write %s 0x%x)\n",
+ printk(KERN_WARNING "msp3400: I/O error, trying reset (write %s 0x%x)\n",
(dev == I2C_MSP3400C_DEM) ? "Demod" : "Audio", addr);
msp3400c_reset(bus);
}
@@ -273,8 +272,7 @@ static struct CARRIER_DETECT carrier_detect_65[] = {
/* ------------------------------------------------------------------------ */
-static void
-msp3400c_setcarrier(struct i2c_bus *bus, int cdo1, int cdo2)
+static void msp3400c_setcarrier(struct i2c_bus *bus, int cdo1, int cdo2)
{
msp3400c_write(bus,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
msp3400c_write(bus,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
@@ -282,8 +280,7 @@ msp3400c_setcarrier(struct i2c_bus *bus, int cdo1, int cdo2)
msp3400c_write(bus,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
}
-static void
-msp3400c_setvolume(struct i2c_bus *bus, int left, int right)
+static void msp3400c_setvolume(struct i2c_bus *bus, int left, int right)
{
int vol,val,balance;
@@ -302,8 +299,7 @@ msp3400c_setvolume(struct i2c_bus *bus, int left, int right)
msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0001, balance << 8);
}
-static void
-msp3400c_setbass(struct i2c_bus *bus, int bass)
+static void msp3400c_setbass(struct i2c_bus *bus, int bass)
{
int val = ((bass-32768) * 0x60 / 65535) << 8;
@@ -311,8 +307,7 @@ msp3400c_setbass(struct i2c_bus *bus, int bass)
msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
}
-static void
-msp3400c_settreble(struct i2c_bus *bus, int treble)
+static void msp3400c_settreble(struct i2c_bus *bus, int treble)
{
int val = ((treble-32768) * 0x60 / 65535) << 8;
@@ -320,8 +315,7 @@ msp3400c_settreble(struct i2c_bus *bus, int treble)
msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
}
-static void
-msp3400c_setmode(struct msp3400c *msp, int type)
+static void msp3400c_setmode(struct msp3400c *msp, int type)
{
int i;
@@ -364,8 +358,7 @@ msp3400c_setmode(struct msp3400c *msp, int type)
}
}
-static void
-msp3400c_setstereo(struct msp3400c *msp, int mode)
+static void msp3400c_setstereo(struct msp3400c *msp, int mode)
{
int nicam=0; /* channel source: FM/AM or nicam */
@@ -457,8 +450,7 @@ struct REGISTER_DUMP d1[] = {
* in the ioctl while doing the sound carrier & stereo detect
*/
-void
-msp3400c_stereo_wake(unsigned long data)
+static void msp3400c_stereo_wake(unsigned long data)
{
struct msp3400c *msp = (struct msp3400c*)data; /* XXX alpha ??? */
@@ -466,8 +458,7 @@ msp3400c_stereo_wake(unsigned long data)
up(msp->wait);
}
-int
-msp3400c_thread(void *data)
+static int msp3400c_thread(void *data)
{
unsigned long flags;
struct msp3400c *msp = data;
@@ -678,8 +669,7 @@ done:
#if 0 /* not finished yet */
-int
-msp3410d_thread(void *data)
+static int msp3410d_thread(void *data)
{
unsigned long flags;
struct msp3400c *msp = data;
@@ -776,8 +766,7 @@ done:
#include <../drivers/sound/sound_config.h>
#include <../drivers/sound/dev_table.h>
-static int
-mix_to_v4l(int i)
+static int mix_to_v4l(int i)
{
int r;
@@ -787,8 +776,7 @@ mix_to_v4l(int i)
return r;
}
-static int
-v4l_to_mix(int i)
+static int v4l_to_mix(int i)
{
int r;
@@ -798,8 +786,7 @@ v4l_to_mix(int i)
return r | (r << 8);
}
-static int
-v4l_to_mix2(int l, int r)
+static int v4l_to_mix2(int l, int r)
{
r = (r * 100 + 32768) / 65536;
if (r > 100) r = 100;
@@ -810,8 +797,7 @@ v4l_to_mix2(int l, int r)
return (r << 8) | l;
}
-static int
-msp3400c_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int msp3400c_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
struct msp3400c *msp = mixer_devs[dev]->devc;
unsigned long flags;
@@ -881,8 +867,7 @@ struct mixer_operations msp3400c_mixer = {
msp3400c_mixer_ioctl
};
-static int
-msp3400c_mixer_init(struct msp3400c *msp)
+static int msp3400c_mixer_init(struct msp3400c *msp)
{
int m;
@@ -902,8 +887,7 @@ msp3400c_mixer_init(struct msp3400c *msp)
return 0;
}
-static int
-msp3400c_mixer_close(struct msp3400c *msp)
+static int msp3400c_mixer_close(struct msp3400c *msp)
{
int m = msp->mixer;
@@ -918,8 +902,7 @@ msp3400c_mixer_close(struct msp3400c *msp)
/* ----------------------------------------------------------------------- */
-static int
-msp3400c_attach(struct i2c_device *device)
+static int msp3400c_attach(struct i2c_device *device)
{
unsigned long flags;
struct semaphore sem = MUTEX_LOCKED;
@@ -940,17 +923,24 @@ msp3400c_attach(struct i2c_device *device)
if (-1 == msp3400c_reset(msp->bus)) {
UNLOCK_I2C_BUS(msp->bus);
kfree(msp);
+ dprintk("msp3400: no chip found\n");
return -1;
}
+ rev1 = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1e);
+ rev2 = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1f);
+ if (0 == rev1 && 0 == rev2) {
+ UNLOCK_I2C_BUS(msp->bus);
+ kfree(msp);
+ printk("msp3400: error while reading chip version\n");
+ return -1;
+ }
+
msp3400c_setmode(msp, MSP_MODE_FM_TERRA);
msp3400c_setvolume(msp->bus, msp->left, msp->right);
msp3400c_setbass(msp->bus, msp->bass);
msp3400c_settreble(msp->bus, msp->treble);
- rev1 = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1e);
- rev2 = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1f);
-
#if 0
/* this will turn on a 1kHz beep - might be useful for debugging... */
msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0014, 0x1040);
@@ -985,8 +975,7 @@ msp3400c_attach(struct i2c_device *device)
return 0;
}
-static int
-msp3400c_detach(struct i2c_device *device)
+static int msp3400c_detach(struct i2c_device *device)
{
unsigned long flags;
struct semaphore sem = MUTEX_LOCKED;
@@ -998,7 +987,8 @@ msp3400c_detach(struct i2c_device *device)
/* shutdown control thread */
del_timer(&msp->wake_stereo);
- if (msp->thread) {
+ if (msp->thread)
+ {
msp->notify = &sem;
msp->rmmod = 1;
if (!msp->active)
@@ -1016,8 +1006,7 @@ msp3400c_detach(struct i2c_device *device)
return 0;
}
-static int
-msp3400c_command(struct i2c_device *device,
+static int msp3400c_command(struct i2c_device *device,
unsigned int cmd, void *arg)
{
unsigned long flags;
diff --git a/bttv/driver/tuner.c b/bttv/driver/tuner.c
index db37406..6f8a6e3 100644
--- a/bttv/driver/tuner.c
+++ b/bttv/driver/tuner.c
@@ -22,30 +22,32 @@ MODULE_PARM(debug,"i");
MODULE_PARM(type,"i");
#endif
-struct tuner {
- struct i2c_bus *bus; /* where is our chip */
- int addr;
+struct tuner
+{
+ struct i2c_bus *bus; /* where is our chip */
+ int addr;
- int type; /* chip type */
- int freq; /* keep track of the current settings */
- int radio;
+ int type; /* chip type */
+ int freq; /* keep track of the current settings */
+ int radio;
};
/* ---------------------------------------------------------------------- */
-struct tunertype {
- char *name;
- unchar Vendor;
- unchar Type;
+struct tunertype
+{
+ char *name;
+ unsigned char Vendor;
+ unsigned char Type;
- ushort thresh1; /* frequency Range for UHF,VHF-L, VHF_H */
- ushort thresh2;
- unchar VHF_L;
- unchar VHF_H;
- unchar UHF;
- unchar config;
- unchar I2C;
- ushort IFPCoff;
+ unsigned short thresh1; /* frequency Range for UHF,VHF-L, VHF_H */
+ unsigned short thresh2;
+ unsigned char VHF_L;
+ unsigned char VHF_H;
+ unsigned char UHF;
+ unsigned char config;
+ unsigned char I2C;
+ unsigned short IFPCoff;
};
/*
@@ -108,7 +110,7 @@ static void set_tv_freq(struct tuner *t, int freq)
else
config = tun->UHF;
- div=freq + (int)(16*38.9);
+ div=freq + tun->IFPCoff;
div&=0x7fff;
LOCK_I2C_BUS(t->bus);
@@ -158,79 +160,89 @@ static void set_radio_freq(struct tuner *t, int freq)
/* ---------------------------------------------------------------------- */
-static int
-tuner_attach(struct i2c_device *device)
+static int tuner_attach(struct i2c_device *device)
{
- struct tuner *t;
-
- device->data = t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
- if (NULL == t)
- return -ENOMEM;
- memset(t,0,sizeof(struct tuner));
- strcpy(device->name,"tuner");
- t->bus = device->bus;
- t->addr = device->addr;
- t->type = type;
- dprintk("tuner: type is %d (%s)\n",t->type,tuners[t->type].name);
- MOD_INC_USE_COUNT;
- return 0;
+ struct tuner *t;
+
+ /*
+ * For now we only try and attach these tuners to the BT848
+ * bus. This same module will however work different species
+ * of card using these chips. Just change the constraints
+ * (i2c doesn't have a totally clash free 'address' space)
+ */
+
+ if(device->bus->id!=I2C_BUSID_BT848)
+ return -EINVAL;
+
+ device->data = t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
+ if (NULL == t)
+ return -ENOMEM;
+ memset(t,0,sizeof(struct tuner));
+ strcpy(device->name,"tuner");
+ t->bus = device->bus;
+ t->addr = device->addr;
+ t->type = type;
+ dprintk("tuner: type is %d (%s)\n",t->type,tuners[t->type].name);
+
+ MOD_INC_USE_COUNT;
+ return 0;
}
-static int
-tuner_detach(struct i2c_device *device)
+static int tuner_detach(struct i2c_device *device)
{
- struct tuner *t = (struct tuner*)device->data;
- kfree(t);
- MOD_DEC_USE_COUNT;
- return 0;
+ struct tuner *t = (struct tuner*)device->data;
+ kfree(t);
+ MOD_DEC_USE_COUNT;
+ return 0;
}
-static int
-tuner_command(struct i2c_device *device,
+static int tuner_command(struct i2c_device *device,
unsigned int cmd, void *arg)
{
- struct tuner *t = (struct tuner*)device->data;
- int *iarg = (int*)arg;
-
- switch (cmd) {
- case TUNER_SET_TYPE:
- t->type = *iarg;
- dprintk("tuner: type set to %d (%s)\n",
- t->type,tuners[t->type].name);
- break;
-
- case TUNER_SET_TVFREQ:
- dprintk("tuner: tv freq set to %d.%02d\n",
- (*iarg)/16,(*iarg)%16*100/16);
- set_tv_freq(t,*iarg);
- t->radio = 0;
- t->freq = *iarg;
- break;
+ struct tuner *t = (struct tuner*)device->data;
+ int *iarg = (int*)arg;
+
+ switch (cmd)
+ {
+ case TUNER_SET_TYPE:
+ t->type = *iarg;
+ dprintk("tuner: type set to %d (%s)\n",
+ t->type,tuners[t->type].name);
+ break;
+
+ case TUNER_SET_TVFREQ:
+ dprintk("tuner: tv freq set to %d.%02d\n",
+ (*iarg)/16,(*iarg)%16*100/16);
+ set_tv_freq(t,*iarg);
+ t->radio = 0;
+ t->freq = *iarg;
+ break;
- case TUNER_SET_RADIOFREQ:
- dprintk("tuner: radio freq set to %d.%02d\n",
- (*iarg)/16,(*iarg)%16*100/16);
- set_radio_freq(t,*iarg);
- t->radio = 1;
- t->freq = *iarg;
- break;
+ case TUNER_SET_RADIOFREQ:
+ dprintk("tuner: radio freq set to %d.%02d\n",
+ (*iarg)/16,(*iarg)%16*100/16);
+ set_radio_freq(t,*iarg);
+ t->radio = 1;
+ t->freq = *iarg;
+ break;
- default:
- return -EINVAL;
- }
- return 0;
+ default:
+ return -EINVAL;
+ }
+ return 0;
}
/* ----------------------------------------------------------------------- */
-struct i2c_driver i2c_driver_tuner = {
- "tuner", /* name */
- I2C_DRIVERID_TUNER, /* ID */
- 0xc0, 0xce, /* addr range */
+struct i2c_driver i2c_driver_tuner =
+{
+ "tuner", /* name */
+ I2C_DRIVERID_TUNER, /* ID */
+ 0xc0, 0xce, /* addr range */
- tuner_attach,
- tuner_detach,
- tuner_command
+ tuner_attach,
+ tuner_detach,
+ tuner_command
};
#ifdef MODULE
@@ -239,14 +251,14 @@ int init_module(void)
int msp3400c_init(void)
#endif
{
- i2c_register_driver(&i2c_driver_tuner);
- return 0;
+ i2c_register_driver(&i2c_driver_tuner);
+ return 0;
}
#ifdef MODULE
void cleanup_module(void)
{
- i2c_unregister_driver(&i2c_driver_tuner);
+ i2c_unregister_driver(&i2c_driver_tuner);
}
#endif
diff --git a/bttv/driver/update b/bttv/driver/update
index 7fac504..91db789 100644
--- a/bttv/driver/update
+++ b/bttv/driver/update
@@ -28,6 +28,8 @@ xrmmod bttv
xrmmod msp3400
xrmmod tuner
xrmmod i2c_chardev
+xrmmod i2c-dev
+xrmmod algo-bit
xrmmod i2c
xrmmod videodev
@@ -36,6 +38,6 @@ xinsmod videodev
xinsmod i2c verbose=1 scan=1 i2c_debug=0
test -f i2c_chardev.o && xinsmod i2c_chardev
xinsmod tuner debug=0 type=5
-xinsmod msp3400 debug=0
+xinsmod msp3400
xinsmod bttv radio=1 vidmem=0xff0
diff --git a/bttv/driver/videodev.c b/bttv/driver/videodev.c
index 4e5aa47..360058c 100644
--- a/bttv/driver/videodev.c
+++ b/bttv/driver/videodev.c
@@ -50,6 +50,15 @@ extern int init_colour_qcams(struct video_init *);
#ifdef CONFIG_VIDEO_BWQCAM
extern int init_bw_qcams(struct video_init *);
#endif
+#ifdef CONFIG_RADIO_AZTECH
+extern int aztech_init(struct video_init *);
+#endif
+#ifdef CONFIG_RADIO_RTRACK
+extern int rtrack_init(struct video_init *);
+#endif
+#ifdef CONFIG_RADIO_SF16FMI
+extern int fmi_init(struct video_init *);
+#endif
static struct video_init video_init_list[]={
#ifdef CONFIG_VIDEO_BT848
@@ -68,6 +77,15 @@ static struct video_init video_init_list[]={
{"PMS", init_pms_cards},
#endif
{"end", NULL}
+#ifdef CONFIG_RADIO_AZTECH
+ {"Aztech", aztech_init},
+#endif
+#ifdef CONFIG_RADIO_RTRACK
+ {"RTrack", rtrack_init},
+#endif
+#ifdef CONFIG_RADIO_SF16FMI
+ {"SF16FMI", fmi_init},
+#endif
};
#if LINUX_VERSION_CODE >= 0x020100
@@ -79,7 +97,10 @@ static ssize_t video_read(struct file *file,
char *buf, size_t count, loff_t *ppos)
{
struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
- return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ if (vfl->read)
+ return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ else
+ return -EINVAL;
}
@@ -93,15 +114,21 @@ static ssize_t video_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
- return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ if (vfl->write)
+ return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ else
+ return 0;
}
#else
static int video_read(struct inode *ino,struct file *file,
char *buf, int count)
{
- int err;
- struct video_device *vfl=video_device[MINOR(ino->i_rdev)];
- return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ int err;
+ struct video_device *vfl=video_device[MINOR(ino->i_rdev)];
+ if (vfl->read)
+ return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ else
+ return -EINVAL;
}
static int video_write(struct inode *ino,struct file *file, const char *buf,
@@ -109,7 +136,10 @@ static int video_write(struct inode *ino,struct file *file, const char *buf,
{
int err;
struct video_device *vfl=video_device[MINOR(ino->i_rdev)];
- return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ if (vfl->write)
+ return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
+ else
+ return 0;
}
#endif
@@ -257,12 +287,15 @@ int video_register_device(struct video_device *vfd, int type)
/* The init call may sleep so we book the slot out
then call */
MOD_INC_USE_COUNT;
- err=vfd->initialize(vfd);
- if(err<0)
- {
- video_device[i]=NULL;
- MOD_DEC_USE_COUNT;
- return err;
+ if (vfd->initialize)
+ {
+ err=vfd->initialize(vfd);
+ if(err<0)
+ {
+ video_device[i]=NULL;
+ MOD_DEC_USE_COUNT;
+ return err;
+ }
}
return 0;
}
diff --git a/bttv/driver/videodev.h b/bttv/driver/videodev.h
index 1b7a6cf..6b13119 100644
--- a/bttv/driver/videodev.h
+++ b/bttv/driver/videodev.h
@@ -69,7 +69,6 @@ struct video_channel
__u16 type;
#define VIDEO_TYPE_TV 1
#define VIDEO_TYPE_CAMERA 2
- __u16 mode; /* PAL/NTSC/SECAM/OTHER */
};
struct video_tuner
@@ -81,11 +80,14 @@ struct video_tuner
#define VIDEO_TUNER_PAL 1
#define VIDEO_TUNER_NTSC 2
#define VIDEO_TUNER_SECAM 4
+#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
+#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
__u16 mode; /* PAL/NTSC/SECAM/OTHER */
#define VIDEO_MODE_PAL 0
#define VIDEO_MODE_NTSC 1
#define VIDEO_MODE_SECAM 2
#define VIDEO_MODE_AUTO 3
+ __u16 signal; /* Signal strength 16bit scale */
};
struct video_picture
@@ -103,6 +105,7 @@ struct video_picture
#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
+#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
};
struct video_audio
@@ -194,6 +197,9 @@ struct video_key
#define VID_HARDWARE_QCAM_C 4
#define VID_HARDWARE_PSEUDO 5
#define VID_HARDWARE_SAA5249 6
+#define VID_HARDWARE_AZTECH 7
+#define VID_HARDWARE_SF16MI 8
+#define VID_HARDWARE_RTRACK 9
/*
* Initialiser list

Privacy Policy