diff options
-rw-r--r-- | v4l_experimental/pvrusb2/Kbuild | 1 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/Makefile | 40 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-eeprom.c | 207 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h | 8 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-hdw.c | 26 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-i2c.c | 12 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-version.h | 2 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-video-v4l.c | 277 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-video-v4l.h | 54 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-video.c | 222 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-video.h | 40 |
11 files changed, 642 insertions, 247 deletions
diff --git a/v4l_experimental/pvrusb2/Kbuild b/v4l_experimental/pvrusb2/Kbuild index 3e1c3d72e..2166db3e7 100644 --- a/v4l_experimental/pvrusb2/Kbuild +++ b/v4l_experimental/pvrusb2/Kbuild @@ -3,6 +3,7 @@ pvrusb2-objs := \ pvrusb2-audio.o \ pvrusb2-encoder.o \ pvrusb2-video.o \ + pvrusb2-video-v4l.o \ pvrusb2-eeprom.o \ pvrusb2-tuner.o \ pvrusb2-i2c.o \ diff --git a/v4l_experimental/pvrusb2/Makefile b/v4l_experimental/pvrusb2/Makefile index b86f841a5..88eb298b6 100644 --- a/v4l_experimental/pvrusb2/Makefile +++ b/v4l_experimental/pvrusb2/Makefile @@ -1,13 +1,13 @@ # Mike Isely <isely@pobox.com> -# This is the module build file for pvrusb2. It requires the kbuild -# system from any 2.6.x kernel. It requires the kbuild system from -# any 2.6.x kernel (but it's only been tried against kernels 2.6.10 -# and later). This WILL NOT BUILD for 2.4.x kernels. Don't even -# bother trying. Even if you were to fix this build for 2.4.x, you -# would still have to port the driver as well. Everything here -# assumes 2.6.x. +# This is the module build file for pvrusb2 (ONLY when built as part +# of v4l in the experimental area). It requires the kbuild system +# from any 2.6.x kernel. It requires the kbuild system from any 2.6.x +# kernel (but it's only been tried against kernels 2.6.10 and later). +# This WILL NOT BUILD for 2.4.x kernels. Don't even bother trying. +# Even if you were to fix this build for 2.4.x, you would still have +# to port the driver as well. Everything here assumes 2.6.x. # To build, you can just run this Makefile. There are several # variables you may want to override however: @@ -27,6 +27,10 @@ # Sensible build targets include 'modules' (same as no target), # 'install', and 'clean' +# For building within the v4l experimental area, we have to adjust our +# include paths and also ensure that the environment as been set up +# (which is presumably what the "links" callout is for). + ifeq ($(KERNELRELEASE),) # Override any of these if you'd like @@ -42,8 +46,17 @@ ifeq ($(KERNELRELEASE),) default: all all: modules - M=$(shell pwd) - MYFLAGS := "CPPFLAGS= -D __KERNEL__ -I$(M)/../../linux/include -I$(M)/../../v4l $(CPPFLAGS) -I$(KDIR)/include" + M:=$(shell pwd) + + CPPFLAGS:= -D__KERNEL__ -I$(M)/../../linux/include -I$(M)/../../v4l $(CPPFLAGS) -I$(KDIR)/include + + modules modules_install clean: + $(MAKE) -C $(M)/../.. links + $(MAKE) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) "CPPFLAGS=$(CPPFLAGS)" -C $(KDIR) M=$(M) CONFIG_VIDEO_PVRUSB2=m $@ + + install: + $(MAKE) -C $(M)/../.. links + $(MAKE) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) "CPPFLAGS=$(CPPFLAGS)" -C $(KDIR) M=$(M) CONFIG_VIDEO_PVRUSB2=m modules_install else @@ -52,12 +65,3 @@ else endif - modules modules_install clean: - $(MAKE) -C $(shell pwd)/../.. links - @echo cppflags=$(MYFLAGS) - $(MAKE) V=1 $(MYFLAGS) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) -C $(KDIR) M=$(shell pwd) CONFIG_VIDEO_PVRUSB2=m $@ - - install: - $(MAKE) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) -C $(KDIR) M=$(shell pwd) CONFIG_VIDEO_PVRUSB2=m modules_install - - diff --git a/v4l_experimental/pvrusb2/pvrusb2-eeprom.c b/v4l_experimental/pvrusb2/pvrusb2-eeprom.c index e83ef0db7..c7a8ec53b 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-eeprom.c +++ b/v4l_experimental/pvrusb2/pvrusb2-eeprom.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-eeprom.c,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-eeprom.c,v 1.2 2005/11/27 23:01:16 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -34,11 +34,11 @@ Method #1: We expect tveeprom to attach to our I2C adapter as a client, in which case we send it a command to tell us what it - knows about the device. + knows about the device. This is the "indirect" method. Method #2: We retrieve the eeprom contents ourselves and call into tveeprom_hauppauge_analog() to parse the data and tell us what - it knows about the device. + it knows about the device. This is the "direct" method. Unfortunately it isn't perfectly clear which method is the best. They each have pros and cons: @@ -59,9 +59,8 @@ implementation of #2. This causes a usability nightmare. Since I can't decide, both methods are implemented below. Method #2 - (direct call) is the default choice, but if you want to try method - #1, comment out the PVRUSB2_EEPROM_DIRECT_CALL macro and cross your - fingers... + (direct) is the default choice, but if you want to try method #1, + then define PVR2_EEPROM_INDIRECT and cross your fingers... If you use method #1, please be aware that you won't have a serial number for the device and thus the sysfs interface may be a little @@ -74,10 +73,10 @@ */ -#define PVRUSB2_EEPROM_DIRECT_CALL - -#ifndef PVRUSB2_EEPROM_DIRECT_CALL +#ifdef PVR2_EEPROM_INDIRECT +/*VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*/ +/* BEGIN INDIRECT METHOD */ #include "pvrusb2-i2c.h" @@ -109,9 +108,136 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) return 0; } -#endif +/* END INDIRECT METHOD */ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +#endif /* PVR2_EEPROM_INDIRECT */ + +#ifndef PVR2_EEPROM_INDIRECT + +/* Stuff common to direct approach of operation tveeprom */ + +/* + + Read and analyze data in the eeprom. Use tveeprom to figure out + the packet structure, since this is another Hauppauge device and + internally it has a family resemblence to ivtv-type devices + +*/ + +#define PVR_EEPROM_I2C_ADDR 0x50 + +#include <media/tveeprom.h> + +/* We seem to only be interested in the back half of the EEPROM */ +#define EEPROM_SIZE 128 +#define EEPROM_OFFS 128 + +/* Grab EEPROM contents, needed for direct method. */ +static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) +{ + struct i2c_msg msg[2]; + u8 *eeprom; + u8 offs; + int ret; + unsigned pcnt,tcnt; + eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); + if (!eeprom) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Failed to allocate memory" + " required to read eeprom"); + return 0; + } + + msg[0].addr = PVR_EEPROM_I2C_ADDR; + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = &offs; + msg[1].addr = PVR_EEPROM_I2C_ADDR; + msg[1].flags = I2C_M_RD; + + /* We have to do the actual eeprom data fetch ourselves, because + (1) we're only fetching part of the eeprom, and (2) if we were + getting the whole thing our I2C driver can't grab it in one + pass - which is what tveeprom is otherwise going to attempt */ + memset(eeprom,0,EEPROM_SIZE); + for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { + pcnt = 16; + if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; + offs = tcnt + EEPROM_OFFS; + msg[1].len = pcnt; + msg[1].buf = eeprom+tcnt; + if ((ret = i2c_transfer( + &hdw->i2c_adap, + msg,sizeof(msg)/sizeof(msg[0]))) != 2) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "eeprom fetch set offs err=%d",ret); + kfree(eeprom); + return 0; + } + } + return eeprom; +} + + +#ifndef PVR2_EEPROM_IVTV +/*VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*/ +/* BEGIN DIRECT METHOD, V4L ONLY */ + -#ifdef PVRUSB2_EEPROM_DIRECT_CALL +/* Directly call eeprom analysis function within tveeprom. This + version directly assumes it is talking to the V4L version of + tveeprom.ko and does not attempt anything ugly to maintain + backwards compatibility. */ + +int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) +{ + u8 *eeprom; + struct tveeprom tvdata; + + memset(&tvdata,0,sizeof(tvdata)); + + eeprom = pvr2_eeprom_fetch(hdw); + if (!eeprom) return -EINVAL; + + { + struct i2c_client fake_client; + /* Newer version expects a useless client interface */ + fake_client.addr = PVR_EEPROM_I2C_ADDR; + fake_client.adapter = &hdw->i2c_adap; + tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom); + } + + trace_eeprom("eeprom assumed v4l tveeprom module"); + trace_eeprom("eeprom direct call results:"); + trace_eeprom("has_radio=%d",tvdata.has_radio); + trace_eeprom("tuner_type=%d",tvdata.tuner_type); + trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats); + trace_eeprom("audio_processor=%d",tvdata.audio_processor); + trace_eeprom("model=%d",tvdata.model); + trace_eeprom("revision=%d",tvdata.revision); + trace_eeprom("serial_number=%d",tvdata.serial_number); + trace_eeprom("rev_str=%s",tvdata.rev_str); + hdw->tuner_type = tvdata.tuner_type; + hdw->serial_number = tvdata.serial_number; + hdw->video_standards = tvdata.tuner_formats; + + kfree(eeprom); + + return 0; +} + + + +/* END DIRECT METHOD, V4L ONLY */ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +#endif /* PVR2_EEPROM_IVTV */ + + + + +#ifdef PVR2_EEPROM_IVTV +/*VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*/ +/* BEGIN DIRECT METHOD, V4L OR IVTV */ /* Directly call eeprom analysis function within tveeprom. This has portability issues because the internal API has been changing. We @@ -124,19 +250,6 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) a hint to determine exactly which tveeprom structure had been used. Did I say this was ugly? It's disgusting. */ -#define PVR_EEPROM_I2C_ADDR 0x50 - -#include <media/tveeprom.h> - -/* - * Read and analyze data in the eeprom. Use tveeprom to figure out - * the packet structure, since this is another Hauppauge device and - * internally it has a family resemblence to ivtv-type devices - */ - -/* We seem to only be interested in the back half of the EEPROM */ -#define EEPROM_SIZE 128 -#define EEPROM_OFFS 128 /* This has to be an EXACT(!!) match with the tveeprom structure defined in our local copy of tveeprom.c. */ @@ -163,11 +276,8 @@ struct tveeprom_ivtv { int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) { u8 *eeprom; - u8 offs; - unsigned pcnt,tcnt; - int ret; + unsigned tcnt; int tp; - struct i2c_msg msg[2]; union { struct tveeprom v4l; struct tveeprom_ivtv ivtv; @@ -175,38 +285,8 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) memset(&tvdata,0x93,sizeof(tvdata)); - eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); - if (!eeprom) { - return -ENOMEM; - } - - msg[0].addr = PVR_EEPROM_I2C_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &offs; - msg[1].addr = PVR_EEPROM_I2C_ADDR; - msg[1].flags = I2C_M_RD; - - /* We have to do the actual eeprom data fetch ourselves, because - (1) we're only fetching part of the eeprom, and (2) if we were - getting the whole thing our I2C driver can't grab it in one - pass - which is what tveeprom is otherwise going to attempt */ - memset(eeprom,0,EEPROM_SIZE); - for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { - pcnt = 16; - if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; - offs = tcnt + EEPROM_OFFS; - msg[1].len = pcnt; - msg[1].buf = eeprom+tcnt; - if ((ret = i2c_transfer( - &hdw->i2c_adap, - msg,sizeof(msg)/sizeof(msg[0]))) != 2) { - trace_eeprom("eeprom fetch set offs err=%d",ret); - if (ret > 0) ret = -EIO; - kfree(eeprom); - return ret; - } - } + eeprom = pvr2_eeprom_fetch(hdw); + if (!eeprom) return -EINVAL; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) { @@ -274,7 +354,12 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) return 0; } -#endif + +/* END DIRECT METHOD, V4L OR IVTV */ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +#endif /* PVR2_EEPROM_V4L */ + +#endif /* PVR2_EEPROM_INDIRECT */ static v4l2_std_id std_choices[] = { diff --git a/v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h b/v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h index ad5cc0731..3051d6cc9 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h +++ b/v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-hdw-internal.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-hdw-internal.h,v 1.2 2005/11/27 23:01:16 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -51,6 +51,8 @@ #define LOCK_TAKE(x) do { down(&x##_sem); x##_held = !0; } while (0) #define LOCK_GIVE(x) do { x##_held = 0; up(&x##_sem); } while (0) +struct pvr2_decoder; + struct pvr2_ctl_state { int value; int dirty; @@ -121,8 +123,8 @@ struct pvr2_hdw { unsigned int tuner_type; unsigned long video_standards; - /* saa7115 info: 0=unknown 1=new decoder 2=old decoder */ - int decoder_info; + /* Context for controller video decoder (see pvrusb2-video.h) */ + struct pvr2_decoder *dcp; int unit_number; /* ID for driver instance */ unsigned long serial_number; /* ID for hardware itself */ diff --git a/v4l_experimental/pvrusb2/pvrusb2-hdw.c b/v4l_experimental/pvrusb2/pvrusb2-hdw.c index 6853db776..715fb772e 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-hdw.c +++ b/v4l_experimental/pvrusb2/pvrusb2-hdw.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-hdw.c,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-hdw.c,v 1.2 2005/11/27 23:01:16 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -702,8 +702,8 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, if (vmsk & PVR2_SUBSYS_DIGITIZER_RUN) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" - " pvr2_decoder_enable_output(0)"); - pvr2_decoder_enable_output(hdw,0); + " pvr2_decoder_disable_output"); + pvr2_decoder_disable_output(hdw->dcp); } if (vmsk & PVR2_SUBSYS_CFG_ALL) { hdw->subsys_enabled_mask &= @@ -759,31 +759,31 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_decoder_set_norm"); - pvr2_decoder_set_norm(hdw); + pvr2_decoder_set_norm(hdw->dcp); } if (vmsk & PVR2_SUBSYS_DIGITIZER_CFG_INPUT) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_decoder_set_input"); - pvr2_decoder_set_input(hdw); + pvr2_decoder_set_input(hdw->dcp); } if (vmsk & PVR2_SUBSYS_DIGITIZER_CFG_SIZE) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_decoder_set_size"); - pvr2_decoder_set_size(hdw); + pvr2_decoder_set_size(hdw->dcp); } if (vmsk & PVR2_SUBSYS_DIGITIZER_CFG_AUDIO) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_decoder_set_audio"); - pvr2_decoder_set_audio(hdw); + pvr2_decoder_set_audio(hdw->dcp); } if (vmsk & PVR2_SUBSYS_DIGITIZER_CFG_BCSH) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_decoder_set_bcsh"); - pvr2_decoder_set_bcsh(hdw); + pvr2_decoder_set_bcsh(hdw->dcp); } if (vmsk & PVR2_SUBSYS_ENC_CFG) { pvr2_trace(PVR2_TRACE_CTL, @@ -801,8 +801,8 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, if (vmsk & PVR2_SUBSYS_DIGITIZER_RUN) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" - " pvr2_decoder_enable_output(1)"); - pvr2_decoder_enable_output(hdw,!0); + " pvr2_decoder_enable_output"); + pvr2_decoder_enable_output(hdw->dcp); } if (vmsk & PVR2_SUBSYS_USBSTREAM_RUN) { pvr2_trace(PVR2_TRACE_CTL, @@ -982,6 +982,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) pvr2_reset_ctl_endpoints(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; + hdw->dcp = pvr2_decoder_create(hdw); + pvr2_eeprom_analyze(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; @@ -1185,6 +1187,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) pvr2_stream_destroy(hdw->vid_stream); hdw->vid_stream = 0; } + pvr2_decoder_destroy(hdw->dcp); + hdw->dcp = 0; pvr2_i2c_done(hdw); pvr2_hdw_remove_usb_stuff(hdw); down(&pvr2_unit_sem); do { @@ -1557,7 +1561,7 @@ unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw) switch (hdw->controls[PVR2_CID_INPUT].value) { case PVR2_CVAL_INPUT_TV: case PVR2_CVAL_INPUT_RADIO: - if (pvr2_decoder_is_tuned(hdw)) { + if (pvr2_decoder_is_tuned(hdw->dcp) > 0) { msk |= PVR2_SIGNAL_OK; if (pvr2_audio_update_status(hdw) == 0) { if (hdw->flag_stereo) { diff --git a/v4l_experimental/pvrusb2/pvrusb2-i2c.c b/v4l_experimental/pvrusb2/pvrusb2-i2c.c index d5cb7467a..fe3ca04f5 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-i2c.c +++ b/v4l_experimental/pvrusb2/pvrusb2-i2c.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-i2c.c,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-i2c.c,v 1.2 2005/11/27 23:01:16 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -286,10 +286,18 @@ static int pvr2_i2c_attach_inform(struct i2c_client *client) hdw->i2c_tuner_client = client; pvr2_tuner_set_type(hdw); } +#ifdef PVR2_ENABLE_SAA7115 if (!(hdw->i2c_video_client) && (id == I2C_DRIVERID_SAA7115)) { trace_i2c("attaching saa7115 I2C client"); hdw->i2c_video_client = client; } +#endif +#ifndef PVR2_SUPPRESS_SAA711X + if (!(hdw->i2c_video_client) && (id == I2C_DRIVERID_SAA711X)) { + trace_i2c("attaching saa711x I2C client"); + hdw->i2c_video_client = client; + } +#endif if (!(hdw->i2c_tveeprom_client) && (id == I2C_DRIVERID_TVEEPROM)) { trace_i2c("attaching tveeprom I2C client"); hdw->i2c_tveeprom_client = client; @@ -358,7 +366,7 @@ static int pvr2_i2c_detach_inform(struct i2c_client *client) hdw->i2c_tuner_client = 0; } if (hdw->i2c_video_client == client) { - trace_i2c("detaching saa7115 I2C client"); + trace_i2c("detaching saa7115 / saa711x I2C client"); hdw->i2c_video_client = 0; } if (hdw->i2c_tveeprom_client == client) { diff --git a/v4l_experimental/pvrusb2/pvrusb2-version.h b/v4l_experimental/pvrusb2/pvrusb2-version.h index 5e3c98a68..f210962d5 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-version.h +++ b/v4l_experimental/pvrusb2/pvrusb2-version.h @@ -1,4 +1,4 @@ #ifndef _INCLUDED_PVRUSB2_DRIVER_VERSION #define _INCLUDED_PVRUSB2_DRIVER_VERSION -#define DRIVER_VERSION "20051113 (from v4l tree)" +#define DRIVER_VERSION "20051126 (from v4l tree)" #endif diff --git a/v4l_experimental/pvrusb2/pvrusb2-video-v4l.c b/v4l_experimental/pvrusb2/pvrusb2-video-v4l.c new file mode 100644 index 000000000..fa35640f2 --- /dev/null +++ b/v4l_experimental/pvrusb2/pvrusb2-video-v4l.c @@ -0,0 +1,277 @@ +/* + * + * $Id: pvrusb2-video-v4l.c,v 1.1 2005/11/27 23:01:16 mcisely Exp $ + * + * Copyright (C) 2005 Mike Isely <isely@pobox.com> + * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + + This module connects the pvrusb2 driver to the I2C chip level + driver which handles device video processing. This interface is + used internally by the driver; higher level code should only + interact through the interface provided by pvrusb2-hdw.h. + + This source file is specifically designed to interface with the + saa711x support that is available in the v4l available starting + with linux 2.6.15. + +*/ + +#include "pvrusb2-video-v4l.h" + +#ifndef PVR2_SUPPRESS_SAA711X + +#include "pvrusb2-i2c.h" +#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-debug.h" +#include <linux/videodev.h> +#include <media/v4l2-common.h> +#include <linux/errno.h> +#include <linux/slab.h> + + +#define pvr2_decoder_trace(...) pvr2_trace(PVR2_TRACE_DECODER,__VA_ARGS__) + + +static int pvr2_decoder_v4l_enable_output(struct pvr2_decoder *dcp) +{ + int status; + struct pvr2_hdw *hdw = dcp->hdw; + pvr2_decoder_trace("pvr2_decoder_enable_output"); + status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_STREAMON,0); + if (status) return status; + hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_RUN; + return 0; +} + + +static int pvr2_decoder_v4l_disable_output(struct pvr2_decoder *dcp) +{ + int status; + struct pvr2_hdw *hdw = dcp->hdw; + pvr2_decoder_trace("pvr2_decoder_disable_output"); + status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_STREAMOFF,0); + if (status) return status; + hdw->subsys_enabled_mask &= ~PVR2_SUBSYS_DIGITIZER_RUN; + return 0; +} + + +static int pvr2_decoder_v4l_set_input(struct pvr2_decoder *dcp) +{ + int status; + struct pvr2_hdw *hdw = dcp->hdw; + int v = 0; + pvr2_decoder_trace("pvr2_decoder_set_input(%d)", + hdw->controls[PVR2_CID_INPUT].value); + switch(hdw->controls[PVR2_CID_INPUT].value){ + case PVR2_CVAL_INPUT_TV: + v = 4; + break; + case PVR2_CVAL_INPUT_COMPOSITE: + v = 5; + break; + case PVR2_CVAL_INPUT_SVIDEO: + v = 8; + break; + case PVR2_CVAL_INPUT_RADIO: + // ????? No idea yet what to do here + default: + return -EINVAL; + } + status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_INPUT,&v); + if (!status) { + hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_INPUT; + } + return status; +} + + +static int pvr2_decoder_v4l_set_bcsh(struct pvr2_decoder *dcp) +{ + struct v4l2_control ctrl; + struct pvr2_hdw *hdw = dcp->hdw; + int ret; + memset(&ctrl,0,sizeof(ctrl)); + + pvr2_decoder_trace("pvr2_decoder_set_bcsh b=%d c=%d s=%d h=%d", + hdw->controls[PVR2_CID_BRIGHTNESS].value, + hdw->controls[PVR2_CID_CONTRAST].value, + hdw->controls[PVR2_CID_SATURATION].value, + hdw->controls[PVR2_CID_HUE].value); + + ctrl.id = V4L2_CID_BRIGHTNESS; + ctrl.value = hdw->controls[PVR2_CID_BRIGHTNESS].value; + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + if (ret) return ret; + ctrl.id = V4L2_CID_CONTRAST; + ctrl.value = hdw->controls[PVR2_CID_CONTRAST].value; + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + if (ret) return ret; + ctrl.id = V4L2_CID_SATURATION; + ctrl.value = hdw->controls[PVR2_CID_SATURATION].value; + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + if (ret) return ret; + ctrl.id = V4L2_CID_HUE; + ctrl.value = hdw->controls[PVR2_CID_HUE].value; + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + if (ret) return ret; + + hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_BCSH; + return 0; +} + + +static int pvr2_decoder_v4l_is_tuned(struct pvr2_decoder *dcp) +{ + struct v4l2_tuner vt; + struct pvr2_hdw *hdw = dcp->hdw; + int ret; + + memset(&vt,0,sizeof(vt)); + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_G_TUNER,&vt); + if (ret < 0) return -EINVAL; + return vt.signal ? 1 : 0; +} + + +static int pvr2_decoder_v4l_set_size(struct pvr2_decoder *dcp) +{ + struct v4l2_format fmt; + struct pvr2_hdw *hdw = dcp->hdw; + int ret; + + memset(&fmt,0,sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = hdw->controls[PVR2_CID_HRES].value; + fmt.fmt.pix.height = hdw->controls[PVR2_CID_VRES].value; + + pvr2_decoder_trace("pvr2_decoder_set_size(%dx%d)", + fmt.fmt.pix.width,fmt.fmt.pix.height); + + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_FMT,&fmt); + if (ret) return ret; + + hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_SIZE; + return 0; +} + + +static int pvr2_decoder_v4l_set_audio(struct pvr2_decoder *dcp) +{ + int ret; + struct pvr2_hdw *hdw = dcp->hdw; + enum v4l2_audio_clock_freq val; + + pvr2_decoder_trace("pvr2_decoder_set_audio %d", + hdw->controls[PVR2_CID_SRATE].value); + switch (hdw->controls[PVR2_CID_SRATE].value) { + default: + case PVR2_CVAL_SRATE_48: + val = V4L2_AUDCLK_48_KHZ; + break; + case PVR2_CVAL_SRATE_44_1: + val = V4L2_AUDCLK_441_KHZ; + break; + } + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); + if (ret) return ret; + hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_AUDIO; + return 0; +} + + +static int pvr2_decoder_v4l_set_norm(struct pvr2_decoder *dcp) +{ + v4l2_std_id std; + struct pvr2_hdw *hdw = dcp->hdw; + int status; + pvr2_decoder_trace("pvr2_decoder_set_norm %d", + hdw->controls[PVR2_CID_VIDEOSTANDARD].value); + switch (hdw->controls[PVR2_CID_VIDEOSTANDARD].value) { + default: + case PVR2_CVAL_VIDEOSTANDARD_NTSC_M: + std = V4L2_STD_NTSC; + break; + case PVR2_CVAL_VIDEOSTANDARD_SECAM_L: + std = V4L2_STD_SECAM; + break; + case PVR2_CVAL_VIDEOSTANDARD_PAL_I: + std = V4L2_STD_PAL_I; + break; + case PVR2_CVAL_VIDEOSTANDARD_PAL_DK: + std = V4L2_STD_PAL_DK; + break; + case PVR2_CVAL_VIDEOSTANDARD_PAL_BG: + std = V4L2_STD_PAL_BG; + break; + } + status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_STD,&std); + if (status) return status; + hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_NORM; + return 0; +} + + +static const struct pvr2_decoder_func_table pvr2_decoder_v4l_table = { + (pvr2_decoder_func)0, + (pvr2_decoder_func)pvr2_decoder_v4l_set_norm, + (pvr2_decoder_func)pvr2_decoder_v4l_set_input, + (pvr2_decoder_func)pvr2_decoder_v4l_set_size, + (pvr2_decoder_func)pvr2_decoder_v4l_set_audio, + (pvr2_decoder_func)pvr2_decoder_v4l_set_bcsh, + (pvr2_decoder_func)pvr2_decoder_v4l_is_tuned, + (pvr2_decoder_func)pvr2_decoder_v4l_enable_output, + (pvr2_decoder_func)pvr2_decoder_v4l_disable_output, +}; + + +struct pvr2_decoder *pvr2_decoder_v4l_create(struct pvr2_hdw *hdw) +{ + /* Attempt to query the decoder - let's see if it will answer */ + struct v4l2_tuner vt; + int ret; + struct pvr2_decoder *dcp; + + memset(&vt,0,sizeof(vt)); + ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_G_TUNER,&vt); + if (ret < 0) return 0; /* Nope, not there */ + + /* Yes, it's there. So initialize... */ + dcp = kmalloc(sizeof(*dcp),GFP_KERNEL); + if (!dcp) return 0; + memset(dcp,0,sizeof(*dcp)); + dcp->hdw = hdw; + dcp->func_table = &pvr2_decoder_v4l_table; + return dcp; +} + +#endif /* PVR2_SUPPRESS_SAA711X */ + + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/v4l_experimental/pvrusb2/pvrusb2-video-v4l.h b/v4l_experimental/pvrusb2/pvrusb2-video-v4l.h new file mode 100644 index 000000000..e3ef12602 --- /dev/null +++ b/v4l_experimental/pvrusb2/pvrusb2-video-v4l.h @@ -0,0 +1,54 @@ +/* + * + * $Id: pvrusb2-video-v4l.h,v 1.1 2005/11/27 23:01:16 mcisely Exp $ + * + * Copyright (C) 2005 Mike Isely <isely@pobox.com> + * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __PVRUSB2_VIDEO_V4L_H +#define __PVRUSB2_VIDEO_V4L_H + +/* + + This module connects the pvrusb2 driver to the I2C chip level + driver which handles device video processing. This interface is + used internally by the driver; higher level code should only + interact through the interface provided by pvrusb2-hdw.h. + +*/ + +#include "compat.h" +#include "pvrusb2-video.h" + +#ifndef PVR2_SUPPRESS_SAA711X + +struct pvr2_decoder *pvr2_decoder_v4l_create(struct pvr2_hdw *); + +#endif /* PVR2_SUPPRESS_SAA711X */ + +#endif /* __PVRUSB2_VIDEO_V4L_H */ + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/v4l_experimental/pvrusb2/pvrusb2-video.c b/v4l_experimental/pvrusb2/pvrusb2-video.c index 7b4e973c5..3dc18ec55 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-video.c +++ b/v4l_experimental/pvrusb2/pvrusb2-video.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-video.c,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-video.c,v 1.2 2005/11/27 23:01:16 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -27,184 +27,120 @@ used internally by the driver; higher level code should only interact through the interface provided by pvrusb2-hdw.h. - This source file is specifically designed to interface with the - saa711x support that is available in the v4l available starting - with linux 2.6.15. + Since there are several possible choices of low level drivers, we + go through a layer of indirection in an attempt to select the right + choice. This module implements that indirection. */ -#include "pvrusb2-i2c.h" +#include "compat.h" #include "pvrusb2-video.h" -#include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" -#include <linux/videodev.h> -#include <media/v4l2-common.h> +#ifndef PVR2_SUPPRESS_SAA711X +#include "pvrusb2-video-v4l.h" +#endif +#ifdef PVR2_ENABLE_SAA7115 +#include "pvrusb2-video-ivtv.h" +#endif +#include "pvrusb2-debug.h" +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/slab.h> -#define pvr2_decoder_trace(...) pvr2_trace(PVR2_TRACE_DECODER,__VA_ARGS__) -int pvr2_decoder_enable_output(struct pvr2_hdw *hdw,int fl) +struct pvr2_decoder *pvr2_decoder_create(struct pvr2_hdw *hdw) { - int status; - pvr2_decoder_trace("pvr2_decoder_enable_output(%d)",fl); - if (fl) { - status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_STREAMON,0); - } else { - status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_STREAMOFF,0); + struct pvr2_decoder *dcp; + +#ifndef PVR2_SUPPRESS_SAA711X + dcp = pvr2_decoder_v4l_create(hdw); + if (dcp) { + pvr2_trace(PVR2_TRACE_INIT,"Using v4l video decoder driver"); + return dcp; } - if (!status) { - hdw->subsys_enabled_mask = - ((hdw->subsys_enabled_mask & - ~PVR2_SUBSYS_DIGITIZER_RUN) | - (fl ? PVR2_SUBSYS_DIGITIZER_RUN : 0)); +#endif + +#ifdef PVR2_ENABLE_SAA7115 + dcp = pvr2_decoder_ivtv_create(hdw); + if (dcp) { + pvr2_trace(PVR2_TRACE_INIT,"Using ivtv video decoder driver"); + return dcp; } - return status; +#endif + + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Failed to select a viable v4l video decoder driver"); + return 0; } -int pvr2_decoder_set_input(struct pvr2_hdw *hdw) + +void pvr2_decoder_destroy(struct pvr2_decoder *dcp) { - int status; - int v = 0; - pvr2_decoder_trace("pvr2_decoder_set_input(%d)", - hdw->controls[PVR2_CID_INPUT].value); - switch(hdw->controls[PVR2_CID_INPUT].value){ - case PVR2_CVAL_INPUT_TV: - v = 4; - break; - case PVR2_CVAL_INPUT_COMPOSITE: - v = 5; - break; - case PVR2_CVAL_INPUT_SVIDEO: - v = 8; - break; - case PVR2_CVAL_INPUT_RADIO: - // ????? No idea yet what to do here - default: - return -EINVAL; - } - status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_INPUT,&v); - if (!status) { - hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_INPUT; + if (!dcp) return; + if (dcp->func_table->destroy_func) { + dcp->func_table->destroy_func(dcp); + } else { + kfree(dcp); } - return status; } -int pvr2_decoder_set_bcsh(struct pvr2_hdw *hdw) + +int pvr2_decoder_set_norm(struct pvr2_decoder *dcp) { - struct v4l2_control ctrl; - int ret; - memset(&ctrl,0,sizeof(ctrl)); - - pvr2_decoder_trace("pvr2_decoder_set_bcsh b=%d c=%d s=%d h=%d", - hdw->controls[PVR2_CID_BRIGHTNESS].value, - hdw->controls[PVR2_CID_CONTRAST].value, - hdw->controls[PVR2_CID_SATURATION].value, - hdw->controls[PVR2_CID_HUE].value); - - ctrl.id = V4L2_CID_BRIGHTNESS; - ctrl.value = hdw->controls[PVR2_CID_BRIGHTNESS].value; - ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - if (ret) return ret; - ctrl.id = V4L2_CID_CONTRAST; - ctrl.value = hdw->controls[PVR2_CID_CONTRAST].value; - ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - if (ret) return ret; - ctrl.id = V4L2_CID_SATURATION; - ctrl.value = hdw->controls[PVR2_CID_SATURATION].value; - ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - if (ret) return ret; - ctrl.id = V4L2_CID_HUE; - ctrl.value = hdw->controls[PVR2_CID_HUE].value; - ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - if (ret) return ret; - - hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_BCSH; - return 0; + if (!dcp) return -EINVAL; + return dcp->func_table->set_norm_func(dcp); } -int pvr2_decoder_is_tuned(struct pvr2_hdw *hdw) -{ - struct v4l2_tuner vt; - int ret; - memset(&vt,0,sizeof(vt)); - ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_G_TUNER,&vt); - if (ret < 0) return 0; - return vt.signal != 0; +int pvr2_decoder_set_input(struct pvr2_decoder *dcp) +{ + if (!dcp) return -EINVAL; + return dcp->func_table->set_input_func(dcp); } -int pvr2_decoder_set_size(struct pvr2_hdw *hdw) + +int pvr2_decoder_set_size(struct pvr2_decoder *dcp) { - struct v4l2_format fmt; - int ret; + if (!dcp) return -EINVAL; + return dcp->func_table->set_size_func(dcp); +} - memset(&fmt,0,sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = hdw->controls[PVR2_CID_HRES].value; - fmt.fmt.pix.height = hdw->controls[PVR2_CID_VRES].value; +int pvr2_decoder_set_audio(struct pvr2_decoder *dcp) +{ + if (!dcp) return -EINVAL; + return dcp->func_table->set_audio_func(dcp); +} - pvr2_decoder_trace("pvr2_decoder_set_size(%dx%d)", - fmt.fmt.pix.width,fmt.fmt.pix.height); - ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_FMT,&fmt); - if (ret) return ret; +int pvr2_decoder_set_bcsh(struct pvr2_decoder *dcp) +{ + if (!dcp) return -EINVAL; + return dcp->func_table->set_bcsh_func(dcp); +} - hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_SIZE; - return 0; + +int pvr2_decoder_is_tuned(struct pvr2_decoder *dcp) +{ + if (!dcp) return -EINVAL; + return dcp->func_table->is_tuned_func(dcp); } -int pvr2_decoder_set_audio(struct pvr2_hdw *hdw) + +int pvr2_decoder_enable_output(struct pvr2_decoder *dcp) { - int ret; - enum v4l2_audio_clock_freq val; - - pvr2_decoder_trace("pvr2_decoder_set_audio %d", - hdw->controls[PVR2_CID_SRATE].value); - switch (hdw->controls[PVR2_CID_SRATE].value) { - default: - case PVR2_CVAL_SRATE_48: - val = V4L2_AUDCLK_48_KHZ; - break; - case PVR2_CVAL_SRATE_44_1: - val = V4L2_AUDCLK_441_KHZ; - break; - } - ret = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); - if (ret) return ret; - hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_AUDIO; - return 0; + if (!dcp) return -EINVAL; + return dcp->func_table->enable_func(dcp); } -int pvr2_decoder_set_norm(struct pvr2_hdw *hdw) + +int pvr2_decoder_disable_output(struct pvr2_decoder *dcp) { - v4l2_std_id std; - int status; - pvr2_decoder_trace("pvr2_decoder_set_norm %d", - hdw->controls[PVR2_CID_VIDEOSTANDARD].value); - switch (hdw->controls[PVR2_CID_VIDEOSTANDARD].value) { - default: - case PVR2_CVAL_VIDEOSTANDARD_NTSC_M: - std = V4L2_STD_NTSC; - break; - case PVR2_CVAL_VIDEOSTANDARD_SECAM_L: - std = V4L2_STD_SECAM; - break; - case PVR2_CVAL_VIDEOSTANDARD_PAL_I: - std = V4L2_STD_PAL_I; - break; - case PVR2_CVAL_VIDEOSTANDARD_PAL_DK: - std = V4L2_STD_PAL_DK; - break; - case PVR2_CVAL_VIDEOSTANDARD_PAL_BG: - std = V4L2_STD_PAL_BG; - break; - } - status = pvr2_i2c_saa7115_cmd(hdw,VIDIOC_S_STD,&std); - if (status) return status; - hdw->subsys_enabled_mask |= PVR2_SUBSYS_DIGITIZER_CFG_NORM; - return 0; + if (!dcp) return -EINVAL; + return dcp->func_table->disable_func(dcp); } + /* Stuff for Emacs to see, in order to encourage consistent editing style: *** Local Variables: *** diff --git a/v4l_experimental/pvrusb2/pvrusb2-video.h b/v4l_experimental/pvrusb2/pvrusb2-video.h index 8c081ccd2..f08c3671d 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-video.h +++ b/v4l_experimental/pvrusb2/pvrusb2-video.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-video.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-video.h,v 1.2 2005/11/27 23:01:16 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -33,14 +33,38 @@ */ struct pvr2_hdw; +struct pvr2_decoder; + +typedef int (*pvr2_decoder_func)(struct pvr2_decoder *); + +struct pvr2_decoder_func_table { + pvr2_decoder_func destroy_func; + pvr2_decoder_func set_norm_func; + pvr2_decoder_func set_input_func; + pvr2_decoder_func set_size_func; + pvr2_decoder_func set_audio_func; + pvr2_decoder_func set_bcsh_func; + pvr2_decoder_func is_tuned_func; + pvr2_decoder_func enable_func; + pvr2_decoder_func disable_func; +}; + +struct pvr2_decoder { + struct pvr2_hdw *hdw; + const struct pvr2_decoder_func_table *func_table; +}; + +struct pvr2_decoder *pvr2_decoder_create(struct pvr2_hdw *); +void pvr2_decoder_destroy(struct pvr2_decoder *); +int pvr2_decoder_set_norm(struct pvr2_decoder *); +int pvr2_decoder_set_input(struct pvr2_decoder *); +int pvr2_decoder_set_size(struct pvr2_decoder *); +int pvr2_decoder_set_audio(struct pvr2_decoder *); +int pvr2_decoder_set_bcsh(struct pvr2_decoder *); +int pvr2_decoder_is_tuned(struct pvr2_decoder *); +int pvr2_decoder_enable_output(struct pvr2_decoder *); +int pvr2_decoder_disable_output(struct pvr2_decoder *); -int pvr2_decoder_set_norm(struct pvr2_hdw *); -int pvr2_decoder_set_input(struct pvr2_hdw *); -int pvr2_decoder_set_size(struct pvr2_hdw *); -int pvr2_decoder_set_audio(struct pvr2_hdw *); -int pvr2_decoder_set_bcsh(struct pvr2_hdw *); -int pvr2_decoder_is_tuned(struct pvr2_hdw *); -int pvr2_decoder_enable_output(struct pvr2_hdw *,int); #endif /* __PVRUSB2_VIDEO_H */ |