Commit 8354eb8a authored by Gerd Knorr's avatar Gerd Knorr Committed by Linus Torvalds

[PATCH] bttv update

This updates the bttv driver.  Major changes are (a) adaptions to the
final v4l2 API and (b) lots of updates in the card-specific code.  There
are also various other small changes.
parent 3344276f
......@@ -347,6 +347,8 @@
#define BT848_PLL_X (1<<7)
#define BT848_PLL_C (1<<6)
#define BT848_DVSIF 0x0FC
/* Bt878 register */
#define BT878_DEVCTRL 0x40
......
This diff is collapsed.
This diff is collapsed.
......@@ -41,11 +41,13 @@ static struct i2c_adapter bttv_i2c_adap_template;
static struct i2c_client bttv_i2c_client_template;
EXPORT_SYMBOL(bttv_get_cardinfo);
EXPORT_SYMBOL(bttv_get_pcidev);
EXPORT_SYMBOL(bttv_get_id);
EXPORT_SYMBOL(bttv_gpio_enable);
EXPORT_SYMBOL(bttv_read_gpio);
EXPORT_SYMBOL(bttv_write_gpio);
EXPORT_SYMBOL(bttv_get_gpio_queue);
EXPORT_SYMBOL(bttv_i2c_call);
/* ----------------------------------------------------------------------- */
/* Exported functions - for other modules which want to access the */
......@@ -62,6 +64,13 @@ int bttv_get_cardinfo(unsigned int card, int *type, int *cardid)
return 0;
}
struct pci_dev* bttv_get_pcidev(unsigned int card)
{
if (card >= bttv_num)
return NULL;
return bttvs[card].dev;
}
int bttv_get_id(unsigned int card)
{
printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n");
......@@ -245,6 +254,13 @@ void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
}
}
void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
{
if (card >= bttv_num)
return;
bttv_call_i2c_clients(&bttvs[card], cmd, arg);
}
static struct i2c_algo_bit_data bttv_i2c_algo_template = {
setsda: bttv_bit_setsda,
setscl: bttv_bit_setscl,
......
This diff is collapsed.
......@@ -47,58 +47,51 @@ MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
#define dprintk(fmt, arg...) if (vbi_debug) \
printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->nr, ## arg)
#ifndef HAVE_V4L2
/* some dummy defines to avoid cluttering up the source code with
a huge number of ifdef's for V4L2 */
# define V4L2_BUF_TYPE_CAPTURE -1
# define V4L2_BUF_TYPE_VBI -1
#endif
/* ----------------------------------------------------------------------- */
/* vbi risc code + mm */
static int
vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
{
int bpl = 2048;
bttv_risc_packed(btv, &buf->odd, buf->vb.dma.sglist,
0, bpl-4, 4, btv->vbi.lines);
bttv_risc_packed(btv, &buf->even, buf->vb.dma.sglist,
btv->vbi.lines * bpl, bpl-4, 4, btv->vbi.lines);
bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
0, bpl-4, 4, lines);
bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
lines * bpl, bpl-4, 4, lines);
return 0;
}
static int vbi_buffer_setup(struct file *file, int *count, int *size)
{
struct bttv *btv = file->private_data;
struct bttv_fh *fh = file->private_data;
if (0 == *count)
*count = vbibufs;
*size = btv->vbi.lines * 2 * 2048;
*size = fh->lines * 2 * 2048;
return 0;
}
static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb,
int fields)
static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb)
{
struct bttv *btv = file->private_data;
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
struct bttv_buffer *buf = (struct bttv_buffer*)vb;
int rc;
buf->vb.size = btv->vbi.lines * 2 * 2048;
buf->vb.size = fh->lines * 2 * 2048;
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
return -EINVAL;
if (STATE_NEEDS_INIT == buf->vb.state) {
if (0 != (rc = videobuf_iolock(btv->dev,&buf->vb)))
goto fail;
if (0 != (rc = vbi_buffer_risc(btv,buf)))
if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
goto fail;
}
buf->vb.state = STATE_PREPARED;
dprintk("buf prepare %p: odd=%p even=%p\n",
vb,&buf->odd,&buf->even);
dprintk("buf prepare %p: top=%p bottom=%p\n",
vb,&buf->top,&buf->bottom);
return 0;
fail:
......@@ -109,7 +102,8 @@ static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb,
static void
vbi_buffer_queue(struct file *file, struct videobuf_buffer *vb)
{
struct bttv *btv = file->private_data;
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
struct bttv_buffer *buf = (struct bttv_buffer*)vb;
dprintk("queue %p\n",vb);
......@@ -120,14 +114,15 @@ vbi_buffer_queue(struct file *file, struct videobuf_buffer *vb)
static void vbi_buffer_release(struct file *file, struct videobuf_buffer *vb)
{
struct bttv *btv = file->private_data;
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
struct bttv_buffer *buf = (struct bttv_buffer*)vb;
dprintk("free %p\n",vb);
bttv_dma_free(btv,buf);
bttv_dma_free(fh->btv,buf);
}
struct videobuf_queue_ops vbi_qops = {
struct videobuf_queue_ops bttv_vbi_qops = {
buf_setup: vbi_buffer_setup,
buf_prepare: vbi_buffer_prepare,
buf_queue: vbi_buffer_queue,
......@@ -136,7 +131,7 @@ struct videobuf_queue_ops vbi_qops = {
/* ----------------------------------------------------------------------- */
static void vbi_setlines(struct bttv *btv, int lines)
void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
{
int vdelay;
......@@ -144,7 +139,7 @@ static void vbi_setlines(struct bttv *btv, int lines)
lines = 1;
if (lines > VBI_MAXLINES)
lines = VBI_MAXLINES;
btv->vbi.lines = lines;
fh->lines = lines;
vdelay = btread(BT848_E_VDELAY_LO);
if (vdelay < lines*2) {
......@@ -154,19 +149,18 @@ static void vbi_setlines(struct bttv *btv, int lines)
}
}
#ifdef HAVE_V4L2
static void vbi_fmt(struct bttv *btv, struct v4l2_format *f)
void bttv_vbi_fmt(struct bttv_fh *fh, struct v4l2_format *f)
{
memset(f,0,sizeof(*f));
f->type = V4L2_BUF_TYPE_VBI;
f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
f->fmt.vbi.sampling_rate = 35468950;
f->fmt.vbi.samples_per_line = 2048;
f->fmt.vbi.sample_format = V4L2_VBI_SF_UBYTE;
f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
f->fmt.vbi.offset = 244;
f->fmt.vbi.count[0] = btv->vbi.lines;
f->fmt.vbi.count[1] = btv->vbi.lines;
f->fmt.vbi.count[0] = fh->lines;
f->fmt.vbi.count[1] = fh->lines;
f->fmt.vbi.flags = 0;
switch (btv->tvnorm) {
switch (fh->btv->tvnorm) {
case 1: /* NTSC */
f->fmt.vbi.start[0] = 10;
f->fmt.vbi.start[1] = 273;
......@@ -178,212 +172,8 @@ static void vbi_fmt(struct bttv *btv, struct v4l2_format *f)
f->fmt.vbi.start[1] = 319;
}
}
#endif
/* ----------------------------------------------------------------------- */
/* vbi interface */
static int vbi_open(struct inode *inode, struct file *file)
{
unsigned int minor = minor(inode->i_rdev);
struct bttv *btv = NULL;
int i;
for (i = 0; i < bttv_num; i++) {
if (bttvs[i].vbi_dev.minor == minor) {
btv = &bttvs[i];
break;
}
}
if (NULL == btv)
return -ENODEV;
down(&btv->vbi.q.lock);
if (btv->vbi.users) {
up(&btv->vbi.q.lock);
return -EBUSY;
}
dprintk("open minor=%d\n",minor);
file->private_data = btv;
btv->vbi.users++;
vbi_setlines(btv,VBI_DEFLINES);
bttv_field_count(btv);
up(&btv->vbi.q.lock);
return 0;
}
static int vbi_release(struct inode *inode, struct file *file)
{
struct bttv *btv = file->private_data;
if (btv->vbi.q.streaming)
videobuf_streamoff(file,&btv->vbi.q);
down(&btv->vbi.q.lock);
if (btv->vbi.q.reading)
videobuf_read_stop(file,&btv->vbi.q);
btv->vbi.users--;
bttv_field_count(btv);
vbi_setlines(btv,0);
up(&btv->vbi.q.lock);
return 0;
}
static int vbi_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
struct bttv *btv = file->private_data;
if (btv->errors)
bttv_reinit_bt848(btv);
switch (cmd) {
case VIDIOCGCAP:
{
struct video_capability *cap = arg;
memset(cap,0,sizeof(*cap));
strcpy(cap->name,btv->vbi_dev.name);
cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
return 0;
}
/* vbi/teletext ioctls */
case BTTV_VBISIZE:
return btv->vbi.lines * 2 * 2048;
case BTTV_VERSION:
case VIDIOCGFREQ:
case VIDIOCSFREQ:
case VIDIOCGTUNER:
case VIDIOCSTUNER:
case VIDIOCGCHAN:
case VIDIOCSCHAN:
return bttv_common_ioctls(btv,cmd,arg);
#ifdef HAVE_V4L2
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = arg;
memset(cap,0,sizeof(*cap));
strcpy(cap->name, btv->name);
cap->type = V4L2_TYPE_VBI;
cap->flags = V4L2_FLAG_TUNER | V4L2_FLAG_READ |
V4L2_FLAG_STREAMING | V4L2_FLAG_SELECT;
return 0;
}
case VIDIOC_G_FMT:
{
struct v4l2_format *f = arg;
vbi_fmt(btv,f);
return 0;
}
case VIDIOC_S_FMT:
{
struct v4l2_format *f = arg;
if (btv->vbi.q.reading || btv->vbi.q.streaming)
return -EBUSY;
vbi_setlines(btv,f->fmt.vbi.count[0]);
vbi_fmt(btv,f);
return 0;
}
case VIDIOC_REQBUFS:
return videobuf_reqbufs(file,&btv->vbi.q,arg);
case VIDIOC_QUERYBUF:
return videobuf_querybuf(&btv->vbi.q, arg);
case VIDIOC_QBUF:
return videobuf_qbuf(file, &btv->vbi.q, arg);
case VIDIOC_DQBUF:
return videobuf_dqbuf(file, &btv->vbi.q, arg);
case VIDIOC_STREAMON:
return videobuf_streamon(file, &btv->vbi.q);
case VIDIOC_STREAMOFF:
return videobuf_streamoff(file, &btv->vbi.q);
case VIDIOC_ENUMSTD:
case VIDIOC_G_STD:
case VIDIOC_S_STD:
case VIDIOC_ENUMINPUT:
case VIDIOC_G_INPUT:
case VIDIOC_S_INPUT:
case VIDIOC_G_TUNER:
case VIDIOC_S_TUNER:
case VIDIOC_G_FREQ:
case VIDIOC_S_FREQ:
return bttv_common_ioctls(btv,cmd,arg);
#endif /* HAVE_V4L2 */
default:
return -ENOIOCTLCMD;
}
return 0;
}
static int vbi_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
return video_usercopy(inode, file, cmd, arg, vbi_do_ioctl);
}
static ssize_t vbi_read(struct file *file, char *data,
size_t count, loff_t *ppos)
{
struct bttv *btv = file->private_data;
if (btv->errors)
bttv_reinit_bt848(btv);
dprintk("read %d\n",count);
return videobuf_read_stream(file, &btv->vbi.q, data, count, ppos, 1);
}
static unsigned int vbi_poll(struct file *file, poll_table *wait)
{
struct bttv *btv = file->private_data;
dprintk("poll%s\n","");
return videobuf_poll_stream(file, &btv->vbi.q, wait);
}
static int
vbi_mmap(struct file *file, struct vm_area_struct * vma)
{
struct bttv *btv = file->private_data;
dprintk("mmap 0x%lx+%ld\n",vma->vm_start,
vma->vm_end - vma->vm_start);
return videobuf_mmap_mapper(vma, &btv->vbi.q);
}
static struct file_operations vbi_fops =
{
owner: THIS_MODULE,
open: vbi_open,
release: vbi_release,
ioctl: vbi_ioctl,
llseek: no_llseek,
read: vbi_read,
poll: vbi_poll,
mmap: vbi_mmap,
};
struct video_device bttv_vbi_template =
{
name: "bt848/878 vbi",
type: VID_TYPE_TUNER|VID_TYPE_TELETEXT,
hardware: VID_HARDWARE_BT848,
fops: &vbi_fops,
minor: -1,
};
/*
* Local variables:
* c-basic-offset: 8
......
......@@ -90,10 +90,26 @@
#define BTTV_SENSORAY311 0x49
#define BTTV_RV605 0x4a
#define BTTV_WINDVR 0x4c
#define BTTV_HAUPPAUGEPVR 0x50
#define BTTV_GVBCTV5PCI 0x51
#define BTTV_OSPREY1x0 0x52
#define BTTV_OSPREY1x0_848 0x53
#define BTTV_OSPREY101_848 0x54
#define BTTV_OSPREY1x1 0x55
#define BTTV_OSPREY1x1_SVID 0x56
#define BTTV_OSPREY2xx 0x57
#define BTTV_OSPREY2x0_SVID 0x58
#define BTTV_OSPREY2x0 0x59
#define BTTV_OSPREY500 0x5a
#define BTTV_OSPREY540 0x5b
#define BTTV_OSPREY2000 0x5c
#define BTTV_IDS_EAGLE 0x5d
/* i2c address list */
#define I2C_TSA5522 0xc2
#define I2C_TDA7432 0x8a
#define I2C_BT832_ALT1 0x88
#define I2C_BT832_ALT2 0x8a // alternate setting
#define I2C_TDA8425 0x82
#define I2C_TDA9840 0x84
#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */
......@@ -105,6 +121,7 @@
#define I2C_MSP3400 0x80
#define I2C_TEA6300 0x80
#define I2C_DPL3518 0x84
#define I2C_TDA9887 0x86
/* more card-specific defines */
#define PT2254_L_CHANNEL 0x10
......@@ -132,6 +149,7 @@ struct tvcard
/* i2c audio flags */
int no_msp34xx:1;
int no_tda9875:1;
int no_tda7432:1;
int needs_tvaudio:1;
/* other settings */
......@@ -174,6 +192,7 @@ extern int bttv_handle_chipset(struct bttv *btv);
returns negative value if error occurred
*/
extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid);
extern struct pci_dev* bttv_get_pcidev(unsigned int card);
/* obsolete, use bttv_get_cardinfo instead */
extern int bttv_get_id(unsigned int card);
......@@ -208,6 +227,11 @@ extern int bttv_write_gpio(unsigned int card,
*/
extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
/* call i2c clients
*/
extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg);
/* i2c */
#define I2C_CLIENTS_MAX 16
extern void bttv_bit_setscl(void *data, int state);
......
......@@ -24,7 +24,7 @@
#ifndef _BTTVP_H_
#define _BTTVP_H_
#define BTTV_VERSION_CODE KERNEL_VERSION(0,8,42)
#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,1)
#include <linux/types.h>
#include <linux/wait.h>
......@@ -54,7 +54,8 @@
#define RISC_SLOT_LOOP 14
#define RESOURCE_OVERLAY 1
#define RESOURCE_STREAMING 2
#define RESOURCE_VIDEO 2
#define RESOURCE_VBI 3
#define RAW_LINES 640
#define RAW_BPL 1024
......@@ -63,15 +64,17 @@
struct bttv_tvnorm
{
int v4l2_id;
u32 Fsc;
u16 swidth, sheight; /* scaled standard width, height */
u16 totalwidth;
u8 adelay, bdelay, iform;
u32 scaledtwidth;
u16 hdelayx1, hactivex1;
u16 vdelay;
u8 vbipack;
int v4l2_id;
char *name;
u32 Fsc;
u16 swidth, sheight; /* scaled standard width, height */
u16 totalwidth;
u8 adelay, bdelay, iform;
u32 scaledtwidth;
u16 hdelayx1, hactivex1;
u16 vdelay;
u8 vbipack;
int sram;
};
extern const struct bttv_tvnorm bttv_tvnorms[];
extern const int BTTV_TVNORMS;
......@@ -99,8 +102,8 @@ struct bttv_geometry {
struct bttv_riscmem {
unsigned int size;
unsigned long *cpu;
unsigned long *jmp;
u32 *cpu;
u32 *jmp;
dma_addr_t dma;
};
......@@ -114,32 +117,34 @@ struct bttv_buffer {
int btformat;
int btswap;
struct bttv_geometry geo;
struct bttv_riscmem even;
struct bttv_riscmem odd;
struct bttv_riscmem top;
struct bttv_riscmem bottom;
};
struct bttv_overlay {
int tvnorm;
int x,y,width,height;
struct video_clip *clips;
struct v4l2_rect w;
enum v4l2_field field;
struct v4l2_clip *clips;
int nclips;
};
struct bttv_vbi {
int users;
int lines;
struct videobuf_queue q;
};
struct bttv_fh {
struct bttv *btv;
struct videobuf_queue q;
int resources;
enum v4l2_buf_type type;
/* video capture */
struct videobuf_queue cap;
struct bttv_buffer buf;
/* current settings */
const struct bttv_format *ovfmt;
struct bttv_overlay ov;
struct bttv_buffer buf;
/* video overlay */
struct videobuf_queue vbi;
int lines;
};
/* ---------------------------------------------------------- */
......@@ -163,18 +168,18 @@ int bttv_risc_planar(struct bttv *btv, struct bttv_riscmem *risc,
int cpadding);
/* risc code generator + helpers - screen overlay */
int bttv_screen_clips(struct video_buffer *fbuf,
int x, int y, int width, int height,
struct video_clip *clips, int n);
void bttv_sort_clips(struct video_clip *clips, int nclips);
int bttv_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
struct v4l2_clip *clips, int n);
void bttv_sort_clips(struct v4l2_clip *clips, int nclips);
int bttv_risc_overlay(struct bttv *btv, struct bttv_riscmem *risc,
const struct bttv_format *fmt,
struct bttv_overlay *ov, int flags);
struct bttv_overlay *ov,
int skip_top, int skip_bottom);
/* calculate / apply geometry settings */
void bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
int width, int height, int interleaved, int norm);
void bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd);
void bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int top);
/* control dma register + risc main loop */
void bttv_set_dma(struct bttv *btv, int override, int irqflags);
......@@ -183,11 +188,9 @@ int bttv_risc_hook(struct bttv *btv, int slot, struct bttv_riscmem *risc,
int irqflags);
/* capture buffer handling */
int bttv_buffer_field(struct bttv *btv, int field, int def_field,
int tvnorm, int height);
int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf);
int bttv_buffer_activate(struct bttv *btv, struct bttv_buffer *odd,
struct bttv_buffer *even);
int bttv_buffer_activate(struct bttv *btv, struct bttv_buffer *top,
struct bttv_buffer *bottom);
void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
/* overlay handling */
......@@ -199,8 +202,10 @@ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
/* ---------------------------------------------------------- */
/* bttv-vbi.c */
extern struct video_device bttv_vbi_template;
extern struct videobuf_queue_ops vbi_qops;
void bttv_vbi_fmt(struct bttv_fh *fh, struct v4l2_format *f);
void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines);
extern struct videobuf_queue_ops bttv_vbi_qops;
/* ---------------------------------------------------------- */
......@@ -212,6 +217,7 @@ extern unsigned int bttv_debug;
extern unsigned int bttv_gpio;
extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
extern int init_bttv_i2c(struct bttv *btv);
extern int pvr_boot(struct bttv *btv);
extern int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg);
extern void bttv_reinit_bt848(struct bttv *btv);
......@@ -285,6 +291,7 @@ struct bttv {
int tvnorm,hue,contrast,bright,saturation;
struct video_buffer fbuf;
int field_count;
int digital_video;
/* various options */
int opt_combfilter;
......@@ -293,27 +300,32 @@ struct bttv {
int opt_chroma_agc;
int opt_adc_crush;
/* vbi data/state */
struct bttv_vbi vbi;
/* radio data/state */
int has_radio;
int radio_user;
/* miro/pinnacle + Aimslab VHX
philips matchbox (tea5757 radio tuner) support */
int has_matchbox;
int mbox_we;
int mbox_we;
int mbox_data;
int mbox_clk;
int mbox_most;
int mbox_mask;
int radio_user;
/* ISA stuff (Terratec Active Radio Upgrade) */
int mbox_ior;
int mbox_iow;
int mbox_csel;
/* risc memory management data
- must aquire s_lock before changing these
- only the irq handler is supported to touch odd + even */
struct bttv_riscmem main;
struct bttv_buffer *odd; /* current active odd field */
struct bttv_buffer *even; /* current active even field */
struct bttv_buffer *screen; /* overlay */
struct list_head capture; /* capture buffer queue */
struct bttv_buffer *top; /* current active top field */
struct bttv_buffer *bottom; /* current active bottom field */
struct bttv_buffer *screen; /* overlay */
struct list_head capture; /* capture buffer queue */
struct bttv_buffer *vcurr;
struct list_head vcapture;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment