summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-04-02 03:24:11 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-04-02 03:24:11 -0300
commite1fbc574390b85339c21945ec238e87018601a08 (patch)
treef867f3c77fdd72133e0b5295475e71804039cffe /linux/drivers
parentdbe2e81959f002660345a0b09161b230df7765cf (diff)
parentb2dfa0b965563e6fdc3bb36dde59473b97b01a6a (diff)
downloadmediapointer-dvb-s2-e1fbc574390b85339c21945ec238e87018601a08.tar.gz
mediapointer-dvb-s2-e1fbc574390b85339c21945ec238e87018601a08.tar.bz2
Merge from http://linuxtv.org/hg/~hverkuil/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@infradead.org> merge: Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers')
-rw-r--r--linux/drivers/media/video/cx88/Kconfig13
-rw-r--r--linux/drivers/media/video/pvrusb2/Kconfig45
-rw-r--r--linux/drivers/media/video/pvrusb2/Makefile13
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-audio.c23
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c116
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h1
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c12
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h125
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c1006
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h200
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c4
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c30
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c15
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-main.c10
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c134
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c400
16 files changed, 1307 insertions, 840 deletions
diff --git a/linux/drivers/media/video/cx88/Kconfig b/linux/drivers/media/video/cx88/Kconfig
index 2c586f903..630273992 100644
--- a/linux/drivers/media/video/cx88/Kconfig
+++ b/linux/drivers/media/video/cx88/Kconfig
@@ -1,3 +1,7 @@
+config VIDEO_CX88_VP3054
+ tristate
+ depends on VIDEO_CX88_DVB && DVB_MT352
+
config VIDEO_CX88
tristate "Conexant 2388x (bt878 successor) support"
depends on VIDEO_DEV && PCI && I2C
@@ -73,10 +77,11 @@ config VIDEO_CX88_DVB_MT352
This adds DVB-T support for cards based on the
Connexant 2388x chip and the MT352 demodulator.
-config VIDEO_CX88_VP3054
- tristate "VP-3054 Secondary I2C Bus Support"
- default m
- depends on DVB_MT352
+config VIDEO_CX88_DVB_VP3054
+ bool "VP-3054 Secondary I2C Bus Support"
+ default y
+ depends on VIDEO_CX88_DVB_MT352
+ select VIDEO_CX88_VP3054
---help---
This adds DVB-T support for cards based on the
Connexant 2388x chip and the MT352 demodulator,
diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig
index 9824ad267..629dc4e05 100644
--- a/linux/drivers/media/video/pvrusb2/Kconfig
+++ b/linux/drivers/media/video/pvrusb2/Kconfig
@@ -12,3 +12,48 @@ config VIDEO_PVRUSB2
To compile this driver as a module, choose M here: the
module will be called pvrusb2
+
+config VIDEO_PVRUSB2_24XXX
+ bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series"
+ depends on VIDEO_PVRUSB2 && EXPERIMENTAL
+ ---help---
+ This option enables inclusion of additional logic to operate
+ newer WinTV-PVR USB2 devices whose model number is of the
+ form "24xxx" (leading prefix of "24" followed by 3 digits).
+ To see if you may need this option, examine the white
+ sticker on the underside of your device. Enabling this
+ option will not harm support for older devices, however it
+ is a separate option because of the experimental nature of
+ this new feature.
+
+ If you are in doubt, say N.
+
+ Note: This feature is _very_ experimental. You have been
+ warned.
+
+config VIDEO_PVRUSB2_SYSFS
+ bool "pvrusb2 sysfs support"
+ default y
+ depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL
+ ---help---
+ This option enables the operation of a sysfs based
+ interface for query and control of the pvrusb2 driver.
+
+ This is not generally needed for v4l applications,
+ although certain applications are optimized to take
+ advantage of this feature.
+
+ If you are in doubt, say Y.
+
+ Note: This feature is experimental and subject to change.
+
+config VIDEO_PVRUSB2_DEBUGIFC
+ bool "pvrusb2 debug interface"
+ depends on VIDEO_PVRUSB2_SYSFS
+ ---help---
+ This option enables the inclusion of a debug interface
+ in the pvrusb2 driver, hosted through sysfs.
+
+ You do not need to select this option unless you plan
+ on debugging the driver or performing a manual firmware
+ extraction.
diff --git a/linux/drivers/media/video/pvrusb2/Makefile b/linux/drivers/media/video/pvrusb2/Makefile
index 4a37fe723..53fccce4f 100644
--- a/linux/drivers/media/video/pvrusb2/Makefile
+++ b/linux/drivers/media/video/pvrusb2/Makefile
@@ -1,11 +1,18 @@
+obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
+obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
+
+obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \
+ pvrusb2-cx2584x-v4l.o \
+ pvrusb2-wm8775.o
+
pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
pvrusb2-encoder.o pvrusb2-video-v4l.o \
pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \
pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
- pvrusb2-sysfs.o pvrusb2-context.o pvrusb2-io.o \
- pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
- pvrusb2-ioread.o pvrusb2-debugifc.o
+ pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
+ $(obj-pvrusb2-24xxx-y) \
+ $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 031412327..7f29a8821 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -37,26 +37,6 @@ struct pvr2_msp3400_handler {
};
-static int xlat_audiomode_to_v4l2(int id)
-{
- switch (id) {
- case PVR2_CVAL_AUDIOMODE_MONO:
- return V4L2_TUNER_MODE_MONO;
- case PVR2_CVAL_AUDIOMODE_STEREO:
- return V4L2_TUNER_MODE_STEREO;
- case PVR2_CVAL_AUDIOMODE_SAP:
- return V4L2_TUNER_MODE_SAP;
- case PVR2_CVAL_AUDIOMODE_LANG1:
- return V4L2_TUNER_MODE_LANG1;
- case PVR2_CVAL_AUDIOMODE_LANG2:
- return V4L2_TUNER_MODE_LANG2;
- case PVR2_CVAL_AUDIOMODE_LANG1_LANG2:
- return V4L2_TUNER_MODE_LANG1_LANG2;
- }
- return V4L2_TUNER_MODE_STEREO;
-}
-
-
/* This function selects the correct audio input source */
static void set_stereo(struct pvr2_msp3400_handler *ctxt)
{
@@ -68,8 +48,7 @@ static void set_stereo(struct pvr2_msp3400_handler *ctxt)
if (hdw->controls[PVR2_CID_INPUT].value == PVR2_CVAL_INPUT_TV) {
struct v4l2_tuner vt;
memset(&vt,0,sizeof(vt));
- vt.audmode = xlat_audiomode_to_v4l2(
- hdw->controls[PVR2_CID_AUDIOMODE].value);
+ vt.audmode = hdw->controls[PVR2_CID_AUDIOMODE].value;
pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt);
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
index 60ee45ca2..78bc968c0 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
@@ -27,56 +27,7 @@
#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
-/*
-
- isely@pobox.com 16-Oct-2005 - There are two method by which we can
- theoretically retrieve information from the device's eeprom:
-
- 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. 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. This is the "direct" method.
-
- Unfortunately it isn't perfectly clear which method is the best.
- They each have pros and cons:
-
- #1 is simpler & more portable and has an API which is more stable.
-
- #1 doesn't provide as much information as #2 does. For example, we
- can't retrieve the device's serial number with method #1.
-
- #1 requires that tveeprom.ko autonomously detect the eeprom chip on
- its own; we can't help it out here. Worse still, it seems that
- the eeprom in some PVR USB2 devices (like mine) can't be detected
- correctly (I don't see an ack on a zero length write which is
- what the I2C core attempts).
-
- #2 uses an unstable API. Current the ivtv implementation of #2 uses
- a completely different tveeprom struct than the v4l
- implementation of #2. This causes a usability nightmare.
-
- Since I can't decide, both methods are implemented below. Method #2
- (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
- different. In addition, if tveeprom.ko fails to detect the eeprom
- you may have to force it using standard i2c module options (try
- force=-1,80). FINALLY (and this may foreclose this option for you
- completely), the PVR USB2 eeprom seems to have valid data only in
- the upper 128 bytes - the lower 128 bytes causes tveeprom.ko to
- abort. In method #2 we only read the upper 128 bytes...
-
- */
-
-
-
-
-/* Stuff common to direct approach of operation tveeprom */
/*
@@ -121,7 +72,7 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
/* FX2 documentation states that a 16bit-addressed eeprom is
expected if the I2C address is an odd number (yeah, this is
- strange bit it's what they do) */
+ strange but it's what they do) */
mode16 = (addr & 1);
eepromSize = (mode16 ? 4096 : 256);
trace_eeprom("Examining %d byte eeprom at location 0x%x"
@@ -165,15 +116,7 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
}
-/*VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*/
-/* BEGIN DIRECT METHOD, V4L ONLY */
-
-
-/* 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. */
-
+/* Directly call eeprom analysis function within tveeprom. */
int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
{
u8 *eeprom;
@@ -204,66 +147,13 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
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;
+ pvr2_hdw_internal_set_std_avail(hdw,tvdata.tuner_formats);
kfree(eeprom);
return 0;
}
-
-
-/* END DIRECT METHOD, V4L ONLY */
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
-
-
-
-
-
-
-static v4l2_std_id std_choices[] = {
- [PVR2_CVAL_VIDEOSTANDARD_NTSC_M] = V4L2_STD_NTSC_M,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_BG] = V4L2_STD_PAL_BG,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_I] = V4L2_STD_PAL_I,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_DK] = V4L2_STD_PAL_DK,
- [PVR2_CVAL_VIDEOSTANDARD_SECAM_L] = V4L2_STD_SECAM_L,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_M] = V4L2_STD_PAL_M,
-};
-
-void pvr2_eeprom_set_default_standard(struct pvr2_hdw *hdw)
-{
- int vstd_value = 0;
- int vstd_found = 0;
- unsigned int idx;
- v4l2_std_id vs = (v4l2_std_id)hdw->video_standards;
-
- for (idx = 0; idx < sizeof(std_choices)/sizeof(std_choices[0]);
- idx++) {
- if (!(vs & std_choices[idx])) continue;
- trace_eeprom("Detected video standard %s (from eeprom)",
- pvr2_hdw_get_ctl_value_name(
- hdw,PVR2_CID_VIDEOSTANDARD,idx));
- if (vstd_found) continue;
- vstd_value = idx;
- vstd_found = !0;
- }
-
- if (!vstd_found) {
- trace_eeprom("eeprom unable to recognize"
- " a known video standard");
- return;
- }
-
- trace_eeprom("Setting initial video standard to %s"
- " (detected from eeprom)",
- pvr2_hdw_get_ctl_value_name(hdw,
- PVR2_CID_VIDEOSTANDARD,
- vstd_value));
- pvr2_hdw_set_ctl_value_internal(hdw,PVR2_CID_VIDEOSTANDARD,vstd_value);
-}
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
*** Local Variables: ***
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
index 061cecd91..84242975d 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
@@ -26,7 +26,6 @@
struct pvr2_hdw;
int pvr2_eeprom_analyze(struct pvr2_hdw *);
-void pvr2_eeprom_set_default_standard(struct pvr2_hdw *);
#endif /* __PVRUSB2_EEPROM_H */
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index b85ef5059..2a93bcc96 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -268,26 +268,22 @@ static int pvr2_write_encoder_vcmd (struct pvr2_hdw *hdw, u8 cmd,
int pvr2_encoder_configure(struct pvr2_hdw *hdw)
{
int ret = 0, audio, i;
- int vd_std = hdw->controls[PVR2_CID_VIDEOSTANDARD].value;
+ int vd_std = hdw->controls[PVR2_CID_STDCUR].value;
int height = hdw->controls[PVR2_CID_VRES].value;
int width = hdw->controls[PVR2_CID_HRES].value;
int height_full = !hdw->controls[PVR2_CID_INTERLACE].value;
int is_30fps, is_ntsc;
- switch (vd_std) {
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
+ if (vd_std & V4L2_STD_NTSC) {
is_ntsc=1;
is_30fps=1;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
+ } else if (vd_std & V4L2_STD_PAL_M) {
is_ntsc=0;
is_30fps=1;
- break;
- default:
+ } else {
is_ntsc=0;
is_30fps=0;
- break;
}
pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure");
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 05e44385b..9c5f0f74c 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -45,6 +45,83 @@
#include "pvrusb2-hdw.h"
#include "pvrusb2-io.h"
+
+/* Definition of state variables that we can inspect & change. Numbers are
+ assigned from zero counting up with no gaps. */
+#define PVR2_CID_BRIGHTNESS 0
+#define PVR2_CID_CONTRAST 1
+#define PVR2_CID_SATURATION 2
+#define PVR2_CID_HUE 3
+#define PVR2_CID_VOLUME 4
+#define PVR2_CID_BALANCE 5
+#define PVR2_CID_BASS 6
+#define PVR2_CID_TREBLE 7
+#define PVR2_CID_MUTE 8
+#define PVR2_CID_SRATE 9
+#define PVR2_CID_AUDIOBITRATE 10
+#define PVR2_CID_AUDIOCRC 11
+#define PVR2_CID_AUDIOEMPHASIS 12
+#define PVR2_CID_VBR 13
+#define PVR2_CID_AVERAGEVIDEOBITRATE 14
+#define PVR2_CID_PEAKVIDEOBITRATE 15
+#define PVR2_CID_STDAVAIL 16 // V4L2 video standard bit mask
+#define PVR2_CID_INPUT 17
+#define PVR2_CID_AUDIOMODE 18 // V4L2 standard audio mode enum
+#define PVR2_CID_FREQUENCY 19 // Units of Hz
+#define PVR2_CID_HRES 20
+#define PVR2_CID_VRES 21
+#define PVR2_CID_INTERLACE 22
+#define PVR2_CID_AUDIOLAYER 23
+#define PVR2_CID_CHANNEL 24
+#define PVR2_CID_CHANPROG_ID 25
+#define PVR2_CID_CHANPROG_FREQ 26
+#define PVR2_CID_SIGNAL_PRESENT 27
+#define PVR2_CID_STREAMING_ENABLED 28
+#define PVR2_CID_HSM 29
+#define PVR2_CID_SUBSYS_MASK 30
+#define PVR2_CID_SUBSYS_STREAM_MASK 31
+#define PVR2_CID_STDCUR 32 // V4L2 video standard bit mask
+#define PVR2_CID_STDNAME 33 // Enumeration of available standards
+
+/* Legal values for the SRATE state variable */
+#define PVR2_CVAL_SRATE_48 0
+#define PVR2_CVAL_SRATE_44_1 1
+#define PVR2_CVAL_SRATE_MIN PVR2_CVAL_SRATE_48
+#define PVR2_CVAL_SRATE_MAX PVR2_CVAL_SRATE_44_1
+
+/* Legal values for the AUDIOBITRATE state variable */
+#define PVR2_CVAL_AUDIOBITRATE_384 0
+#define PVR2_CVAL_AUDIOBITRATE_320 1
+#define PVR2_CVAL_AUDIOBITRATE_256 2
+#define PVR2_CVAL_AUDIOBITRATE_224 3
+#define PVR2_CVAL_AUDIOBITRATE_192 4
+#define PVR2_CVAL_AUDIOBITRATE_160 5
+#define PVR2_CVAL_AUDIOBITRATE_128 6
+#define PVR2_CVAL_AUDIOBITRATE_112 7
+#define PVR2_CVAL_AUDIOBITRATE_96 8
+#define PVR2_CVAL_AUDIOBITRATE_80 9
+#define PVR2_CVAL_AUDIOBITRATE_64 10
+#define PVR2_CVAL_AUDIOBITRATE_56 11
+#define PVR2_CVAL_AUDIOBITRATE_48 12
+#define PVR2_CVAL_AUDIOBITRATE_32 13
+#define PVR2_CVAL_AUDIOBITRATE_VBR 14
+#define PVR2_CVAL_AUDIOBITRATE_MIN PVR2_CVAL_AUDIOBITRATE_384
+#define PVR2_CVAL_AUDIOBITRATE_MAX PVR2_CVAL_AUDIOBITRATE_VBR
+
+/* Legal values for the AUDIOEMPHASIS state variable */
+#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
+#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
+#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
+#define PVR2_CVAL_AUDIOEMPHASIS_MIN PVR2_CVAL_AUDIOEMPHASIS_NONE
+#define PVR2_CVAL_AUDIOEMPHASIS_MAX PVR2_CVAL_AUDIOEMPHASIS_CCITT
+
+/* Legal values for PVR2_CID_HSM */
+#define PVR2_CVAL_HSM_FAIL 0
+#define PVR2_CVAL_HSM_FULL 1
+#define PVR2_CVAL_HSM_HIGH 2
+#define PVR2_CVAL_HSM_MIN PVR2_CVAL_HSM_FAIL
+#define PVR2_CVAL_HSM_MAX PVR2_CVAL_HSM_HIGH
+
#define PVR2_VID_ENDPOINT 0x84
#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */
#define PVR2_VBI_ENDPOINT 0x88
@@ -58,7 +135,33 @@
struct pvr2_decoder;
-struct pvr2_ctl_state {
+struct pvr2_ctl_def;
+struct pvr2_ctrl;
+
+typedef int (*pvr2_ctl_set_func)(struct pvr2_ctrl *,int val);
+typedef int (*pvr2_ctl_get_func)(struct pvr2_ctrl *);
+
+struct pvr2_ctl_def {
+ int id;
+ const char *name;
+ const char *desc;
+ pvr2_ctl_set_func set_func;
+ pvr2_ctl_get_func get_func;
+ int mask_value;
+ int max_value;
+ int min_value;
+ int skip_init;
+ int default_value;
+ int is_valid;
+ const char **value_defs_ptr;
+ unsigned int value_defs_count;
+};
+
+
+struct pvr2_ctrl {
+ struct pvr2_hdw *hdw;
+ const struct pvr2_ctl_def *ctl_def;
+ int is_valid;
int value;
int dirty;
};
@@ -96,7 +199,9 @@ struct pvr2_decoder_ctrl {
/* Known major hardware variants, keyed from device ID */
#define PVR2_HDW_TYPE_29XXX 0
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
#define PVR2_HDW_TYPE_24XXX 1
+#endif
/* This structure contains all state data directly needed to
manipulate the hardware (as opposed to complying with a kernel
@@ -191,7 +296,13 @@ struct pvr2_hdw {
/* Tuner / frequency control stuff */
unsigned int tuner_type;
int tuner_updated;
- unsigned long video_standards;
+ v4l2_std_id video_std_avail;
+ v4l2_std_id video_std_cur;
+ struct pvr2_ctl_def video_std_enum;
+ struct v4l2_standard *std_defs;
+ const char **video_std_names;
+ unsigned int std_cnt;
+ int std_id;
int unit_number; /* ID for driver instance */
unsigned long serial_number; /* ID for hardware itself */
@@ -211,13 +322,17 @@ struct pvr2_hdw {
struct pvr2_audio_stat *audio_stat;
/* Every last bit of controllable state */
- struct pvr2_ctl_state controls[PVR2_CID_COUNT];
+ struct pvr2_ctrl *controls;
};
-int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw,
- unsigned int ctl_id,int value);
int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
+int pvr2_ctrl_internal_set_value(struct pvr2_ctrl *cptr,int val);
+int pvr2_ctrl_internal_get_value(struct pvr2_ctrl *cptr);
+
+int pvr2_hdw_internal_set_stdenum_cur(struct pvr2_hdw *hdw,int val);
+void pvr2_hdw_internal_set_std_cur(struct pvr2_hdw *hdw,int msk);
+void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw,int msk);
#endif /* __PVRUSB2_HDW_INTERNAL_H */
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index ec2b5eeae..f0de1e154 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -24,6 +24,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/firmware.h>
+#include <linux/videodev2.h>
#include <asm/semaphore.h>
#include "pvrusb2.h"
#include "pvrusb2-util.h"
@@ -37,7 +38,9 @@
struct usb_device_id pvr2_device_table[] = {
[PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
+#endif
{ }
};
@@ -45,7 +48,9 @@ MODULE_DEVICE_TABLE(usb, pvr2_device_table);
static const char *pvr2_device_names[] = {
[PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
+#endif
};
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0};
@@ -86,22 +91,6 @@ MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
/* size of a firmware chunk */
#define FIRMWARE_CHUNK_SIZE 0x2000
-typedef int (*pvr2_ctl_set_func)(struct pvr2_hdw *,int ctl_id,int val);
-typedef int (*pvr2_ctl_get_func)(struct pvr2_hdw *,int ctl_id);
-
-struct pvr2_ctl_def {
- const char *name;
- pvr2_ctl_set_func set_func;
- pvr2_ctl_get_func get_func;
- int max_value;
- int min_value;
- int skip_init;
- int default_value;
- const char **value_defs_ptr;
- unsigned int value_defs_count;
-};
-
-
static const char *control_values_srate[] = {
[PVR2_CVAL_SRATE_48] = "48KHz",
[PVR2_CVAL_SRATE_44_1] = "44.1KHz",
@@ -135,12 +124,35 @@ static const char *control_values_audioemphasis[] = {
static const char *control_values_videostandard[] = {
- [PVR2_CVAL_VIDEOSTANDARD_NTSC_M] = "NTSC-M",
- [PVR2_CVAL_VIDEOSTANDARD_SECAM_L] = "SECAM-L",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_BG] = "PAL-BG",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_I] = "PAL-I",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_DK] = "PAL-DK",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_M] = "PAL-M",
+ "PAL-B",
+ "PAL-B1",
+ "PAL-G",
+ "PAL-H",
+
+ "PAL-I",
+ "PAL-D",
+ "PAL-D1",
+ "PAL-K",
+
+ "PAL-M",
+ "PAL-N",
+ "PAL-Nc",
+ "PAL-60",
+
+ "NTSC-M",
+ "NTSC-M-JP",
+ "NTSC-443",
+ 0,
+
+ "SECAM-B",
+ "SECAM-D",
+ "SECAM-G",
+ "SECAM-H",
+
+ "SECAM-K",
+ "SECAM-K1",
+ "SECAM-L",
+ "SECAM-LC",
};
@@ -153,12 +165,11 @@ static const char *control_values_input[] = {
static const char *control_values_audiomode[] = {
- [PVR2_CVAL_AUDIOMODE_MONO] = "Mono",
- [PVR2_CVAL_AUDIOMODE_STEREO] = "Stereo",
- [PVR2_CVAL_AUDIOMODE_SAP] = "SAP",
- [PVR2_CVAL_AUDIOMODE_LANG1] = "Lang1",
- [PVR2_CVAL_AUDIOMODE_LANG2] = "Lang2",
- [PVR2_CVAL_AUDIOMODE_LANG1_LANG2] = "Lang1+Lang2",
+ [V4L2_TUNER_MODE_MONO] = "Mono",
+ [V4L2_TUNER_MODE_STEREO] = "Stereo",
+ [V4L2_TUNER_MODE_LANG1] = "Lang1",
+ [V4L2_TUNER_MODE_LANG2] = "Lang2",
+ [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
};
@@ -173,183 +184,265 @@ static const char *control_values_hsm[] = {
.value_defs_ptr = x, \
.value_defs_count = (sizeof(x)/sizeof(x[0]))
-static int pvr2_ctl_set_chanprog_id(struct pvr2_hdw *hdw,int ctl_id,int value);
-static int pvr2_ctl_get_chanprog_id(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_signal(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_streaming(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_hsm(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_subsys_mask(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_set_subsys_mask(struct pvr2_hdw *hdw,int ctl_id,int val);
-static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id,
- int val);
-
-static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] =
+static int pvr2_ctl_set_chanprog_id(struct pvr2_ctrl *cptr,int value);
+static int pvr2_ctl_get_chanprog_id(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_streaming(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_set_stdcur(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_get_stdcur(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_stdavail(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_set_stdenumcur(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_get_stdenumcur(struct pvr2_ctrl *cptr);
+
+static struct pvr2_ctl_def control_defs[] =
{
[PVR2_CID_BRIGHTNESS] = {
- .name = "Brightness",
+ .id = V4L2_CID_BRIGHTNESS,
+ .is_valid = !0,
+ .desc = "Brightness",
+ .name = "brightness",
.min_value = 0,
.max_value = 255,
.default_value = 128,
},
[PVR2_CID_CONTRAST] = {
- .name = "Contrast",
+ .id = V4L2_CID_CONTRAST,
+ .is_valid = !0,
+ .desc = "Contrast",
+ .name = "contrast",
.min_value = 0,
.max_value = 127,
.default_value = 68,
},
[PVR2_CID_SATURATION] = {
- .name = "Saturation",
+ .id = V4L2_CID_SATURATION,
+ .is_valid = !0,
+ .desc = "Saturation",
+ .name = "saturation",
.min_value = 0,
.max_value = 127,
.default_value = 64,
},
[PVR2_CID_HUE] = {
- .name = "Hue",
+ .id = V4L2_CID_HUE,
+ .is_valid = !0,
+ .desc = "Hue",
+ .name = "hue",
.min_value = -128,
.max_value = 127,
.default_value = 0,
},
[PVR2_CID_VOLUME] = {
- .name = "Volume",
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .is_valid = !0,
+ .desc = "Volume",
+ .name = "volume",
.min_value = 0,
.max_value = 65535,
.default_value = 65535,
},
[PVR2_CID_BALANCE] = {
- .name = "Balance",
+ .id = V4L2_CID_AUDIO_BALANCE,
+ .is_valid = !0,
+ .desc = "Balance",
+ .name = "balance",
.min_value = -32768,
.max_value = 32767,
.default_value = 0,
},
[PVR2_CID_BASS] = {
- .name = "Bass",
+ .id = V4L2_CID_AUDIO_BASS,
+ .is_valid = !0,
+ .desc = "Bass",
+ .name = "bass",
.min_value = -32768,
.max_value = 32767,
.default_value = 0,
},
[PVR2_CID_TREBLE] = {
- .name = "Treble",
+ .id = V4L2_CID_AUDIO_TREBLE,
+ .is_valid = !0,
+ .desc = "Treble",
+ .name = "treble",
.min_value = -32768,
.max_value = 32767,
.default_value = 0,
},
[PVR2_CID_MUTE] = {
- .name = "Mute",
+ .id = V4L2_CID_AUDIO_MUTE,
+ .is_valid = !0,
+ .desc = "Mute",
+ .name = "mute",
.min_value = 0,
.max_value = 1,
.default_value = 0,
},
[PVR2_CID_SRATE] = {
- .name = "Sample rate",
+ .id = V4L2_CID_PVR_SRATE,
+ .is_valid = !0,
+ .desc = "Sample rate",
+ .name = "srate",
.min_value = PVR2_CVAL_SRATE_MIN,
.max_value = PVR2_CVAL_SRATE_MAX,
.default_value = PVR2_CVAL_SRATE_48,
VDEF(control_values_srate),
},
[PVR2_CID_AUDIOBITRATE] = {
- .name = "Audio Bitrate",
+ .id = V4L2_CID_PVR_AUDIOBITRATE,
+ .is_valid = !0,
+ .desc = "Audio Bitrate",
+ .name = "audio_bitrate",
.min_value = PVR2_CVAL_AUDIOBITRATE_MIN,
.max_value = PVR2_CVAL_AUDIOBITRATE_MAX,
.default_value = PVR2_CVAL_AUDIOBITRATE_224,
VDEF(control_values_audiobitrate),
},
[PVR2_CID_AUDIOCRC] = {
- .name = "Audio CRC",
+ .id = V4L2_CID_PVR_AUDIOCRC,
+ .is_valid = !0,
+ .desc = "Audio CRC",
+ .name = "audio_crc",
.min_value = 0,
.max_value = 1,
.default_value = 1,
},
[PVR2_CID_AUDIOEMPHASIS] = {
- .name = "Audio Emphasis",
+ .id = V4L2_CID_PVR_AUDIOEMPHASIS,
+ .is_valid = !0,
+ .desc = "Audio Emphasis",
+ .name = "audio_emphasis",
.min_value = PVR2_CVAL_AUDIOEMPHASIS_MIN,
.max_value = PVR2_CVAL_AUDIOEMPHASIS_MAX,
.default_value = PVR2_CVAL_AUDIOEMPHASIS_NONE,
VDEF(control_values_audioemphasis),
},
[PVR2_CID_VBR] = {
- .name = "Variable video bitrate",
+ .id = V4L2_CID_PVR_VBR,
+ .is_valid = !0,
+ .desc = "Variable video bitrate",
+ .name = "vbr",
.min_value = 0,
.max_value = 1,
.default_value = 0,
},
[PVR2_CID_AVERAGEVIDEOBITRATE] = {
- .name = "Average video bitrate",
+ .id = V4L2_CID_PVR_VIDEOBITRATE,
+ .is_valid = !0,
+ .desc = "Average video bitrate",
+ .name = "video_average_bitrate",
.min_value = 1,
.max_value = 20000000,
.default_value = 6000000,
},
[PVR2_CID_PEAKVIDEOBITRATE] = {
- .name = "Peak video bitrate",
+ .id = V4L2_CID_PVR_VIDEOPEAK,
+ .is_valid = !0,
+ .desc = "Peak video bitrate",
+ .name = "video_peak_bitrate",
.min_value = 1,
.max_value = 20000000,
.default_value = 6000000,
},
- [PVR2_CID_VIDEOSTANDARD] = {
- .name = "Video Standard",
- .min_value = PVR2_CVAL_VIDEOSTANDARD_MIN,
- .max_value = PVR2_CVAL_VIDEOSTANDARD_MAX,
- .default_value = PVR2_CVAL_VIDEOSTANDARD_NTSC_M,
+ [PVR2_CID_STDAVAIL] = {
+ .is_valid = !0,
+ .desc = "Video Standards Available Mask",
+ .name = "video_standard_mask_available",
+ .min_value = 0,
+ .max_value = 0,
+ .default_value = (int)V4L2_STD_UNKNOWN,
+ .mask_value = (int)V4L2_STD_ALL,
+ .get_func = pvr2_ctl_get_stdavail,
VDEF(control_values_videostandard),
},
[PVR2_CID_INPUT] = {
- .name = "Video Source",
+ .id = V4L2_CID_PVR_INPUT,
+ .is_valid = !0,
+ .desc = "Video Source",
+ .name = "input",
.min_value = PVR2_CVAL_INPUT_MIN,
.max_value = PVR2_CVAL_INPUT_MAX,
.default_value = PVR2_CVAL_INPUT_TV,
VDEF(control_values_input),
},
[PVR2_CID_AUDIOMODE] = {
- .name = "Audio Mode",
- .min_value = PVR2_CVAL_AUDIOMODE_MIN,
- .max_value = PVR2_CVAL_AUDIOMODE_MAX,
- .default_value = PVR2_CVAL_AUDIOMODE_STEREO,
+ .id = V4L2_CID_PVR_AUDIOMODE,
+ .is_valid = !0,
+ .desc = "Audio Mode",
+ .name = "audio_mode",
+ .min_value = V4L2_TUNER_MODE_MONO,
+ .max_value = V4L2_TUNER_MODE_LANG1_LANG2,
+ .default_value = V4L2_TUNER_MODE_STEREO,
VDEF(control_values_audiomode),
},
[PVR2_CID_FREQUENCY] = {
- .name = "Tuner Frequency (Hz)",
+ .id = V4L2_CID_PVR_FREQUENCY,
+ .is_valid = !0,
+ .desc = "Tuner Frequency (Hz)",
+ .name = "frequency",
.min_value = 55250000L,
.max_value = 850000000L,
.default_value = 175250000L,
},
[PVR2_CID_HRES] = {
- .name = "Horizontal capture resolution",
+ .id = V4L2_CID_PVR_HRES,
+ .is_valid = !0,
+ .desc = "Horizontal capture resolution",
+ .name = "resolution_hor",
.min_value = 320,
.max_value = 720,
.default_value = 720,
},
[PVR2_CID_VRES] = {
- .name = "Vertical capture resolution",
+ .id = V4L2_CID_PVR_VRES,
+ .is_valid = !0,
+ .desc = "Vertical capture resolution",
+ .name = "resolution_ver",
.min_value = 200,
.max_value = 625,
.default_value = 480,
},
[PVR2_CID_INTERLACE] = {
- .name = "Interlace mode",
+ .id = V4L2_CID_PVR_INTERLACE,
+ .is_valid = !0,
+ .desc = "Interlace mode",
+ .name = "interlace",
.min_value = 0,
.max_value = 1,
.default_value = 0,
},
[PVR2_CID_AUDIOLAYER] = {
- .name = "Audio Layer",
+ .is_valid = !0,
+ .desc = "Audio Layer",
+ .name = "audio_layer",
.min_value = 0, /* This is all a wild guess */
.max_value = 3,
.default_value = 2, /* Appears to be all that is supported */
},
[PVR2_CID_CHANNEL] = {
- .name = "Channel",
+ .is_valid = !0,
+ .desc = "Channel",
+ .name = "channel",
.min_value = 0,
.max_value = FREQTABLE_SIZE,
.default_value = 0,
},
[PVR2_CID_CHANPROG_ID] = {
- .name = "Channel Program ID",
+ .is_valid = !0,
+ .desc = "Channel Program ID",
+ .name = "freq_table_channel",
.min_value = 0,
.max_value = FREQTABLE_SIZE,
.default_value = 0,
},
[PVR2_CID_CHANPROG_FREQ] = {
- .name = "Channel Program Frequency",
+ .is_valid = !0,
+ .desc = "Channel Program Frequency",
+ .name = "freq_table_value",
.min_value = 55250000L,
.max_value = 850000000L,
.skip_init = !0,
@@ -357,26 +450,34 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] =
.get_func = pvr2_ctl_get_chanprog_id,
},
[PVR2_CID_SIGNAL_PRESENT] = {
- .name = "Signal Present",
+ .is_valid = !0,
+ .desc = "Signal Present",
+ .name = "signal_present",
.min_value = 0,
.max_value = 1,
.get_func = pvr2_ctl_get_signal,
},
[PVR2_CID_STREAMING_ENABLED] = {
- .name = "Streaming Enabled",
+ .is_valid = !0,
+ .desc = "Streaming Enabled",
+ .name = "streaming_enabled",
.min_value = 0,
.max_value = 1,
.get_func = pvr2_ctl_get_streaming,
},
[PVR2_CID_HSM] = {
- .name = "USB Speed",
+ .is_valid = !0,
+ .desc = "USB Speed",
+ .name = "usb_speed",
.min_value = PVR2_CVAL_HSM_MIN,
.max_value = PVR2_CVAL_HSM_MAX,
.get_func = pvr2_ctl_get_hsm,
VDEF(control_values_hsm),
},
[PVR2_CID_SUBSYS_MASK] = {
- .name = "Subsystem enabled mask",
+ .is_valid = !0,
+ .desc = "Subsystem enabled mask",
+ .name = "debug_subsys_mask",
.min_value = 0,
.max_value = 0x7fffffff,
.skip_init = !0,
@@ -384,17 +485,34 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] =
.set_func = pvr2_ctl_set_subsys_mask,
},
[PVR2_CID_SUBSYS_STREAM_MASK] = {
- .name = "Subsystem stream mask",
+ .is_valid = !0,
+ .desc = "Subsystem stream mask",
+ .name = "debug_subsys_stream_mask",
.min_value = 0,
.max_value = 0x7fffffff,
.skip_init = !0,
.get_func = pvr2_ctl_get_subsys_stream_mask,
.set_func = pvr2_ctl_set_subsys_stream_mask,
},
+ [PVR2_CID_STDCUR] = {
+ .id = V4L2_CID_PVR_STDCUR,
+ .is_valid = !0,
+ .desc = "Video Standard In Use Mask",
+ .name = "video_standard_mask_active",
+ .min_value = 0,
+ .max_value = 0,
+ .default_value = (int)V4L2_STD_UNKNOWN,
+ .mask_value = (int)V4L2_STD_ALL,
+ .set_func = pvr2_ctl_set_stdcur,
+ .get_func = pvr2_ctl_get_stdcur,
+ VDEF(control_values_videostandard),
+ },
};
#undef VDEF
+#define CTRL_DEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
+#define CTRL_COUNT CTRL_DEF_COUNT+1
const char *pvr2_config_get_name(enum pvr2_config cfg)
{
@@ -511,9 +629,11 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
static const char *fw_files_29xxx[] = {
"v4l-pvrusb2-29xxx-01.fw",
};
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
static const char *fw_files_24xxx[] = {
"v4l-pvrusb2-24xxx-01.fw",
};
+#endif
static const struct {
const char **lst;
unsigned int cnt;
@@ -522,10 +642,12 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
fw_files_29xxx,
sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
},
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = {
fw_files_24xxx,
sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
},
+#endif
};
hdw->fw1_state = FW1_STATE_FAILED; // default result
@@ -944,9 +1066,9 @@ void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
}
-static int pvr2_ctl_get_streaming(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_streaming(struct pvr2_ctrl *cptr)
{
- return hdw->flag_streaming_enabled != 0;
+ return cptr->hdw->flag_streaming_enabled != 0;
}
@@ -1061,6 +1183,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
{
int ret;
unsigned int idx;
+ struct pvr2_ctrl *cptr;
int reloadFl = 0;
if (!reloadFl) {
reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
@@ -1106,14 +1229,17 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
pvr2_i2c_core_init(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
- for (idx = 0; idx < PVR2_CID_COUNT; idx++) {
- if (control_defs[idx].skip_init) continue;
- pvr2_hdw_set_ctl_value_internal(
- hdw,idx,control_defs[idx].default_value);
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ if (!pvr2_ctrl_is_valid(cptr)) continue;
+ if (cptr->ctl_def->skip_init) continue;
+ pvr2_ctrl_internal_set_value(cptr,
+ cptr->ctl_def->default_value);
}
- pvr2_reset_ctl_endpoints(hdw);
- if (!pvr2_hdw_dev_ok(hdw)) return;
+ // Do not use pvr2_reset_ctl_endpoints() here. It is not
+ // thread-safe against the normal pvr2_send_request() mechanism.
+ // (We should make it thread safe).
ret = pvr2_hdw_get_eeprom_addr(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -1138,7 +1264,21 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
if (!pvr2_hdw_dev_ok(hdw)) return;
- pvr2_eeprom_set_default_standard(hdw);
+ for (idx = 0; idx < hdw->std_cnt; idx++) {
+ pvr2_trace(PVR2_TRACE_EEPROM,
+ "Detected video standard %s (from eeprom)",
+ hdw->std_defs[idx].name);
+ }
+ if (hdw->std_cnt) {
+ pvr2_trace(PVR2_TRACE_EEPROM,
+ "Initial video standard set to %s"
+ " (detected from eeprom)",
+ hdw->std_defs[hdw->std_id].name);
+ } else {
+ pvr2_trace(PVR2_TRACE_EEPROM,
+ "Unable to select a viable video standard");
+ }
+
if (!pvr2_hdw_dev_ok(hdw)) return;
pvr2_hdw_commit_ctl_internal(hdw);
@@ -1259,8 +1399,35 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw,pvr2_device_names[hdw_type]);
if (!hdw) goto fail;
memset(hdw,0,sizeof(*hdw));
+
+ // Initialize video standard enum dynamic control
+ hdw->video_std_enum.name = "video_standard";
+ hdw->video_std_enum.desc = "Video Standard Name";
+ hdw->video_std_enum.id = 0; // ?????
+ hdw->video_std_enum.set_func = pvr2_ctl_set_stdenumcur;
+ hdw->video_std_enum.get_func = pvr2_ctl_get_stdenumcur;
+ hdw->video_std_enum.mask_value = 0;
+ hdw->video_std_enum.max_value = 0;
+ hdw->video_std_enum.min_value = 0;
+ hdw->video_std_enum.default_value = 0;
+ hdw->video_std_enum.is_valid = !0;
+
+ hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * CTRL_COUNT,
+ GFP_KERNEL);
+ if (!hdw->controls) goto fail;
+ memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * CTRL_COUNT);
hdw->hdw_type = hdw_type;
+ for (idx = 0; idx < CTRL_DEF_COUNT; idx++) {
+ hdw->controls[idx].hdw = hdw;
+ hdw->controls[idx].ctl_def = control_defs + idx;
+ hdw->controls[idx].is_valid =
+ hdw->controls[idx].ctl_def->is_valid;
+ }
+ hdw->controls[PVR2_CID_STDNAME].hdw = hdw;
+ hdw->controls[PVR2_CID_STDNAME].ctl_def = &hdw->video_std_enum;
+ hdw->controls[PVR2_CID_STDNAME].is_valid = !0;
+
hdw->eeprom_addr = -1;
hdw->unit_number = -1;
hdw->v4l_minor_number = -1;
@@ -1322,6 +1489,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb);
if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer);
if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer);
+ if (hdw->controls) kfree(hdw->controls);
kfree(hdw);
}
return 0;
@@ -1386,6 +1554,9 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
unit_pointers[hdw->unit_number] = 0;
}
} while (0); up(&pvr2_unit_sem);
+ kfree(hdw->controls);
+ if (hdw->std_defs) kfree(hdw->std_defs);
+ if (hdw->video_std_names) kfree(hdw->video_std_names);
kfree(hdw);
}
@@ -1414,10 +1585,11 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_set_chanprog_id(struct pvr2_hdw *hdw,int ctl_id,int value)
+static int pvr2_ctl_set_chanprog_id(struct pvr2_ctrl *cptr,int value)
{
/* This is a special case; the value to store is to an array, and
the element to select is determined by PVR_CID_CHANPROG_ID. */
+ struct pvr2_hdw *hdw = cptr->hdw;
int id = hdw->controls[PVR2_CID_CHANPROG_ID].value;
if ((id < 1) || (id > FREQTABLE_SIZE)) return 0;
hdw->freqTable[id-1] = value;
@@ -1431,120 +1603,581 @@ static int pvr2_ctl_set_chanprog_id(struct pvr2_hdw *hdw,int ctl_id,int value)
}
-static int pvr2_ctl_get_chanprog_id(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_chanprog_id(struct pvr2_ctrl *cptr)
{
/* This is a special case; the value to return is from an array,
and the element to select is determined by
PVR_CID_CHANPROG_ID. */
+ struct pvr2_hdw *hdw = cptr->hdw;
int id = hdw->controls[PVR2_CID_CHANPROG_ID].value;
if ((id < 1) || (id > FREQTABLE_SIZE)) return 0;
return hdw->freqTable[id-1];
}
+// Template data for possible enumerated video standards
+static struct v4l2_standard pvr_standards[] = {
+ {
+ .id = V4L2_STD_PAL_BG,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_PAL_I,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_PAL_DK,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_SECAM,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_NTSC_M,
+ .frameperiod =
+ {
+ .numerator = 1001,
+ .denominator= 30000
+ },
+ .framelines = 525,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_PAL_M,
+ .frameperiod =
+ {
+ .numerator = 1001,
+ .denominator= 30000
+ },
+ .framelines = 525,
+ .reserved = {0,0,0,0}
+ }
+};
+
+#define pvr_standards_cnt (sizeof(pvr_standards)/sizeof(pvr_standards[0]))
-/* Retrieve current value for a given control */
-int pvr2_hdw_get_ctl_value(struct pvr2_hdw *hdw,unsigned int ctl_id)
+
+struct name_data {
+ struct v4l2_standard *std;
+ unsigned int bcnt;
+ unsigned int scnt;
+};
+
+static void name_build(struct name_data *dp,const char *str)
{
- int ret = 0;
+ if (!dp->bcnt) {
+ dp->bcnt = scnprintf(dp->std->name,
+ sizeof(dp->std->name)-1,"%s",str);
+ dp->scnt = 0;
+ return;
+ }
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- LOCK_TAKE(hdw->big_lock); do {
- if (control_defs[ctl_id].get_func) {
- ret = control_defs[ctl_id].get_func(hdw,ctl_id);
- break;
+ dp->bcnt += scnprintf(dp->std->name+dp->bcnt,
+ sizeof(dp->std->name)-(1+dp->bcnt),
+ "%s%s",
+ (dp->scnt ? "/" : "-"),str);
+ (dp->scnt)++;
+}
+
+// Generate a descriptive name for a given standard
+static void name_bucket(struct v4l2_standard *std)
+{
+ struct name_data nd;
+ nd.std = std;
+ nd.bcnt = 0;
+ if (std->id & (V4L2_STD_PAL_B|
+ V4L2_STD_PAL_B1|
+ V4L2_STD_PAL_G|
+ V4L2_STD_PAL_H|
+ V4L2_STD_PAL_I|
+ V4L2_STD_PAL_D|
+ V4L2_STD_PAL_D1|
+ V4L2_STD_PAL_K)) {
+ name_build(&nd,"PAL");
+ if (std->id & V4L2_STD_PAL_B) name_build(&nd,"B");
+ if (std->id & V4L2_STD_PAL_B1) name_build(&nd,"B1");
+ if (std->id & V4L2_STD_PAL_D) name_build(&nd,"D");
+ if (std->id & V4L2_STD_PAL_D1) name_build(&nd,"D1");
+ if (std->id & V4L2_STD_PAL_G) name_build(&nd,"G");
+ if (std->id & V4L2_STD_PAL_H) name_build(&nd,"H");
+ if (std->id & V4L2_STD_PAL_I) name_build(&nd,"I");
+ if (std->id & V4L2_STD_PAL_K) name_build(&nd,"K");
+ if (std->id & V4L2_STD_PAL_M) name_build(&nd,"M");
+ if (std->id & V4L2_STD_PAL_N) name_build(&nd,"N");
+ if (std->id & V4L2_STD_PAL_Nc) name_build(&nd,"Nc");
+ if (std->id & V4L2_STD_PAL_60) name_build(&nd,"60");
+ std->name[nd.bcnt] = 0;
+ return;
+ }
+ if (std->id & (V4L2_STD_NTSC_M|
+ V4L2_STD_NTSC_M_JP|
+ V4L2_STD_NTSC_443)) {
+ name_build(&nd,"NTSC");
+ if (std->id & V4L2_STD_NTSC_M) name_build(&nd,"M");
+ if (std->id & V4L2_STD_NTSC_M_JP) name_build(&nd,"Mjp");
+ if (std->id & V4L2_STD_NTSC_443) name_build(&nd,"443");
+ std->name[nd.bcnt] = 0;
+ return;
+ }
+ if (std->id & (V4L2_STD_SECAM_B|
+ V4L2_STD_SECAM_D|
+ V4L2_STD_SECAM_G|
+ V4L2_STD_SECAM_H|
+ V4L2_STD_SECAM_K|
+ V4L2_STD_SECAM_K1|
+ V4L2_STD_SECAM_L|
+ V4L2_STD_SECAM_LC)) {
+ name_build(&nd,"SECAM");
+ if (std->id & V4L2_STD_SECAM_B) name_build(&nd,"B");
+ if (std->id & V4L2_STD_SECAM_D) name_build(&nd,"D");
+ if (std->id & V4L2_STD_SECAM_G) name_build(&nd,"G");
+ if (std->id & V4L2_STD_SECAM_H) name_build(&nd,"H");
+ if (std->id & V4L2_STD_SECAM_K) name_build(&nd,"K");
+ if (std->id & V4L2_STD_SECAM_K1) name_build(&nd,"K1");
+ if (std->id & V4L2_STD_SECAM_L) name_build(&nd,"L");
+ if (std->id & V4L2_STD_SECAM_LC) name_build(&nd,"LC");
+ std->name[nd.bcnt] = 0;
+ return;
+ }
+ std->name[0] = 0;
+}
+
+
+// Given a mask of viable video standards to choose from, generate an
+// appropriate array of v4l2_standard data that corresponds to it and set
+// up related state in the driver to match.
+void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw,int arg)
+{
+ v4l2_std_id buckets[pvr_standards_cnt];
+ unsigned int idx1,idx2,std_cnt;
+ v4l2_std_id mmsk,amsk;
+
+ amsk = (v4l2_std_id)arg;
+
+ // Figure out which standard groups we can work with
+ std_cnt = 0;
+ mmsk = 0;
+ for (idx1 = 0; idx1 < pvr_standards_cnt; idx1++) {
+ buckets[idx1] = pvr_standards[idx1].id & amsk;
+ if (!buckets[idx1]) continue;
+ mmsk |= buckets[idx1];
+ amsk &= ~buckets[idx1];
+ std_cnt++;
+ }
+
+ if (amsk) {
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Failed to bucketize the following standards: 0x%llx",
+ amsk);
+ }
+
+ if (hdw->std_defs) {
+ kfree(hdw->std_defs);
+ hdw->std_defs = 0;
+ }
+ if (hdw->video_std_names) {
+ kfree(hdw->video_std_names);
+ hdw->video_std_names = 0;
+ }
+ hdw->std_cnt = 0;
+
+ if (!std_cnt) {
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Failed to identify any viable standard groups");
+ hdw->video_std_avail = 0;
+ pvr2_hdw_internal_set_std_cur(hdw,0);
+ return;
+ }
+
+ if (std_cnt) {
+ // Allocate new video standard array
+ hdw->std_defs = kmalloc(sizeof(struct v4l2_standard) * std_cnt,
+ GFP_KERNEL);
+ hdw->std_cnt = std_cnt;
+ memset(hdw->std_defs,0,sizeof(struct v4l2_standard) * std_cnt);
+ hdw->video_std_names = kmalloc(sizeof(char *) * std_cnt,
+ GFP_KERNEL);
+ memset(hdw->video_std_names,0,sizeof(char *) * std_cnt);
+ idx2 = 0;
+
+ // Initialize video standard array
+ for (idx1 = 0; idx1 < pvr_standards_cnt; idx1++) {
+ if (!buckets[idx1]) continue;
+ memcpy(hdw->std_defs + idx2,
+ pvr_standards + idx1,
+ sizeof(struct v4l2_standard));
+ hdw->std_defs[idx2].id = buckets[idx1];
+ idx2++;
}
- ret = hdw->controls[ctl_id].value;
- } while(0); LOCK_GIVE(hdw->big_lock);
- return ret;
+
+ // Generate a name for each known video standard
+ for (idx1 = 0; idx1 < std_cnt; idx1++) {
+ name_bucket(hdw->std_defs + idx1);
+ hdw->video_std_names[idx1] =
+ hdw->std_defs[idx1].name;
+ }
+
+ // Set up the dynamic control for this standard
+ hdw->video_std_enum.value_defs_ptr = hdw->video_std_names;
+ hdw->video_std_enum.value_defs_count = std_cnt;
+ }
+
+ hdw->video_std_avail = mmsk;
+ if (!(hdw->video_std_avail & hdw->video_std_cur)) {
+ // Reselect standard if there isn't one that matches...
+ pvr2_hdw_internal_set_stdenum_cur(hdw,0);
+ }
}
-/* Return true if control is writable */
-int pvr2_hdw_get_ctl_rw(struct pvr2_hdw *hdw,unsigned int ctl_id)
+unsigned int pvr2_hdw_get_stdenum_count(struct pvr2_hdw *hdw)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- if (control_defs[ctl_id].get_func && !control_defs[ctl_id].set_func) {
- return 0;
+ return hdw->std_cnt;
+}
+
+
+const struct v4l2_standard *pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
+ unsigned int idx)
+{
+ if (idx >= hdw->std_cnt) return 0;
+ return hdw->std_defs + idx;
+}
+
+
+int pvr2_hdw_internal_set_stdenum_cur(struct pvr2_hdw *hdw,int val)
+{
+ if (val < 0) return -EINVAL;
+ if (val >= hdw->std_cnt) return -EINVAL;
+ pvr2_hdw_internal_set_std_cur(hdw,hdw->std_defs[val].id);
+ return 0;
+}
+
+
+void pvr2_hdw_internal_set_std_cur(struct pvr2_hdw *hdw,int val)
+{
+ unsigned int idx;
+ v4l2_std_id msk,id;
+
+ id = (v4l2_std_id)val;
+ // Only select from available standards
+ id &= hdw->video_std_avail;
+
+ // Only select a single bit
+ for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
+ if (!(id & msk)) continue;
+ id = msk;
+ break;
}
- return !0;
+
+ // Get out if nothing found
+ if (!msk) return;
+
+ // Fix up standard group now
+ hdw->video_std_cur = id;
+ hdw->controls[PVR2_CID_STDCUR].value = id;
+ hdw->controls[PVR2_CID_STDCUR].dirty = !0;
+ for (idx = 0; idx < hdw->std_cnt; idx++) {
+ if (hdw->std_defs[idx].id & id) {
+ hdw->std_id = idx;
+ return;
+ }
+ }
+
+ // Should never really get here, but just in case...
+ hdw->std_id = 0;
}
-/* Retrieve legal minimum value for a given control */
-int pvr2_hdw_get_ctl_min_value(struct pvr2_hdw *hdw,unsigned int ctl_id)
+static int pvr2_ctl_set_stdcur(struct pvr2_ctrl *cptr,int val)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- return control_defs[ctl_id].min_value;
+ pvr2_hdw_internal_set_std_cur(cptr->hdw,val);
+ return 0;
+}
+
+
+static int pvr2_ctl_get_stdcur(struct pvr2_ctrl *cptr)
+{
+ return (int)(cptr->hdw->video_std_cur);
+}
+
+
+static int pvr2_ctl_set_stdenumcur(struct pvr2_ctrl *cptr,int val)
+{
+ if (val < 0) return -EINVAL;
+ if (val >= cptr->hdw->std_cnt) return -EINVAL;
+ cptr->hdw->std_id = val;
+ pvr2_hdw_internal_set_std_cur(cptr->hdw,
+ cptr->hdw->std_id);
+ return 0;
+}
+
+
+static int pvr2_ctl_get_stdenumcur(struct pvr2_ctrl *cptr)
+{
+ return cptr->hdw->std_id;
+}
+
+
+static int pvr2_ctl_get_stdavail(struct pvr2_ctrl *cptr)
+{
+ return (int)(cptr->hdw->video_std_avail);
+}
+
+
+/* Get the number of defined controls */
+unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
+{
+ return CTRL_COUNT;
+}
+
+
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
+ unsigned int idx)
+{
+ if (idx < 0) return 0;
+ if (idx >= CTRL_COUNT) return 0;
+ return hdw->controls + idx;
}
-/* Retrieve legal maximum value for a given control */
-int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *hdw,unsigned int ctl_id)
+/* Given an ID, retrieve the control structure associated with it. */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl(struct pvr2_hdw *hdw,unsigned int ctl_id)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- return control_defs[ctl_id].max_value;
+ struct pvr2_ctrl *cptr;
+ unsigned int idx;
+ int i;
+
+ /* This could be made a lot more efficient, but for now... */
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ i = cptr->ctl_def->id;
+ if (i && (i == ctl_id)) return cptr;
+ }
+
+ return 0;
}
-/* Set current value for given control - normally this is just stored and
- the hardware isn't updated until the commit function is called. */
-int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw,
- unsigned int ctl_id,int value)
+/* Set the current value of a given control. This assumes we are already
+ inside our critical region. */
+int pvr2_ctrl_internal_set_value(struct pvr2_ctrl *cptr,int value)
{
+ const struct pvr2_ctl_def *dptr;
int ret;
- if (ctl_id >= PVR2_CID_COUNT) return -EINVAL;
- if (value < control_defs[ctl_id].min_value) return -EINVAL;
- if (value > control_defs[ctl_id].max_value) return -EINVAL;
- if (control_defs[ctl_id].set_func) {
- ret = control_defs[ctl_id].set_func(hdw,ctl_id,value);
- pvr2_i2c_core_check_stale(hdw);
- pvr2_i2c_core_sync(hdw);
+ if (!cptr) return -EINVAL;
+ if (!cptr->is_valid) return -EINVAL;
+ dptr = cptr->ctl_def;
+ if (!dptr->is_valid) return -EINVAL;
+ if (value < dptr->min_value) return -EINVAL;
+ if (value > dptr->max_value) return -EINVAL;
+ if (dptr->set_func) {
+ ret = dptr->set_func(cptr,value);
+ pvr2_i2c_core_check_stale(cptr->hdw);
+ pvr2_i2c_core_sync(cptr->hdw);
return ret;
- } else if (control_defs[ctl_id].get_func) {
+ } else if (dptr->get_func) {
/* If there's no "set" function yet there is still a "get"
function, then treat this as a read-only value. */
return -EINVAL;
}
- if ((hdw->controls[ctl_id].value != value) || (ctlchg != 0)) {
- hdw->controls[ctl_id].value = value;
- hdw->controls[ctl_id].dirty = !0;
+ if ((cptr->value != value) || (ctlchg != 0)) {
+ cptr->value = value;
+ cptr->dirty = !0;
}
return 0;
}
-/* Set current value for given control - this is just stored; the hardware
- isn't updated until the commit function is called. */
-int pvr2_hdw_set_ctl_value(struct pvr2_hdw *hdw,unsigned int ctl_id,int value)
+/* Get the current value of a given control. This assumes that we are
+ already inside our critical region. */
+int pvr2_ctrl_internal_get_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ if (!cptr->is_valid) return 0;
+ dptr = cptr->ctl_def;
+ if (!dptr->is_valid) return 0;
+ if (dptr->get_func) {
+ return dptr->get_func(cptr);
+ }
+
+ return cptr->value;
+}
+
+
+/* Set the current value of the given control. */
+int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
{
int ret;
- LOCK_TAKE(hdw->big_lock); do {
- ret = pvr2_hdw_set_ctl_value_internal(hdw,ctl_id,value);
- } while (0); LOCK_GIVE(hdw->big_lock);
+ if (!cptr) return -EINVAL;
+ LOCK_TAKE(cptr->hdw->big_lock); do {
+ ret = pvr2_ctrl_internal_set_value(cptr,val);
+ } while(0); LOCK_GIVE(cptr->hdw->big_lock);
return ret;
}
-/* Retrieve string name for a given control value (returns a null pointer
- for any invalid combinations). */
-const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *hdw,
- unsigned int ctl_id,
- int value)
+/* Get the current value of the given control. */
+int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr)
{
- struct pvr2_ctl_def *cdef;
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- cdef = control_defs + ctl_id;
- if (! cdef->value_defs_ptr) return 0;
- if (value >= cdef->value_defs_count) return 0;
- return cdef->value_defs_ptr[value];
+ int ret;
+ if (!cptr) return -EINVAL;
+ LOCK_TAKE(cptr->hdw->big_lock); do {
+ ret = pvr2_ctrl_internal_get_value(cptr);
+ } while(0); LOCK_GIVE(cptr->hdw->big_lock);
+ return ret;
}
-/* Retrieve string name for given control */
-const char *pvr2_hdw_get_ctl_name(struct pvr2_hdw *hdw,unsigned int ctl_id)
+/* Return the type of the given control (int, enum, or bit mask). */
+int pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- return control_defs[ctl_id].name;
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return PVR2_CTRL_TYPE_INVALID;
+ dptr = cptr->ctl_def;
+ if (dptr->mask_value) {
+ return PVR2_CTRL_TYPE_BITMASK;
+ }
+ if (dptr->value_defs_ptr) {
+ return PVR2_CTRL_TYPE_ENUM;
+ }
+ return PVR2_CTRL_TYPE_INT;
+}
+
+
+/* Return the minimum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_min_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->min_value;
+}
+
+
+/* Return the maximum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_max_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->max_value;
+}
+
+
+/* Return the default value for a given control. */
+int pvr2_ctrl_get_default_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->default_value;
+}
+
+
+/* Return a mask of which bits are used within the bit mask of a given
+ control. This command is only relevant for bit mask types. */
+int pvr2_ctrl_get_mask_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->mask_value;
+}
+
+
+/* Return true if this is a valid control. */
+int pvr2_ctrl_is_valid(struct pvr2_ctrl *cptr)
+{
+ if (!cptr) return 0;
+ return cptr->is_valid;
+}
+
+
+/* Return true if the control can be set (otherwise it may only be read,
+ assuming that it is valid). */
+int pvr2_ctrl_is_writeable(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ if (!dptr->is_valid) return 0;
+ if (dptr->set_func) return !0;
+ if (dptr->get_func) return 0;
+ return !0;
+}
+
+
+/* Return the control's name, or null if there isn't a name or the control
+ isn't otherwise valid. */
+const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->name;
+}
+
+
+/* Return the control's description, or null if there isn't a name or the
+ control isn't otherwise valid. */
+const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->desc;
+}
+
+
+/* Return the name for an enumeration value or bit mask position for the
+ given control. If the control is not an enumeration or bit mask type,
+ then return null. */
+const char *pvr2_ctrl_get_value_name(struct pvr2_ctrl *cptr,int val)
+{
+ int msk,idx;
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ if (dptr->mask_value) {
+ for (idx = 0, msk = 1;
+ (idx < dptr->value_defs_count) && msk;
+ idx++, msk <<= 1) {
+ if (val & msk) {
+ return dptr->value_defs_ptr[idx];
+ }
+ }
+ } else {
+ val -= dptr->min_value;
+ if (val < 0) return 0;
+ if (val >= dptr->value_defs_count) return 0;
+ return dptr->value_defs_ptr[val];
+ }
+ return 0;
}
@@ -1560,6 +2193,8 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
unsigned long stale_subsys_mask = 0;
unsigned int idx;
+ const struct pvr2_ctl_def *dptr;
+ struct pvr2_ctrl *cptr;
int value;
const char *ctl_name;
const char *ctl_value;
@@ -1595,17 +2230,18 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
}
}
- for (idx = 0; idx < PVR2_CID_COUNT; idx++) {
- if (!hdw->controls[idx].dirty) continue;
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ if (!cptr->dirty) continue;
if (!commit_flag) {
commit_flag = !0;
}
- value = hdw->controls[idx].value;
- ctl_name = control_defs[idx].name;
- if (control_defs[idx].value_defs_ptr) {
- if (value < control_defs[idx].value_defs_count) {
- ctl_value =
- control_defs[idx].value_defs_ptr[value];
+ value = cptr->value;
+ dptr = cptr->ctl_def;
+ ctl_name = dptr->name;
+ if (dptr->value_defs_ptr) {
+ if (value < dptr->value_defs_count) {
+ ctl_value = dptr->value_defs_ptr[value];
} else {
ctl_value = "<out of range>";
}
@@ -1625,16 +2261,13 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
/* When video standard changes, reset the hres and vres values -
but if the user has pending changes there, then let the changes
take priority. */
- if (hdw->controls[PVR2_CID_VIDEOSTANDARD].dirty) {
+ if (hdw->controls[PVR2_CID_STDCUR].dirty) {
/* Rewrite the vertical resolution to be appropriate to the
video standard that has been selected. */
- int nvres = hdw->controls[PVR2_CID_VRES].value;
- switch (hdw->controls[PVR2_CID_VIDEOSTANDARD].value) {
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
+ int nvres;
+ if (hdw->video_std_cur & V4L2_STD_525_60) {
nvres = 480;
- break;
- default:
+ } else {
nvres = 576;
}
if (nvres != hdw->controls[PVR2_CID_VRES].value) {
@@ -1647,7 +2280,7 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
}
}
- if (hdw->controls[PVR2_CID_VIDEOSTANDARD].dirty ||
+ if (hdw->controls[PVR2_CID_STDCUR].dirty ||
hdw->controls[PVR2_CID_VRES].dirty ||
hdw->controls[PVR2_CID_HRES].dirty ||
hdw->controls[PVR2_CID_INTERLACE].dirty ||
@@ -1671,8 +2304,9 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
the client drivers in order to keep everything in sync */
pvr2_i2c_core_check_stale(hdw);
- for (idx = 0; idx < PVR2_CID_COUNT; idx++) {
- hdw->controls[idx].dirty = 0;
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ cptr->dirty = 0;
}
/* Now execute i2c core update */
@@ -1729,14 +2363,6 @@ void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw)
}
-/* Find out how many controls there are. Legal ids are numbered from 1
- through this value. */
-unsigned int pvr2_hdw_get_ctl_count(struct pvr2_hdw *hdw)
-{
- return PVR2_CID_COUNT;
-}
-
-
/* Return name for this driver instance */
const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
{
@@ -1772,36 +2398,36 @@ unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_get_subsys_mask(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr)
{
- return hdw->subsys_enabled_mask;
+ return cptr->hdw->subsys_enabled_mask;
}
-static int pvr2_ctl_set_subsys_mask(struct pvr2_hdw *hdw,int ctl_id,int val)
+static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val)
{
- pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,val);
+ pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,~0,val);
return 0;
}
-static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr)
{
- return hdw->subsys_stream_mask;
+ return cptr->hdw->subsys_stream_mask;
}
-static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id,
+static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr,
int val)
{
- pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,~0,val);
+ pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,~0,val);
return 0;
}
-static int pvr2_ctl_get_hsm(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr)
{
- int result = pvr2_hdw_is_hsm(hdw);
+ int result = pvr2_hdw_is_hsm(cptr->hdw);
if (result < 0) return PVR2_CVAL_HSM_FAIL;
if (result) return PVR2_CVAL_HSM_HIGH;
return PVR2_CVAL_HSM_FULL;
@@ -1823,10 +2449,10 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_get_signal(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr)
{
- return ((pvr2_hdw_get_signal_status_internal(hdw) & PVR2_SIGNAL_OK) ?
- 1 : 0);
+ return ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
+ PVR2_SIGNAL_OK) ? 1 : 0);
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index aa6d9029a..4101f4097 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -21,89 +21,37 @@
#ifndef __PVRUSB2_HDW_H
#define __PVRUSB2_HDW_H
+#include "compat.h"
#include <linux/usb.h>
+#include <linux/videodev2.h>
#include "pvrusb2-io.h"
-/* Definition of state variables that we can inspect & change. Numbers are
- assigned from zero counting up with no gaps. */
-#define PVR2_CID_BRIGHTNESS 0
-#define PVR2_CID_CONTRAST 1
-#define PVR2_CID_SATURATION 2
-#define PVR2_CID_HUE 3
-#define PVR2_CID_VOLUME 4
-#define PVR2_CID_BALANCE 5
-#define PVR2_CID_BASS 6
-#define PVR2_CID_TREBLE 7
-#define PVR2_CID_MUTE 8
-#define PVR2_CID_SRATE 9
-#define PVR2_CID_AUDIOBITRATE 10
-#define PVR2_CID_AUDIOCRC 11
-#define PVR2_CID_AUDIOEMPHASIS 12
-#define PVR2_CID_VBR 13
-#define PVR2_CID_AVERAGEVIDEOBITRATE 14
-#define PVR2_CID_PEAKVIDEOBITRATE 15
-#define PVR2_CID_VIDEOSTANDARD 16
-#define PVR2_CID_INPUT 17
-#define PVR2_CID_AUDIOMODE 18
-#define PVR2_CID_FREQUENCY 19 // Units of Hz
-#define PVR2_CID_HRES 20
-#define PVR2_CID_VRES 21
-#define PVR2_CID_INTERLACE 22
-#define PVR2_CID_AUDIOLAYER 23
-#define PVR2_CID_CHANNEL 24
-#define PVR2_CID_CHANPROG_ID 25
-#define PVR2_CID_CHANPROG_FREQ 26
-#define PVR2_CID_SIGNAL_PRESENT 27
-#define PVR2_CID_STREAMING_ENABLED 28
-#define PVR2_CID_HSM 29
-#define PVR2_CID_SUBSYS_MASK 30
-#define PVR2_CID_SUBSYS_STREAM_MASK 31
-
-/* Number of state variables */
-#define PVR2_CID_COUNT 32
-
-/* Legal values for the SRATE state variable */
-#define PVR2_CVAL_SRATE_48 0
-#define PVR2_CVAL_SRATE_44_1 1
-#define PVR2_CVAL_SRATE_MIN PVR2_CVAL_SRATE_48
-#define PVR2_CVAL_SRATE_MAX PVR2_CVAL_SRATE_44_1
-
-/* Legal values for the AUDIOBITRATE state variable */
-#define PVR2_CVAL_AUDIOBITRATE_384 0
-#define PVR2_CVAL_AUDIOBITRATE_320 1
-#define PVR2_CVAL_AUDIOBITRATE_256 2
-#define PVR2_CVAL_AUDIOBITRATE_224 3
-#define PVR2_CVAL_AUDIOBITRATE_192 4
-#define PVR2_CVAL_AUDIOBITRATE_160 5
-#define PVR2_CVAL_AUDIOBITRATE_128 6
-#define PVR2_CVAL_AUDIOBITRATE_112 7
-#define PVR2_CVAL_AUDIOBITRATE_96 8
-#define PVR2_CVAL_AUDIOBITRATE_80 9
-#define PVR2_CVAL_AUDIOBITRATE_64 10
-#define PVR2_CVAL_AUDIOBITRATE_56 11
-#define PVR2_CVAL_AUDIOBITRATE_48 12
-#define PVR2_CVAL_AUDIOBITRATE_32 13
-#define PVR2_CVAL_AUDIOBITRATE_VBR 14
-#define PVR2_CVAL_AUDIOBITRATE_MIN PVR2_CVAL_AUDIOBITRATE_384
-#define PVR2_CVAL_AUDIOBITRATE_MAX PVR2_CVAL_AUDIOBITRATE_VBR
-
-/* Legal values for the AUDIOEMPHASIS state variable */
-#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
-#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
-#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
-#define PVR2_CVAL_AUDIOEMPHASIS_MIN PVR2_CVAL_AUDIOEMPHASIS_NONE
-#define PVR2_CVAL_AUDIOEMPHASIS_MAX PVR2_CVAL_AUDIOEMPHASIS_CCITT
-
-/* Legal values for the VIDEOSTANDARD state variable */
-#define PVR2_CVAL_VIDEOSTANDARD_NTSC_M 0
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_BG 1
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_I 2
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_DK 3
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_M 4
-#define PVR2_CVAL_VIDEOSTANDARD_SECAM_L 5
-
-#define PVR2_CVAL_VIDEOSTANDARD_MIN PVR2_CVAL_VIDEOSTANDARD_NTSC_M
-#define PVR2_CVAL_VIDEOSTANDARD_MAX PVR2_CVAL_VIDEOSTANDARD_SECAM_L
+#define PVR2_CTRL_TYPE_INVALID 0
+#define PVR2_CTRL_TYPE_ENUM 1
+#define PVR2_CTRL_TYPE_INT 2
+#define PVR2_CTRL_TYPE_BITMASK 3
+
+/* Private V4L2-compatible controls available in this driver */
+#define V4L2_CID_PVR_SRATE (V4L2_CID_PRIVATE_BASE)
+#define V4L2_CID_PVR_AUDIOBITRATE (V4L2_CID_PRIVATE_BASE+1)
+#define V4L2_CID_PVR_AUDIOCRC (V4L2_CID_PRIVATE_BASE+2)
+#define V4L2_CID_PVR_AUDIOEMPHASIS (V4L2_CID_PRIVATE_BASE+3)
+#define V4L2_CID_PVR_VBR (V4L2_CID_PRIVATE_BASE+4)
+#define V4L2_CID_PVR_VIDEOBITRATE (V4L2_CID_PRIVATE_BASE+5)
+#define V4L2_CID_PVR_VIDEOPEAK (V4L2_CID_PRIVATE_BASE+6)
+#define V4L2_CID_PVR_VIDEOSTANDARD (V4L2_CID_PRIVATE_BASE+7)
+
+/* Deliberate gap for CIDs we don't want apps to discover */
+#define V4L2_CID_PVR_GAP (V4L2_CID_PRIVATE_BASE+8)
+
+/* Additional explicit controls needed by V4L2 ioctl implementation */
+#define V4L2_CID_PVR_STDCUR (V4L2_CID_PVR_GAP+1)
+#define V4L2_CID_PVR_INPUT (V4L2_CID_PVR_GAP+2)
+#define V4L2_CID_PVR_AUDIOMODE (V4L2_CID_PVR_GAP+3)
+#define V4L2_CID_PVR_FREQUENCY (V4L2_CID_PVR_GAP+4)
+#define V4L2_CID_PVR_HRES (V4L2_CID_PVR_GAP+5)
+#define V4L2_CID_PVR_VRES (V4L2_CID_PVR_GAP+6)
+#define V4L2_CID_PVR_INTERLACE (V4L2_CID_PVR_GAP+7)
/* Legal values for the INPUT state variable */
#define PVR2_CVAL_INPUT_TV 0
@@ -113,27 +61,11 @@
#define PVR2_CVAL_INPUT_MIN PVR2_CVAL_INPUT_TV
#define PVR2_CVAL_INPUT_MAX PVR2_CVAL_INPUT_RADIO
-/* Legal values for the AUDIOMODE state variable */
-#define PVR2_CVAL_AUDIOMODE_MONO 0
-#define PVR2_CVAL_AUDIOMODE_STEREO 1
-#define PVR2_CVAL_AUDIOMODE_SAP 2
-#define PVR2_CVAL_AUDIOMODE_LANG1 3
-#define PVR2_CVAL_AUDIOMODE_LANG2 4
-#define PVR2_CVAL_AUDIOMODE_LANG1_LANG2 5
-#define PVR2_CVAL_AUDIOMODE_MIN PVR2_CVAL_AUDIOMODE_MONO
-#define PVR2_CVAL_AUDIOMODE_MAX PVR2_CVAL_AUDIOMODE_LANG1_LANG2
-
/* Values that pvr2_hdw_get_signal_status() returns */
#define PVR2_SIGNAL_OK 0x0001
#define PVR2_SIGNAL_STEREO 0x0002
#define PVR2_SIGNAL_SAP 0x0004
-/* Legal values for PVR2_CID_HSM */
-#define PVR2_CVAL_HSM_FAIL 0
-#define PVR2_CVAL_HSM_FULL 1
-#define PVR2_CVAL_HSM_HIGH 2
-#define PVR2_CVAL_HSM_MIN PVR2_CVAL_HSM_FAIL
-#define PVR2_CVAL_HSM_MAX PVR2_CVAL_HSM_HIGH
/* Subsystem definitions - these are various pieces that can be
independently stopped / started. Usually you don't want to mess with
@@ -167,6 +99,8 @@ const char *pvr2_config_get_name(enum pvr2_config);
struct pvr2_hdw;
+struct pvr2_ctrl;
+
/* Create and return a structure for interacting with the underlying
hardware */
struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
@@ -215,37 +149,69 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
-/* Retrieve current value for a given control */
-int pvr2_hdw_get_ctl_value(struct pvr2_hdw *,unsigned int ctl_id);
+/* Get the number of defined controls */
+unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
+
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int);
+
+/* Retrieve a control handle given its well known ID */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl(struct pvr2_hdw *,unsigned int ctl_id);
+
+/* Set the current value of the given control. */
+int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val);
+
+/* Get the current value of the given control. */
+int pvr2_ctrl_get_value(struct pvr2_ctrl *);
+
+/* Return the type of the given control (int, enum, or bit mask). */
+int pvr2_ctrl_get_type(struct pvr2_ctrl *);
-/* Return true if control is writable */
-int pvr2_hdw_get_ctl_rw(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return the minimum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_min_value(struct pvr2_ctrl *);
-/* Retrieve legal minimum value for a given control */
-int pvr2_hdw_get_ctl_min_value(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return the maximum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_max_value(struct pvr2_ctrl *);
-/* Retrieve legal maximum value for a given control */
-int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return a mask of which bits are used within the bit mask of a given
+ control. This command is only relevant for bit mask types. */
+int pvr2_ctrl_get_mask_value(struct pvr2_ctrl *);
-/* Set current value for given control - this is just stored; the hardware
- isn't updated until the commit function is called. */
-int pvr2_hdw_set_ctl_value(struct pvr2_hdw *,unsigned int ctl_id,int value);
+/* Return the default value for a given control. */
+int pvr2_ctrl_get_default_value(struct pvr2_ctrl *);
-/* Retrieve string name for given control */
-const char *pvr2_hdw_get_ctl_name(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return true if this is a valid control. */
+int pvr2_ctrl_is_valid(struct pvr2_ctrl *);
-/* Retrieve string name for a given control value (returns a null pointer
- for any invalid combinations). */
-const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *,
- unsigned int ctl_id,int value);
+/* Return true if the control can be set (otherwise it may only be read,
+ assuming that it is valid). */
+int pvr2_ctrl_is_writeable(struct pvr2_ctrl *);
+
+/* Return the control's name, or null if there isn't a name or the control
+ isn't otherwise valid. */
+const char *pvr2_ctrl_get_name(struct pvr2_ctrl *);
+
+/* Return the control's description, or null if there isn't a name or the
+ control isn't otherwise valid. */
+const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *);
+
+/* Return the name for an enumeration value or bit mask position for the
+ given control. If the control is not an enumeration or bit mask type,
+ then return null. */
+const char *pvr2_ctrl_get_value_name(struct pvr2_ctrl *,int val);
+
+/* Return the number of support standard groups */
+unsigned int pvr2_hdw_get_stdenum_count(struct pvr2_hdw *);
+
+/* Return a pointer to a v4l2 standard descriptor for a given group */
+const struct v4l2_standard *pvr2_hdw_get_stdenum_value(struct pvr2_hdw *,
+ unsigned int idx);
/* Commit all control changes made up to this point */
int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
-/* Find out how many controls there are. Legal ids are numbered from 0
- through this value - 1. */
-unsigned int pvr2_hdw_get_ctl_count(struct pvr2_hdw *);
-
/* Return name for this driver instance */
const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index fc9d76792..89d0da053 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -28,8 +28,10 @@
#include "pvrusb2-tuner.h"
#include "pvrusb2-demod.h"
#include "pvrusb2-video-v4l.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
#include "pvrusb2-cx2584x-v4l.h"
#include "pvrusb2-wm8775.h"
+#endif
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
@@ -71,6 +73,7 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
return;
}
}
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
if (id == I2C_DRIVERID_CX25840) {
if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
return;
@@ -81,6 +84,7 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
return;
}
}
+#endif
if (id == I2C_DRIVERID_SAA711X) {
if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
return;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
index 000c26911..b3d2ce926 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -24,43 +24,23 @@
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
#include <linux/videodev.h>
+#include <linux/videodev2.h>
static void set_standard(struct pvr2_hdw *hdw)
{
- int cvstd = hdw->controls[PVR2_CID_VIDEOSTANDARD].value;
v4l2_std_id vs;
+ vs = hdw->controls[PVR2_CID_STDCUR].value;
pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_standard(%d)",cvstd);
-
- switch (cvstd) {
- default:
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- vs = V4L2_STD_NTSC_M;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_SECAM_L:
- vs = V4L2_STD_SECAM;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_BG:
- vs = V4L2_STD_PAL_BG;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_I:
- vs = V4L2_STD_PAL_I;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_DK:
- vs = V4L2_STD_PAL_DK;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
- vs = V4L2_STD_PAL_M;
- break;
- }
+ "i2c v4l2 set_standard(0x%llx)",(__u64)vs);
+
pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
}
static int check_standard(struct pvr2_hdw *hdw)
{
- return hdw->controls[PVR2_CID_VIDEOSTANDARD].dirty != 0;
+ return hdw->controls[PVR2_CID_STDCUR].dirty != 0;
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 2f7946195..9a96273f2 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -262,18 +262,29 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
done:
if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
- unsigned int idx;
+ unsigned int idx,offs,cnt;
for (idx = 0; idx < num; idx++) {
+ cnt = msgs[idx].len;
printk(KERN_INFO
"pvrusb2 i2c xfer %u/%u:"
" addr=0x%x len=%d %s%s",
idx+1,num,
msgs[idx].addr,
- msgs[idx].len,
+ cnt,
(msgs[idx].flags & I2C_M_RD ?
"read" : "write"),
(msgs[idx].flags & I2C_M_NOSTART ?
" nostart" : ""));
+ if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
+ if (cnt > 8) cnt = 8;
+ printk(" [");
+ for (offs = 0; offs < (cnt>8?8:cnt); offs++) {
+ if (offs) printk(" ");
+ printk("%02x",msgs[idx].buf[offs]);
+ }
+ if (offs < cnt) printk(" ...");
+ printk("]");
+ }
if (idx+1 == num) {
printk(" result=%d",ret);
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c
index c070fc195..40fb6ae41 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -35,7 +35,9 @@
#include "pvrusb2-context.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-v4l2.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
#include "pvrusb2-sysfs.h"
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
#define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>"
#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner"
@@ -60,13 +62,17 @@ int pvrusb2_debug = DEFAULT_DEBUG_MASK;
module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug, "Debug trace mask");
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
static struct pvr2_sysfs_class *class_ptr = 0;
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
static void pvr_setup_attach(struct pvr2_context *pvr)
{
/* Create association with v4l layer */
pvr2_v4l2_create(pvr);
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
pvr2_sysfs_create(pvr,class_ptr);
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
}
static int pvr_probe(struct usb_interface *intf,
@@ -138,7 +144,9 @@ static int __init pvr_init(void)
request_module("tda9887");
request_module("wm8775");
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
class_ptr = pvr2_sysfs_class_create();
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
ret = usb_register(&pvr_driver);
@@ -155,7 +163,9 @@ static void __exit pvr_exit(void)
pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
pvr2_sysfs_class_destroy(class_ptr);
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
usb_deregister(&pvr_driver);
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index f82fd643c..053c0b24c 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -26,49 +26,18 @@
#include "pvrusb2-sysfs.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
#include "pvrusb2-debugifc.h"
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
-static char *item_names[PVR2_CID_COUNT] = {
- [PVR2_CID_BRIGHTNESS] = "ctl_brightness",
- [PVR2_CID_CONTRAST] = "ctl_contrast",
- [PVR2_CID_SATURATION] = "ctl_saturation",
- [PVR2_CID_HUE] = "ctl_hue",
- [PVR2_CID_VOLUME] = "ctl_volume",
- [PVR2_CID_BALANCE] = "ctl_balance",
- [PVR2_CID_BASS] = "ctl_bass",
- [PVR2_CID_TREBLE] = "ctl_treble",
- [PVR2_CID_MUTE] = "ctl_mute",
- [PVR2_CID_SRATE] = "ctl_srate",
- [PVR2_CID_AUDIOBITRATE] = "ctl_audio_bitrate",
- [PVR2_CID_AUDIOCRC] = "ctl_audio_crc",
- [PVR2_CID_AUDIOEMPHASIS] = "ctl_audio_emphasis",
- [PVR2_CID_VBR] = "ctl_vbr",
- [PVR2_CID_AVERAGEVIDEOBITRATE] = "ctl_video_average_bitrate",
- [PVR2_CID_PEAKVIDEOBITRATE] = "ctl_video_peak_bitrate",
- [PVR2_CID_VIDEOSTANDARD] = "ctl_video_standard",
- [PVR2_CID_INPUT] = "ctl_input",
- [PVR2_CID_AUDIOMODE] = "ctl_audio_mode",
- [PVR2_CID_FREQUENCY] = "ctl_frequency",
- [PVR2_CID_HRES] = "ctl_resolution_hor",
- [PVR2_CID_VRES] = "ctl_resolution_ver",
- [PVR2_CID_INTERLACE] = "ctl_interlace",
- [PVR2_CID_AUDIOLAYER] = "ctl_audio_layer",
- [PVR2_CID_CHANNEL] = "ctl_channel",
- [PVR2_CID_CHANPROG_ID] = "ctl_freq_table_channel",
- [PVR2_CID_CHANPROG_FREQ] = "ctl_freq_table_value",
- [PVR2_CID_SIGNAL_PRESENT] = "ctl_signal_present",
- [PVR2_CID_STREAMING_ENABLED] = "ctl_streaming_enabled",
- [PVR2_CID_HSM] = "ctl_usb_speed",
- [PVR2_CID_SUBSYS_MASK] = "ctl_debug_subsys_mask",
- [PVR2_CID_SUBSYS_STREAM_MASK] = "ctl_debug_subsys_stream_mask",
-};
-
struct pvr2_sysfs {
struct pvr2_channel channel;
struct class_device *class_dev;
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
struct pvr2_sysfs_debugifc *debugifc;
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
struct pvr2_sysfs_ctl_item *item_first;
struct pvr2_sysfs_ctl_item *item_last;
struct sysfs_ops kops;
@@ -77,10 +46,12 @@ struct pvr2_sysfs {
struct class_device_attribute attr_unit_number;
};
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
struct pvr2_sysfs_debugifc {
struct class_device_attribute attr_debugcmd;
struct class_device_attribute attr_debuginfo;
};
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
struct pvr2_sysfs_ctl_item {
struct class_device_attribute attr_name;
@@ -88,11 +59,12 @@ struct pvr2_sysfs_ctl_item {
struct class_device_attribute attr_max;
struct class_device_attribute attr_enum;
struct class_device_attribute attr_val;
- int attr_id;
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *chptr;
struct pvr2_sysfs_ctl_item *item_next;
struct attribute *attr_gen[5];
struct attribute_group grp;
+ char name[80];
};
struct pvr2_sysfs_class {
@@ -101,13 +73,16 @@ struct pvr2_sysfs_class {
static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
const char *name;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- name = pvr2_hdw_get_ctl_name(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ name = pvr2_ctrl_get_desc(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name);
if (!name) return -EINVAL;
@@ -117,13 +92,15 @@ static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,id);
-
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ val = pvr2_ctrl_get_min_value(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %d",sfp,id,val);
return scnprintf(buf,PAGE_SIZE,"%d\n",val);
@@ -131,12 +108,15 @@ static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_max_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ val = pvr2_ctrl_get_max_value(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %d",sfp,id,val);
@@ -145,12 +125,15 @@ static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
static ssize_t show_val_int(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ val = pvr2_ctrl_get_value(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_int(cid=%d) is %d",
sfp,id,val);
@@ -160,15 +143,18 @@ static ssize_t show_val_int(int id,struct class_device *class_dev,char *buf)
static ssize_t show_val_enum(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
const char *name;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
- name = pvr2_hdw_get_ctl_value_name(sfp->channel.hdw,id,val);
+ val = pvr2_ctrl_get_value(cptr);
+ name = pvr2_ctrl_get_value_name(cptr,val);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_enum(cid=%d) is %s (%d)",
sfp,id,name,val);
@@ -178,6 +164,7 @@ static ssize_t show_val_enum(int id,struct class_device *class_dev,char *buf)
static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int minval,maxval,val;
const char *name;
@@ -185,10 +172,12 @@ static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- minval = pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,id);
- maxval = pvr2_hdw_get_ctl_max_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ minval = pvr2_ctrl_get_min_value(cptr);
+ maxval = pvr2_ctrl_get_max_value(cptr);
for (val = minval; val <= maxval; val++) {
- name = pvr2_hdw_get_ctl_value_name(sfp->channel.hdw,id,val);
+ name = pvr2_ctrl_get_value_name(cptr,val);
cnt += scnprintf(buf+cnt,PAGE_SIZE-cnt,"%s\n",name);
}
pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id);
@@ -198,6 +187,7 @@ static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
static int store_val_any(int id,struct pvr2_sysfs *sfp,
const char *buf,unsigned int count)
{
+ struct pvr2_ctrl *cptr;
int val,minval,maxval;
int ch,ret;
const char *nv;
@@ -217,11 +207,14 @@ static int store_val_any(int id,struct pvr2_sysfs *sfp,
count--;
}
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+
/* Is this an enum? Look for a string value */
- minval = pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,id);
- maxval = pvr2_hdw_get_ctl_max_value(sfp->channel.hdw,id);
+ minval = pvr2_ctrl_get_min_value(cptr);
+ maxval = pvr2_ctrl_get_max_value(cptr);
for (val = minval; val <= maxval; val++) {
- nv = pvr2_hdw_get_ctl_value_name(sfp->channel.hdw,id,val);
+ nv = pvr2_ctrl_get_value_name(cptr,val);
if ((!nv) && (val == minval)) break; /* Not an enum */
pvr2_sysfs_trace("pvr2_sysfs(%p) trying ctl_id %d val %d",
sfp,id,val);
@@ -246,7 +239,7 @@ static int store_val_any(int id,struct pvr2_sysfs *sfp,
pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_any(cid=%d)"
" is enum %s",
sfp,id,nv);
- ret = pvr2_hdw_set_ctl_value(sfp->channel.hdw,id,val);
+ ret = pvr2_ctrl_set_value(cptr,val);
pvr2_hdw_commit_ctl(sfp->channel.hdw);
return 0;
}
@@ -284,7 +277,7 @@ static int store_val_any(int id,struct pvr2_sysfs *sfp,
" int is %d",
sfp,id,val);
- ret = pvr2_hdw_set_ctl_value(sfp->channel.hdw,id,val);
+ ret = pvr2_ctrl_set_value(cptr,val);
pvr2_hdw_commit_ctl(sfp->channel.hdw);
return ret;
}
@@ -395,6 +388,8 @@ CREATE_BATCH(28)
CREATE_BATCH(29)
CREATE_BATCH(30)
CREATE_BATCH(31)
+CREATE_BATCH(32)
+CREATE_BATCH(33)
struct pvr2_sysfs_func_set {
ssize_t (*show_name)(struct class_device *,char *);
@@ -454,6 +449,8 @@ static struct pvr2_sysfs_func_set funcs[] = {
INIT_BATCH(29),
INIT_BATCH(30),
INIT_BATCH(31),
+ INIT_BATCH(32),
+ INIT_BATCH(33),
};
@@ -461,19 +458,23 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
{
struct pvr2_sysfs_ctl_item *cip;
struct pvr2_sysfs_func_set *fp;
+ struct pvr2_ctrl *cptr;
+ unsigned int cnt;
if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
return;
}
fp = funcs + ctl_id;
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
+ if (!cptr) return;
cip = kmalloc(sizeof(*cip),GFP_KERNEL);
if (!cip) return;
memset(cip,0,sizeof(*cip));
pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
- cip->attr_id = ctl_id;
+ cip->cptr = cptr;
cip->chptr = sfp;
cip->item_next = 0;
@@ -508,15 +509,13 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
cip->attr_enum.attr.mode = S_IRUGO;
cip->attr_enum.show = fp->show_enum;
- if (pvr2_hdw_get_ctl_rw(sfp->channel.hdw,ctl_id)) {
+ if (pvr2_ctrl_is_writeable(cptr)) {
cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
}
cip->attr_gen[0] = &cip->attr_name.attr;
cip->attr_gen[1] = &cip->attr_val.attr;
- if (pvr2_hdw_get_ctl_value_name(
- sfp->channel.hdw,ctl_id,
- pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,ctl_id))) {
+ if (pvr2_ctrl_get_type(cptr) == PVR2_CTRL_TYPE_ENUM) {
// Control is an enumeration
cip->attr_gen[2] = &cip->attr_enum.attr;
cip->attr_val.show = fp->show_val_enum;
@@ -529,12 +528,16 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
cip->attr_gen[3] = &cip->attr_max.attr;
}
- cip->grp.name = item_names[ctl_id];
+ cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
+ pvr2_ctrl_get_name(cptr));
+ cip->name[cnt] = 0;
+ cip->grp.name = cip->name;
cip->grp.attrs = cip->attr_gen;
sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
}
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
static ssize_t debuginfo_show(struct class_device *,char *);
static ssize_t debugcmd_show(struct class_device *,char *);
static ssize_t debugcmd_store(struct class_device *,const char *,size_t count);
@@ -569,16 +572,15 @@ static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
kfree(sfp->debugifc);
sfp->debugifc = 0;
}
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
{
- unsigned int ctl_id;
-
- for (ctl_id = 0;
- ctl_id < (sizeof(item_names)/sizeof(item_names[0])); ctl_id++) {
- if (!item_names[ctl_id]) continue;
- pvr2_sysfs_add_control(sfp,ctl_id);
+ unsigned int idx,cnt;
+ cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
+ for (idx = 0; idx < cnt; idx++) {
+ pvr2_sysfs_add_control(sfp,idx);
}
}
@@ -614,7 +616,9 @@ static void pvr2_sysfs_release(struct class_device *class_dev)
static void class_dev_destroy(struct pvr2_sysfs *sfp)
{
if (!sfp->class_dev) return;
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
pvr2_sysfs_tear_down_debugifc(sfp);
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
pvr2_sysfs_tear_down_controls(sfp);
class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number);
@@ -690,7 +694,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
pvr2_sysfs_add_controls(sfp);
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
pvr2_sysfs_add_debugifc(sfp);
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
}
@@ -761,6 +767,7 @@ void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
}
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
static ssize_t debuginfo_show(struct class_device *class_dev,char *buf)
{
struct pvr2_sysfs *sfp;
@@ -793,6 +800,7 @@ static ssize_t debugcmd_store(struct class_device *class_dev,
if (ret < 0) return ret;
return count;
}
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
/*
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index dd207fae4..fe7045e8f 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -80,22 +80,6 @@ static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
module_param_array(video_nr, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "Offset for device's minor");
-#define V4L2_CID_PVR_SRATE (V4L2_CID_PRIVATE_BASE)
-#define V4L2_CID_PVR_AUDIOBITRATE (V4L2_CID_PRIVATE_BASE+1)
-#define V4L2_CID_PVR_AUDIOCRC (V4L2_CID_PRIVATE_BASE+2)
-#define V4L2_CID_PVR_AUDIOEMPHASIS (V4L2_CID_PRIVATE_BASE+3)
-#define V4L2_CID_PVR_VBR (V4L2_CID_PRIVATE_BASE+4)
-#define V4L2_CID_PVR_VIDEOBITRATE (V4L2_CID_PRIVATE_BASE+5)
-#define V4L2_CID_PVR_VIDEOPEAK (V4L2_CID_PRIVATE_BASE+6)
-#define V4L2_CID_PVR_VIDEOSTANDARD (V4L2_CID_PRIVATE_BASE+7)
-#define V4L2_CID_PVR_INPUT (V4L2_CID_PRIVATE_BASE+8)
-#define V4L2_CID_PVR_AUDIOMODE (V4L2_CID_PRIVATE_BASE+9)
-#define V4L2_CID_PVR_FREQUENCY (V4L2_CID_PRIVATE_BASE+10)
-#define V4L2_CID_PVR_HRES (V4L2_CID_PRIVATE_BASE+11)
-#define V4L2_CID_PVR_VRES (V4L2_CID_PRIVATE_BASE+12)
-
-#define V4L2_CID_PVR_MAX (V4L2_CID_PRIVATE_BASE+12)
-
struct v4l2_capability pvr_capability ={
.driver = "pvrusb2",
.card = "Hauppauge WinTV pvr-usb2",
@@ -141,69 +125,6 @@ static struct v4l2_tuner pvr_v4l2_tuners[]= {
#endif
};
-struct v4l2_standard pvr_standards[] = {
- [PVR2_CVAL_VIDEOSTANDARD_PAL_BG] = {
- .id = V4L2_STD_PAL_BG,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_PAL_I] = {
- .id = V4L2_STD_PAL_I,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_PAL_DK] = {
- .id = V4L2_STD_PAL_DK,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_SECAM_L] = {
- .id = V4L2_STD_SECAM,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_NTSC_M] = {
- .id = V4L2_STD_NTSC_M,
- .frameperiod =
- {
- .numerator = 1001,
- .denominator= 30000
- },
- .framelines = 525,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_PAL_M] = {
- .id = V4L2_STD_PAL_M,
- .frameperiod =
- {
- .numerator = 1001,
- .denominator= 30000
- },
- .framelines = 525,
- .reserved = {0,0,0,0}
- }
-};
-
struct v4l2_fmtdesc pvr_fmtdesc [] = {
{
.index = 0,
@@ -257,84 +178,6 @@ struct v4l2_format pvr_format [] = {
}
};
-static int cnv_cid_v4l2_pvr2(int id)
-{
- switch (id) {
- case V4L2_CID_BRIGHTNESS:
- return PVR2_CID_BRIGHTNESS;
- case V4L2_CID_SATURATION:
- return PVR2_CID_SATURATION;
- case V4L2_CID_CONTRAST:
- return PVR2_CID_CONTRAST;
- case V4L2_CID_HUE:
- return PVR2_CID_HUE;
- case V4L2_CID_AUDIO_VOLUME:
- return PVR2_CID_VOLUME;
- case V4L2_CID_AUDIO_BALANCE:
- return PVR2_CID_BALANCE;
- case V4L2_CID_AUDIO_BASS:
- return PVR2_CID_BASS;
- case V4L2_CID_AUDIO_TREBLE:
- return PVR2_CID_TREBLE;
- case V4L2_CID_AUDIO_MUTE:
- return PVR2_CID_MUTE;
- case V4L2_CID_PVR_SRATE:
- return PVR2_CID_SRATE;
- case V4L2_CID_PVR_AUDIOBITRATE:
- return PVR2_CID_AUDIOBITRATE;
- case V4L2_CID_PVR_AUDIOCRC:
- return PVR2_CID_AUDIOCRC;
- case V4L2_CID_PVR_AUDIOEMPHASIS:
- return PVR2_CID_AUDIOEMPHASIS;
- case V4L2_CID_PVR_VBR:
- return PVR2_CID_VBR;
- case V4L2_CID_PVR_VIDEOBITRATE:
- return PVR2_CID_AVERAGEVIDEOBITRATE;
- case V4L2_CID_PVR_VIDEOPEAK:
- return PVR2_CID_PEAKVIDEOBITRATE;
- case V4L2_CID_PVR_INPUT:
- return PVR2_CID_INPUT;
- case V4L2_CID_PVR_AUDIOMODE:
- return PVR2_CID_AUDIOMODE;
- case V4L2_CID_PVR_FREQUENCY:
- return PVR2_CID_FREQUENCY;
- case V4L2_CID_PVR_HRES:
- return PVR2_CID_HRES;
- case V4L2_CID_PVR_VRES:
- return PVR2_CID_VRES;
- }
- return -1;
-}
-
-#if 0
-static int cnv_cid_pvr2_v4l2(int id)
-{
- switch (id) {
- case PVR2_CID_BRIGHTNESS:
- return V4L2_CID_BRIGHTNESS;
- case PVR2_CID_SATURATION:
- return V4L2_CID_SATURATION;
- case PVR2_CID_CONTRAST:
- return V4L2_CID_CONTRAST;
- case PVR2_CID_HUE:
- return V4L2_CID_HUE;
- case PVR2_CID_VOLUME:
- return V4L2_CID_AUDIO_VOLUME;
- case PVR2_CID_BALANCE:
- return V4L2_CID_AUDIO_BALANCE;
- case PVR2_CID_BASS:
- return V4L2_CID_AUDIO_BASS;
- case PVR2_CID_TREBLE:
- return V4L2_CID_AUDIO_TREBLE;
- case PVR2_CID_MUTE:
- return V4L2_CID_AUDIO_MUTE;
-
- return id + V4L2_CID_PRIVATE_BASE;
- }
- return -1;
-}
-#endif
-
/*
* pvr_ioctl()
*
@@ -402,22 +245,15 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_ENUMSTD:
{
-
struct v4l2_standard *vs = (struct v4l2_standard *)arg;
+ const struct v4l2_standard *src;
int idx = vs->index;
- if ((vs->index < PVR2_CVAL_VIDEOSTANDARD_MIN) ||
- (vs->index > PVR2_CVAL_VIDEOSTANDARD_MAX)) {
- break;
- }
+ src = pvr2_hdw_get_stdenum_value(hdw,idx);
+ if (!src) break;
- memcpy(vs, &pvr_standards[idx], sizeof(struct v4l2_standard));
+ memcpy(vs, src, sizeof(struct v4l2_standard));
vs->index = idx;
- strlcpy(vs->name,
- pvr2_hdw_get_ctl_value_name(hdw,
- PVR2_CID_VIDEOSTANDARD,
- idx),
- sizeof(vs->name));
ret = 0;
break;
@@ -425,59 +261,37 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_STD:
{
+ struct pvr2_ctrl *cptr;
v4l2_std_id *vs = (v4l2_std_id *)arg;
-
- switch (pvr2_hdw_get_ctl_value(hdw,PVR2_CID_VIDEOSTANDARD)) {
- default:
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- *vs = V4L2_STD_NTSC_M;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
- *vs = V4L2_STD_PAL_M;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_SECAM_L:
- *vs = V4L2_STD_SECAM;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_BG:
- *vs = V4L2_STD_PAL_BG;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_I:
- *vs = V4L2_STD_PAL_I;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_DK:
- *vs = V4L2_STD_PAL_DK;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_STDCUR);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
break;
}
+
+ *vs = pvr2_ctrl_get_value(cptr);
ret = 0;
break;
}
case VIDIOC_S_STD:
{
+ struct pvr2_ctrl *cptr;
v4l2_std_id *vs = (v4l2_std_id *)arg;
- int val = PVR2_CVAL_VIDEOSTANDARD_NTSC_M;
-
- if (*vs & V4L2_STD_NTSC_M){
- val = PVR2_CVAL_VIDEOSTANDARD_NTSC_M;
- } else if (*vs & V4L2_STD_PAL_BG){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_BG;
- } else if (*vs & V4L2_STD_PAL_I){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_I;
- } else if (*vs & V4L2_STD_PAL_DK){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_DK;
- } else if (*vs & V4L2_STD_SECAM){
- val = PVR2_CVAL_VIDEOSTANDARD_SECAM_L;
- } else if (*vs & V4L2_STD_PAL_M){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_M;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_STDCUR);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
}
- pvr2_hdw_set_ctl_value(hdw,PVR2_CID_VIDEOSTANDARD,val);
-
+ pvr2_ctrl_set_value(cptr,*vs);
+ ret = 0;
break;
}
case VIDIOC_ENUMINPUT:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_input *vi = (struct v4l2_input *)arg;
struct v4l2_input tmp;
@@ -486,6 +300,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
break;
}
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_INPUT);
+
memset(&tmp,0,sizeof(tmp));
tmp.index = vi->index;
switch (vi->index) {
@@ -500,8 +316,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
}
strlcpy(tmp.name,
- pvr2_hdw_get_ctl_value_name(hdw,PVR2_CID_INPUT,
- vi->index),
+ pvr2_ctrl_get_value_name(cptr,vi->index),
sizeof(tmp.name));
/* Don't bother with audioset, since this driver currently
@@ -522,17 +337,31 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_INPUT:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_input *vi = (struct v4l2_input *)arg;
- vi->index = pvr2_hdw_get_ctl_value(hdw,PVR2_CID_INPUT);
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_INPUT);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ vi->index = pvr2_ctrl_get_value(cptr);
ret = 0;
break;
}
case VIDIOC_S_INPUT:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_input *vi = (struct v4l2_input *)arg;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_INPUT);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
ret = 0;
- if (pvr2_hdw_set_ctl_value(hdw,PVR2_CID_INPUT,vi->index)) {
+ if (pvr2_ctrl_set_value(cptr,vi->index)) {
ret = -EINVAL;
}
break;
@@ -557,6 +386,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
}
case VIDIOC_G_TUNER:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
unsigned int status_mask;
if (vt->index !=0) break;
@@ -580,26 +410,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
vt->signal = 65535;
}
- switch (pvr2_hdw_get_ctl_value(hdw,PVR2_CID_AUDIOMODE)) {
- case PVR2_CVAL_AUDIOMODE_MONO:
- vt->audmode = V4L2_TUNER_MODE_MONO;
- break;
- case PVR2_CVAL_AUDIOMODE_STEREO:
- vt->audmode = V4L2_TUNER_MODE_STEREO;
- break;
- case PVR2_CVAL_AUDIOMODE_LANG1:
- vt->audmode = V4L2_TUNER_MODE_LANG1;
- break;
- case PVR2_CVAL_AUDIOMODE_LANG2:
- vt->audmode = V4L2_TUNER_MODE_LANG2;
- break;
- case PVR2_CVAL_AUDIOMODE_LANG1_LANG2:
- vt->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
- break;
- case PVR2_CVAL_AUDIOMODE_SAP:
- vt->audmode = V4L2_TUNER_MODE_SAP;
- break;
- }
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_AUDIOMODE);
+ vt->audmode = pvr2_ctrl_get_value(cptr);
ret = 0;
break;
@@ -607,40 +419,34 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_S_TUNER:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
- int val = PVR2_CVAL_AUDIOMODE_STEREO;
if (vt->index != 0)
break;
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- val = PVR2_CVAL_AUDIOMODE_MONO;
- break;
- case V4L2_TUNER_MODE_STEREO:
- val = PVR2_CVAL_AUDIOMODE_STEREO;
- break;
- case V4L2_TUNER_MODE_LANG1:
- val = PVR2_CVAL_AUDIOMODE_LANG1;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- val = PVR2_CVAL_AUDIOMODE_LANG1_LANG2;
- break;
- case V4L2_TUNER_MODE_SAP: // Also LANG2
- val = PVR2_CVAL_AUDIOMODE_SAP;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_AUDIOMODE);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
break;
}
- pvr2_hdw_set_ctl_value(hdw,PVR2_CID_AUDIOMODE,val);
+ pvr2_ctrl_set_value(cptr,vt->audmode);
ret = 0;
}
case VIDIOC_S_FREQUENCY:
{
+ struct pvr2_ctrl *cptr;
const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
- pvr2_hdw_set_ctl_value(hdw,PVR2_CID_FREQUENCY,
- vf->frequency * 62500);
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_FREQUENCY);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ pvr2_ctrl_set_value(cptr,vf->frequency * 62500);
ret = 0;
break;
@@ -648,10 +454,17 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_FREQUENCY:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
int val;
- val = pvr2_hdw_get_ctl_value(hdw,PVR2_CID_FREQUENCY);
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_FREQUENCY);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ val = pvr2_ctrl_get_value(cptr);
val /= 62500;
vf->frequency = val;
@@ -682,12 +495,18 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
sizeof(struct v4l2_format));
vf->fmt.pix.width =
- pvr2_hdw_get_ctl_value(hdw,PVR2_CID_HRES);
- if (pvr2_hdw_get_ctl_value(hdw,PVR2_CID_INTERLACE)) {
+ pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_HRES));
+ if (pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(
+ hdw,V4L2_CID_PVR_INTERLACE))) {
vf->fmt.pix.width /= 2;
}
vf->fmt.pix.height =
- pvr2_hdw_get_ctl_value(hdw,PVR2_CID_VRES);
+ pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_VRES));
ret = 0;
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -713,16 +532,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
int w = vf->fmt.pix.width;
int vd_std, hf, hh;
- vd_std = pvr2_hdw_get_ctl_value(hdw,
- PVR2_CID_VIDEOSTANDARD);
- switch (vd_std) {
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
+ vd_std = pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_STDCUR));
+ if (vd_std & V4L2_STD_525_60) {
hf=480;
- break;
- default:
+ } else {
hf=576;
- break;
}
hh = (int) (hf / 2);
@@ -734,15 +549,18 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
vf->fmt.pix.height = (h > hh) ? hf : hh;
if (cmd == VIDIOC_S_FMT){
- pvr2_hdw_set_ctl_value(
- hdw,PVR2_CID_HRES,
+ pvr2_ctrl_set_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_HRES),
vf->fmt.pix.width);
- pvr2_hdw_set_ctl_value(
- hdw,PVR2_CID_VRES,
+ pvr2_ctrl_set_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_VRES),
vf->fmt.pix.height);
- pvr2_hdw_set_ctl_value(
- hdw,PVR2_CID_INTERLACE,
- (vf->fmt.pix.height != hf));
+ pvr2_ctrl_set_value(
+ pvr2_hdw_get_ctrl(
+ hdw,V4L2_CID_PVR_INTERLACE),
+ vf->fmt.pix.height != hf);
}
} break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -772,22 +590,31 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_QUERYCTRL:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
- int pvr2_id = cnv_cid_v4l2_pvr2(vc->id);
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vc->id);
+
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
- if (pvr2_hdw_get_ctl_value_name(hdw,pvr2_id,0)) {
+ switch (pvr2_ctrl_get_type(cptr)) {
+ case PVR2_CTRL_TYPE_ENUM:
vc->type = V4L2_CTRL_TYPE_MENU;
- } else {
+ break;
+ case PVR2_CTRL_TYPE_INT:
vc->type = V4L2_CTRL_TYPE_INTEGER;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
}
- strlcpy(vc->name,pvr2_hdw_get_ctl_name(hdw,pvr2_id),
- sizeof(vc->name));
- vc->minimum = pvr2_hdw_get_ctl_min_value(hdw,pvr2_id);
- vc->maximum = pvr2_hdw_get_ctl_max_value(hdw,pvr2_id);
+
+ strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name));
+ vc->minimum = pvr2_ctrl_get_min_value(cptr);
+ vc->maximum = pvr2_ctrl_get_max_value(cptr);
+ vc->default_value = pvr2_ctrl_get_default_value(cptr);
vc->step = 1;
ret = 0;
break;
@@ -795,16 +622,15 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_QUERYMENU:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
- int pvr2_id = cnv_cid_v4l2_pvr2(vm->id);
const char *value_name;
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vm->id);
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
-
- value_name = pvr2_hdw_get_ctl_value_name(hdw,pvr2_id,
- vm->index);
+ value_name = pvr2_ctrl_get_value_name(cptr,vm->index);
if (value_name) {
strlcpy(vm->name,value_name,sizeof(vm->name));
ret = 0;
@@ -817,31 +643,31 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_CTRL:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_control *vc = (struct v4l2_control *)arg;
- int pvr2_id;
- pvr2_id = cnv_cid_v4l2_pvr2(vc->id);
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vc->id);
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
ret = 0;
- vc->value = pvr2_hdw_get_ctl_value(hdw,pvr2_id);
+ vc->value = pvr2_ctrl_get_value(cptr);
break;
}
case VIDIOC_S_CTRL:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_control *vc = (struct v4l2_control *)arg;
- int pvr2_id;
- pvr2_id = cnv_cid_v4l2_pvr2(vc->id);
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vc->id);
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
- ret = pvr2_hdw_set_ctl_value(hdw,pvr2_id,vc->value);
+ ret = pvr2_ctrl_set_value(cptr,vc->value);
break;
}