summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--v4l_experimental/pvrusb2/Kbuild1
-rw-r--r--v4l_experimental/pvrusb2/Makefile40
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-eeprom.c207
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h8
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-hdw.c26
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-i2c.c12
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-version.h2
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-video-v4l.c277
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-video-v4l.h54
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-video.c222
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-video.h40
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 */