summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c1764
1 files changed, 760 insertions, 1004 deletions
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index f0de1e154..890aa4a06 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -24,9 +24,9 @@
#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-std.h"
#include "pvrusb2-util.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-i2c-core.h"
@@ -53,6 +53,42 @@ static const char *pvr2_device_names[] = {
#endif
};
+struct pvr2_string_table {
+ const char **lst;
+ unsigned int cnt;
+};
+
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+// Names of other client modules to request for 24xxx model hardware
+static const char *pvr2_client_24xxx[] = {
+ "cx25840",
+ "tuner",
+ "tda9887",
+ "wm8775",
+};
+#endif
+
+// Names of other client modules to request for 29xxx model hardware
+static const char *pvr2_client_29xxx[] = {
+ "msp3400",
+ "saa7115",
+ "tuner",
+ "tda9887",
+};
+
+static struct pvr2_string_table pvr2_client_lists[] = {
+ [PVR2_HDW_TYPE_29XXX] = {
+ pvr2_client_29xxx,
+ sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]),
+ },
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+ [PVR2_HDW_TYPE_24XXX] = {
+ pvr2_client_24xxx,
+ sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]),
+ },
+#endif
+};
+
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0};
DECLARE_MUTEX(pvr2_unit_sem);
@@ -61,6 +97,7 @@ static int initusbreset = 1;
static int procreload = 0;
static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
+static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
static int init_pause_msec = 0;
module_param(ctlchg, int, S_IRUGO|S_IWUSR);
@@ -74,6 +111,8 @@ MODULE_PARM_DESC(procreload,
"Attempt init failure recovery with firmware reload");
module_param_array(tuner, int, NULL, 0444);
MODULE_PARM_DESC(tuner,"specify installed tuner type");
+module_param_array(video_std, int, NULL, 0444);
+MODULE_PARM_DESC(video_std,"specify initial video standard");
module_param_array(tolerance, int, NULL, 0444);
MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
@@ -123,39 +162,6 @@ static const char *control_values_audioemphasis[] = {
};
-static const char *control_values_videostandard[] = {
- "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",
-};
-
-
static const char *control_values_input[] = {
[PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
[PVR2_CVAL_INPUT_RADIO] = "radio",
@@ -180,339 +186,552 @@ static const char *control_values_hsm[] = {
};
-#define VDEF(x) \
- .value_defs_ptr = x, \
- .value_defs_count = (sizeof(x)/sizeof(x[0]))
-
-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] = {
- .id = V4L2_CID_BRIGHTNESS,
- .is_valid = !0,
+static const char *control_values_subsystem[] = {
+ [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
+ [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
+ [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
+ [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
+ [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
+};
+
+
+static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ struct pvr2_hdw *hdw = cptr->hdw;
+ if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
+ *vp = hdw->freqTable[hdw->freqProgSlot-1];
+ } else {
+ *vp = 0;
+ }
+ return 0;
+}
+
+static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ struct pvr2_hdw *hdw = cptr->hdw;
+ if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
+ hdw->freqTable[hdw->freqProgSlot-1] = v;
+ }
+ return 0;
+}
+
+static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->freqProgSlot;
+ return 0;
+}
+
+static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ struct pvr2_hdw *hdw = cptr->hdw;
+ if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
+ hdw->freqProgSlot = v;
+ }
+ return 0;
+}
+
+static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->freqSlot;
+ return 0;
+}
+
+static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ unsigned freq = 0;
+ struct pvr2_hdw *hdw = cptr->hdw;
+ hdw->freqSlot = v;
+ if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) {
+ freq = hdw->freqTable[hdw->freqSlot-1];
+ }
+ if (freq && (freq != hdw->freqVal)) {
+ hdw->freqVal = freq;
+ hdw->freqDirty = !0;
+ }
+ return 0;
+}
+
+static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->freqVal;
+ return 0;
+}
+
+static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
+{
+ return cptr->hdw->freqDirty != 0;
+}
+
+static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
+{
+ cptr->hdw->freqDirty = 0;
+}
+
+static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ struct pvr2_hdw *hdw = cptr->hdw;
+ hdw->freqVal = v;
+ hdw->freqDirty = !0;
+ hdw->freqSlot = 0;
+ return 0;
+}
+
+static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->flag_streaming_enabled;
+ return 0;
+}
+
+static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ int result = pvr2_hdw_is_hsm(cptr->hdw);
+ *vp = PVR2_CVAL_HSM_FULL;
+ if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
+ if (result) *vp = PVR2_CVAL_HSM_HIGH;
+ return 0;
+}
+
+static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->std_mask_avail;
+ return 0;
+}
+
+static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ struct pvr2_hdw *hdw = cptr->hdw;
+ v4l2_std_id ns;
+ ns = hdw->std_mask_avail;
+ ns = (ns & ~m) | (v & m);
+ if (ns == hdw->std_mask_avail) return 0;
+ hdw->std_mask_avail = ns;
+ pvr2_hdw_internal_set_std_avail(hdw);
+ pvr2_hdw_internal_find_stdenum(hdw);
+ return 0;
+}
+
+static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
+ char *bufPtr,unsigned int bufSize,
+ unsigned int *len)
+{
+ *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
+ return 0;
+}
+
+static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
+ const char *bufPtr,unsigned int bufSize,
+ int *mskp,int *valp)
+{
+ int ret;
+ v4l2_std_id id;
+ ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
+ if (ret < 0) return ret;
+ if (mskp) *mskp = id;
+ if (valp) *valp = id;
+ return 0;
+}
+
+static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->std_mask_cur;
+ return 0;
+}
+
+static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ struct pvr2_hdw *hdw = cptr->hdw;
+ v4l2_std_id ns;
+ ns = hdw->std_mask_cur;
+ ns = (ns & ~m) | (v & m);
+ if (ns == hdw->std_mask_cur) return 0;
+ hdw->std_mask_cur = ns;
+ hdw->std_dirty = !0;
+ pvr2_hdw_internal_find_stdenum(hdw);
+ return 0;
+}
+
+static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
+{
+ return cptr->hdw->std_dirty != 0;
+}
+
+static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
+{
+ cptr->hdw->std_dirty = 0;
+}
+
+static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
+ PVR2_SIGNAL_OK) ? 1 : 0);
+ return 0;
+}
+
+static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->subsys_enabled_mask;
+ return 0;
+}
+
+static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
+ return 0;
+}
+
+static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->subsys_stream_mask;
+ return 0;
+}
+
+static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
+ return 0;
+}
+
+static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+ struct pvr2_hdw *hdw = cptr->hdw;
+ if (v < 0) return -EINVAL;
+ if (v > hdw->std_enum_cnt) return -EINVAL;
+ hdw->std_enum_cur = v;
+ if (!v) return 0;
+ v--;
+ if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
+ hdw->std_mask_cur = hdw->std_defs[v].id;
+ hdw->std_dirty = !0;
+ return 0;
+}
+
+
+static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ *vp = cptr->hdw->std_enum_cur;
+ return 0;
+}
+
+
+static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
+{
+ return cptr->hdw->std_dirty != 0;
+}
+
+
+static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
+{
+ cptr->hdw->std_dirty = 0;
+}
+
+
+#define DEFINT(vmin,vmax) \
+ .type = pvr2_ctl_int, \
+ .def.type_int.min_value = vmin, \
+ .def.type_int.max_value = vmax
+
+#define DEFENUM(tab) \
+ .type = pvr2_ctl_enum, \
+ .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
+ .def.type_enum.value_names = tab
+
+#define DEFMASK(msk,tab) \
+ .type = pvr2_ctl_bitmask, \
+ .def.type_bitmask.valid_bits = msk, \
+ .def.type_bitmask.bit_names = tab
+
+#define DEFREF(vname) \
+ .set_value = ctrl_set_##vname, \
+ .get_value = ctrl_get_##vname, \
+ .is_dirty = ctrl_isdirty_##vname, \
+ .clear_dirty = ctrl_cleardirty_##vname
+
+
+#define VCREATE_FUNCS(vname) \
+static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
+{*vp = cptr->hdw->vname##_val; return 0;} \
+static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
+{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
+static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
+{return cptr->hdw->vname##_dirty != 0;} \
+static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
+{cptr->hdw->vname##_dirty = 0;}
+
+VCREATE_FUNCS(brightness)
+VCREATE_FUNCS(contrast)
+VCREATE_FUNCS(saturation)
+VCREATE_FUNCS(hue)
+VCREATE_FUNCS(volume)
+VCREATE_FUNCS(balance)
+VCREATE_FUNCS(bass)
+VCREATE_FUNCS(treble)
+VCREATE_FUNCS(mute)
+VCREATE_FUNCS(srate)
+VCREATE_FUNCS(audiobitrate)
+VCREATE_FUNCS(audiocrc)
+VCREATE_FUNCS(audioemphasis)
+VCREATE_FUNCS(vbr)
+VCREATE_FUNCS(videobitrate)
+VCREATE_FUNCS(videopeak)
+VCREATE_FUNCS(input)
+VCREATE_FUNCS(audiomode)
+VCREATE_FUNCS(res_hor)
+VCREATE_FUNCS(res_ver)
+VCREATE_FUNCS(interlace)
+VCREATE_FUNCS(audiolayer)
+
+#define MIN_FREQ 55250000L
+#define MAX_FREQ 850000000L
+
+/* Table definition of all controls which can be manipulated */
+static const struct pvr2_ctl_info control_defs[] = {
+ {
+ .v4l_id = V4L2_CID_BRIGHTNESS,
.desc = "Brightness",
.name = "brightness",
- .min_value = 0,
- .max_value = 255,
.default_value = 128,
- },
- [PVR2_CID_CONTRAST] = {
- .id = V4L2_CID_CONTRAST,
- .is_valid = !0,
+ DEFREF(brightness),
+ DEFINT(0,255),
+ },{
+ .v4l_id = V4L2_CID_CONTRAST,
.desc = "Contrast",
.name = "contrast",
- .min_value = 0,
- .max_value = 127,
.default_value = 68,
- },
- [PVR2_CID_SATURATION] = {
- .id = V4L2_CID_SATURATION,
- .is_valid = !0,
+ DEFREF(contrast),
+ DEFINT(0,127),
+ },{
+ .v4l_id = V4L2_CID_SATURATION,
.desc = "Saturation",
.name = "saturation",
- .min_value = 0,
- .max_value = 127,
.default_value = 64,
- },
- [PVR2_CID_HUE] = {
- .id = V4L2_CID_HUE,
- .is_valid = !0,
+ DEFREF(saturation),
+ DEFINT(0,127),
+ },{
+ .v4l_id = V4L2_CID_HUE,
.desc = "Hue",
.name = "hue",
- .min_value = -128,
- .max_value = 127,
.default_value = 0,
- },
- [PVR2_CID_VOLUME] = {
- .id = V4L2_CID_AUDIO_VOLUME,
- .is_valid = !0,
+ DEFREF(hue),
+ DEFINT(-128,127),
+ },{
+ .v4l_id = V4L2_CID_AUDIO_VOLUME,
.desc = "Volume",
.name = "volume",
- .min_value = 0,
- .max_value = 65535,
.default_value = 65535,
- },
- [PVR2_CID_BALANCE] = {
- .id = V4L2_CID_AUDIO_BALANCE,
- .is_valid = !0,
+ DEFREF(volume),
+ DEFINT(0,65535),
+ },{
+ .v4l_id = V4L2_CID_AUDIO_BALANCE,
.desc = "Balance",
.name = "balance",
- .min_value = -32768,
- .max_value = 32767,
.default_value = 0,
- },
- [PVR2_CID_BASS] = {
- .id = V4L2_CID_AUDIO_BASS,
- .is_valid = !0,
+ DEFREF(balance),
+ DEFINT(-32768,32767),
+ },{
+ .v4l_id = V4L2_CID_AUDIO_BASS,
.desc = "Bass",
.name = "bass",
- .min_value = -32768,
- .max_value = 32767,
.default_value = 0,
- },
- [PVR2_CID_TREBLE] = {
- .id = V4L2_CID_AUDIO_TREBLE,
- .is_valid = !0,
+ DEFREF(bass),
+ DEFINT(-32768,32767),
+ },{
+ .v4l_id = V4L2_CID_AUDIO_TREBLE,
.desc = "Treble",
.name = "treble",
- .min_value = -32768,
- .max_value = 32767,
.default_value = 0,
- },
- [PVR2_CID_MUTE] = {
- .id = V4L2_CID_AUDIO_MUTE,
- .is_valid = !0,
+ DEFREF(treble),
+ DEFINT(-32768,32767),
+ },{
+ .v4l_id = V4L2_CID_AUDIO_MUTE,
.desc = "Mute",
.name = "mute",
- .min_value = 0,
- .max_value = 1,
.default_value = 0,
- },
- [PVR2_CID_SRATE] = {
- .id = V4L2_CID_PVR_SRATE,
- .is_valid = !0,
+ DEFREF(mute),
+ DEFINT(0,1),
+ },{
+ .v4l_id = V4L2_CID_PVR_SRATE,
.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] = {
- .id = V4L2_CID_PVR_AUDIOBITRATE,
- .is_valid = !0,
+ DEFREF(srate),
+ DEFENUM(control_values_srate),
+ },{
+ .v4l_id = V4L2_CID_PVR_AUDIOBITRATE,
.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] = {
- .id = V4L2_CID_PVR_AUDIOCRC,
- .is_valid = !0,
+ DEFREF(audiobitrate),
+ DEFENUM(control_values_audiobitrate),
+ },{
+ .v4l_id = V4L2_CID_PVR_AUDIOCRC,
.desc = "Audio CRC",
.name = "audio_crc",
- .min_value = 0,
- .max_value = 1,
.default_value = 1,
- },
- [PVR2_CID_AUDIOEMPHASIS] = {
- .id = V4L2_CID_PVR_AUDIOEMPHASIS,
- .is_valid = !0,
+ DEFREF(audiocrc),
+ DEFINT(0,1),
+ },{
+ .desc = "Audio Layer",
+ .name = "audio_layer",
+ .default_value = 2,
+ DEFREF(audiolayer),
+ DEFINT(0,3),
+ },{
+ .v4l_id = V4L2_CID_PVR_AUDIOEMPHASIS,
.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] = {
- .id = V4L2_CID_PVR_VBR,
- .is_valid = !0,
+ DEFREF(audioemphasis),
+ DEFENUM(control_values_audioemphasis),
+ },{
+ .desc = "Interlace mode",
+ .name = "interlace",
+ .internal_id = PVR2_CID_INTERLACE,
+ .default_value = 0,
+ DEFREF(interlace),
+ DEFINT(0,1),
+ },{
+ .v4l_id = V4L2_CID_PVR_VBR,
.desc = "Variable video bitrate",
.name = "vbr",
- .min_value = 0,
- .max_value = 1,
.default_value = 0,
- },
- [PVR2_CID_AVERAGEVIDEOBITRATE] = {
- .id = V4L2_CID_PVR_VIDEOBITRATE,
- .is_valid = !0,
+ DEFREF(vbr),
+ DEFINT(0,1),
+ },{
+ .v4l_id = V4L2_CID_PVR_VIDEOBITRATE,
.desc = "Average video bitrate",
.name = "video_average_bitrate",
- .min_value = 1,
- .max_value = 20000000,
.default_value = 6000000,
- },
- [PVR2_CID_PEAKVIDEOBITRATE] = {
- .id = V4L2_CID_PVR_VIDEOPEAK,
- .is_valid = !0,
+ DEFREF(videobitrate),
+ DEFINT(500000,20000000),
+ },{
+ .v4l_id = V4L2_CID_PVR_VIDEOPEAK,
.desc = "Peak video bitrate",
.name = "video_peak_bitrate",
- .min_value = 1,
- .max_value = 20000000,
.default_value = 6000000,
- },
- [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] = {
- .id = V4L2_CID_PVR_INPUT,
- .is_valid = !0,
+ DEFREF(videopeak),
+ DEFINT(500000,20000000),
+ },{
.desc = "Video Source",
.name = "input",
- .min_value = PVR2_CVAL_INPUT_MIN,
- .max_value = PVR2_CVAL_INPUT_MAX,
+ .internal_id = PVR2_CID_INPUT,
.default_value = PVR2_CVAL_INPUT_TV,
- VDEF(control_values_input),
- },
- [PVR2_CID_AUDIOMODE] = {
- .id = V4L2_CID_PVR_AUDIOMODE,
- .is_valid = !0,
+ DEFREF(input),
+ DEFENUM(control_values_input),
+ },{
.desc = "Audio Mode",
.name = "audio_mode",
- .min_value = V4L2_TUNER_MODE_MONO,
- .max_value = V4L2_TUNER_MODE_LANG1_LANG2,
+ .internal_id = PVR2_CID_AUDIOMODE,
.default_value = V4L2_TUNER_MODE_STEREO,
- VDEF(control_values_audiomode),
- },
- [PVR2_CID_FREQUENCY] = {
- .id = V4L2_CID_PVR_FREQUENCY,
- .is_valid = !0,
+ DEFREF(audiomode),
+ DEFENUM(control_values_audiomode),
+ },{
.desc = "Tuner Frequency (Hz)",
.name = "frequency",
- .min_value = 55250000L,
- .max_value = 850000000L,
+ .internal_id = PVR2_CID_FREQUENCY,
.default_value = 175250000L,
- },
- [PVR2_CID_HRES] = {
- .id = V4L2_CID_PVR_HRES,
- .is_valid = !0,
+ .set_value = ctrl_freq_set,
+ .get_value = ctrl_freq_get,
+ .is_dirty = ctrl_freq_is_dirty,
+ .clear_dirty = ctrl_freq_clear_dirty,
+ DEFINT(MIN_FREQ,MAX_FREQ),
+ },{
+ .desc = "Channel",
+ .name = "channel",
+ .set_value = ctrl_channel_set,
+ .get_value = ctrl_channel_get,
+ DEFINT(0,FREQTABLE_SIZE),
+ },{
+ .desc = "Channel Program Frequency",
+ .name = "freq_table_value",
+ .set_value = ctrl_channelfreq_set,
+ .get_value = ctrl_channelfreq_get,
+ DEFINT(MIN_FREQ,MAX_FREQ),
+ },{
+ .desc = "Channel Program ID",
+ .name = "freq_table_channel",
+ .set_value = ctrl_channelprog_set,
+ .get_value = ctrl_channelprog_get,
+ DEFINT(0,FREQTABLE_SIZE),
+ },{
.desc = "Horizontal capture resolution",
.name = "resolution_hor",
- .min_value = 320,
- .max_value = 720,
+ .internal_id = PVR2_CID_HRES,
.default_value = 720,
- },
- [PVR2_CID_VRES] = {
- .id = V4L2_CID_PVR_VRES,
- .is_valid = !0,
+ DEFREF(res_hor),
+ DEFINT(320,720),
+ },{
.desc = "Vertical capture resolution",
.name = "resolution_ver",
- .min_value = 200,
- .max_value = 625,
+ .internal_id = PVR2_CID_VRES,
.default_value = 480,
- },
- [PVR2_CID_INTERLACE] = {
- .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] = {
- .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] = {
- .is_valid = !0,
- .desc = "Channel",
- .name = "channel",
- .min_value = 0,
- .max_value = FREQTABLE_SIZE,
- .default_value = 0,
- },
- [PVR2_CID_CHANPROG_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] = {
- .is_valid = !0,
- .desc = "Channel Program Frequency",
- .name = "freq_table_value",
- .min_value = 55250000L,
- .max_value = 850000000L,
- .skip_init = !0,
- .set_func = pvr2_ctl_set_chanprog_id,
- .get_func = pvr2_ctl_get_chanprog_id,
- },
- [PVR2_CID_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] = {
- .is_valid = !0,
+ DEFREF(res_ver),
+ DEFINT(200,625),
+ },{
.desc = "Streaming Enabled",
.name = "streaming_enabled",
- .min_value = 0,
- .max_value = 1,
- .get_func = pvr2_ctl_get_streaming,
- },
- [PVR2_CID_HSM] = {
- .is_valid = !0,
+ .get_value = ctrl_streamingenabled_get,
+ DEFINT(0,1),
+ },{
.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] = {
- .is_valid = !0,
+ .get_value = ctrl_hsm_get,
+ DEFENUM(control_values_hsm),
+ },{
+ .desc = "Signal Present",
+ .name = "signal_present",
+ .get_value = ctrl_signal_get,
+ DEFINT(0,1),
+ },{
+ .desc = "Video Standards Available Mask",
+ .name = "video_standard_mask_available",
+ .internal_id = PVR2_CID_STDAVAIL,
+ .skip_init = !0,
+ .get_value = ctrl_stdavail_get,
+ .set_value = ctrl_stdavail_set,
+ .val_to_sym = ctrl_std_val_to_sym,
+ .sym_to_val = ctrl_std_sym_to_val,
+ .type = pvr2_ctl_bitmask,
+ },{
+ .desc = "Video Standards In Use Mask",
+ .name = "video_standard_mask_active",
+ .internal_id = PVR2_CID_STDCUR,
+ .skip_init = !0,
+ .get_value = ctrl_stdcur_get,
+ .set_value = ctrl_stdcur_set,
+ .is_dirty = ctrl_stdcur_is_dirty,
+ .clear_dirty = ctrl_stdcur_clear_dirty,
+ .val_to_sym = ctrl_std_val_to_sym,
+ .sym_to_val = ctrl_std_sym_to_val,
+ .type = pvr2_ctl_bitmask,
+ },{
.desc = "Subsystem enabled mask",
.name = "debug_subsys_mask",
- .min_value = 0,
- .max_value = 0x7fffffff,
.skip_init = !0,
- .get_func = pvr2_ctl_get_subsys_mask,
- .set_func = pvr2_ctl_set_subsys_mask,
- },
- [PVR2_CID_SUBSYS_STREAM_MASK] = {
- .is_valid = !0,
+ .get_value = ctrl_subsys_get,
+ .set_value = ctrl_subsys_set,
+ DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
+ },{
.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),
- },
+ .get_value = ctrl_subsys_stream_get,
+ .set_value = ctrl_subsys_stream_set,
+ DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
+ },{
+ .desc = "Video Standard Name",
+ .name = "video_standard",
+ .internal_id = PVR2_CID_STDENUM,
+ .skip_init = !0,
+ .get_value = ctrl_stdenumcur_get,
+ .set_value = ctrl_stdenumcur_set,
+ .is_dirty = ctrl_stdenumcur_is_dirty,
+ .clear_dirty = ctrl_stdenumcur_clear_dirty,
+ .type = pvr2_ctl_enum,
+ }
};
-#undef VDEF
+#define CTRL_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
-#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)
{
@@ -634,10 +853,7 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
"v4l-pvrusb2-24xxx-01.fw",
};
#endif
- static const struct {
- const char **lst;
- unsigned int cnt;
- } fw_file_defs[] = {
+ static const struct pvr2_string_table fw_file_defs[] = {
[PVR2_HDW_TYPE_29XXX] = {
fw_files_29xxx,
sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
@@ -825,17 +1041,17 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"firmware2 upload post-proc failure");
} else {
- hdw->subsys_enabled_mask |= PVR2_SUBSYS_ENC_FIRMWARE;
+ hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
}
return ret;
}
#define FIRMWARE_RECOVERY_BITS \
- (PVR2_SUBSYS_ENC_CFG | \
- PVR2_SUBSYS_ENC_RUN | \
- PVR2_SUBSYS_ENC_FIRMWARE | \
- PVR2_SUBSYS_USBSTREAM_RUN)
+ ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
+ (1<<PVR2_SUBSYS_B_ENC_RUN) | \
+ (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
+ (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
/*
@@ -903,7 +1119,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
hdw->subsys_enabled_mask;
if (vmsk) {
- if (vmsk & PVR2_SUBSYS_ENC_RUN) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" pvr2_encoder_stop");
@@ -916,13 +1132,13 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
continue;
}
}
- if (vmsk & PVR2_SUBSYS_USBSTREAM_RUN) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" pvr2_hdw_cmd_usbstream(0)");
pvr2_hdw_cmd_usbstream(hdw,0);
}
- if (vmsk & PVR2_SUBSYS_DIGITIZER_RUN) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" decoder disable");
@@ -935,7 +1151,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
" No decoder present");
}
hdw->subsys_enabled_mask &=
- ~PVR2_SUBSYS_DIGITIZER_RUN;
+ ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
}
if (vmsk & PVR2_SUBSYS_CFG_ALL) {
hdw->subsys_enabled_mask &=
@@ -944,7 +1160,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
}
vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
if (vmsk) {
- if (vmsk & PVR2_SUBSYS_ENC_FIRMWARE) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" pvr2_upload_firmware2");
@@ -957,7 +1173,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
break;
}
}
- if (vmsk & PVR2_SUBSYS_ENC_CFG) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" pvr2_encoder_configure");
@@ -970,7 +1186,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
continue;
}
}
- if (vmsk & PVR2_SUBSYS_DIGITIZER_RUN) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" decoder enable");
@@ -983,15 +1199,15 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
" No decoder present");
}
hdw->subsys_enabled_mask |=
- PVR2_SUBSYS_DIGITIZER_RUN;
+ (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
}
- if (vmsk & PVR2_SUBSYS_USBSTREAM_RUN) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" pvr2_hdw_cmd_usbstream(1)");
pvr2_hdw_cmd_usbstream(hdw,!0);
}
- if (vmsk & PVR2_SUBSYS_ENC_RUN) {
+ if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
pvr2_trace(PVR2_TRACE_CTL,
"/*---TRACE_CTL----*/"
" pvr2_encoder_start");
@@ -1066,12 +1282,6 @@ void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
}
-static int pvr2_ctl_get_streaming(struct pvr2_ctrl *cptr)
-{
- return cptr->hdw->flag_streaming_enabled != 0;
-}
-
-
int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
{
if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
@@ -1142,6 +1352,17 @@ static int get_default_tuner_type(struct pvr2_hdw *hdw)
}
+static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
+{
+ int unit_number = hdw->unit_number;
+ int tp = 0;
+ if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
+ tp = video_std[unit_number];
+ }
+ return tp;
+}
+
+
static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
{
int unit_number = hdw->unit_number;
@@ -1178,6 +1399,59 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
return result == 0;
}
+static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
+{
+ char buf[40];
+ unsigned int bcnt;
+ v4l2_std_id std1,std2;
+
+ std1 = get_default_standard(hdw);
+
+ bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Supported video standard(s) reported by eeprom: %.*s",
+ bcnt,buf);
+
+ hdw->std_mask_avail = hdw->std_mask_eeprom;
+
+ std2 = std1 & ~hdw->std_mask_avail;
+ if (std2) {
+ bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Expanding supported video standards"
+ " to include: %.*s",
+ bcnt,buf);
+ hdw->std_mask_avail |= std2;
+ }
+
+ pvr2_hdw_internal_set_std_avail(hdw);
+
+ if (std1) {
+ bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Initial video standard forced to %.*s",
+ bcnt,buf);
+ hdw->std_mask_cur = std1;
+ hdw->std_dirty = !0;
+ pvr2_hdw_internal_find_stdenum(hdw);
+ return;
+ }
+
+ if (hdw->std_enum_cnt > 1) {
+ // Autoselect the first listed standard
+ hdw->std_enum_cur = 1;
+ hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
+ hdw->std_dirty = !0;
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Initial video standard auto-selected to %s",
+ hdw->std_defs[hdw->std_enum_cur-1].name);
+ return;
+ }
+
+ pvr2_trace(PVR2_TRACE_EEPROM,
+ "Unable to select a viable initial video standard");
+}
+
static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
{
@@ -1216,6 +1490,10 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
}
if (!pvr2_hdw_dev_ok(hdw)) return;
+ for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
+ request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
+ }
+
pvr2_hdw_cmd_powerup(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -1231,10 +1509,9 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
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);
+ if (cptr->info->skip_init) continue;
+ if (!cptr->info->set_value) continue;
+ cptr->info->set_value(cptr,~0,cptr->info->default_value);
}
// Do not use pvr2_reset_ctl_endpoints() here. It is not
@@ -1252,6 +1529,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
if (!pvr2_hdw_dev_ok(hdw)) return;
}
+ pvr2_hdw_setup_std(hdw);
+
if (!get_default_tuner_type(hdw)) {
pvr2_trace(PVR2_TRACE_INIT,
"pvr2_hdw_setup: Tuner type overridden to %d",
@@ -1264,23 +1543,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
if (!pvr2_hdw_dev_ok(hdw)) return;
- 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);
if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -1384,6 +1646,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
unsigned int idx,cnt1,cnt2;
struct pvr2_hdw *hdw;
unsigned int hdw_type;
+ int valid_std_mask;
+ struct pvr2_ctrl *cptr;
__u8 ifnum;
hdw_type = devid - pvr2_device_table;
@@ -1400,33 +1664,60 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
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;
+ for (idx = 0; idx < 32; idx++) {
+ hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
+ }
+
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ cptr->hdw = hdw;
+ cptr->info = control_defs+idx;
+ }
+
+ // Initialize video standard enum dynamic control
+ cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
+ if (cptr) {
+ memcpy(&hdw->std_info_enum,cptr->info,
+ sizeof(hdw->std_info_enum));
+ cptr->info = &hdw->std_info_enum;
+
+ }
+ // Initialize control data regarding video standard masks
+ valid_std_mask = pvr2_std_get_usable();
+ for (idx = 0; idx < 32; idx++) {
+ if (!(valid_std_mask & (1 << idx))) continue;
+ cnt1 = pvr2_std_id_to_str(
+ hdw->std_mask_names[idx],
+ sizeof(hdw->std_mask_names[idx])-1,
+ 1 << idx);
+ hdw->std_mask_names[idx][cnt1] = 0;
+ }
+ cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
+ if (cptr) {
+ memcpy(&hdw->std_info_avail,cptr->info,
+ sizeof(hdw->std_info_avail));
+ cptr->info = &hdw->std_info_avail;
+ hdw->std_info_avail.def.type_bitmask.bit_names =
+ hdw->std_mask_ptrs;
+ hdw->std_info_avail.def.type_bitmask.valid_bits =
+ valid_std_mask;
+ }
+ cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
+ if (cptr) {
+ memcpy(&hdw->std_info_cur,cptr->info,
+ sizeof(hdw->std_info_cur));
+ cptr->info = &hdw->std_info_cur;
+ hdw->std_info_cur.def.type_bitmask.bit_names =
+ hdw->std_mask_ptrs;
+ hdw->std_info_avail.def.type_bitmask.valid_bits =
+ valid_std_mask;
}
- 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;
@@ -1468,7 +1759,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
/* Initialize the mask of subsystems that we will shut down when we
stop streaming. */
hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
- hdw->subsys_stream_mask |= PVR2_SUBSYS_ENC_CFG;
+ hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
hdw->subsys_stream_mask);
@@ -1556,7 +1847,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
} 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);
+ if (hdw->std_enum_names) kfree(hdw->std_enum_names);
kfree(hdw);
}
@@ -1585,363 +1876,75 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
}
-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;
- if (hdw->controls[PVR2_CID_CHANNEL].value == id) {
- /* If the current channel happens to be the slot we just
- set, then act like the current channel just got changed
- so we'll update that too. */
- hdw->controls[PVR2_CID_CHANNEL].dirty = !0;
- }
- return 0;
-}
-
-
-static int pvr2_ctl_get_chanprog_id(struct pvr2_ctrl *cptr)
+// Attempt to autoselect an appropriate value for std_enum_cur given
+// whatever is currently in std_mask_cur
+void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
{
- /* 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]))
-
-
-struct name_data {
- struct v4l2_standard *std;
- unsigned int bcnt;
- unsigned int scnt;
-};
-
-static void name_build(struct name_data *dp,const char *str)
-{
- if (!dp->bcnt) {
- dp->bcnt = scnprintf(dp->std->name,
- sizeof(dp->std->name)-1,"%s",str);
- dp->scnt = 0;
- return;
- }
-
- 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;
+ unsigned int idx;
+ for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
+ if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
+ hdw->std_enum_cur = idx;
+ return;
+ }
}
- std->name[0] = 0;
+ hdw->std_enum_cur = 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)
+// Calculate correct set of enumerated standards based on currently known
+// set of available standards bits.
+void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
{
- 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++;
- }
+ struct v4l2_standard *newstd;
+ unsigned int std_cnt;
+ unsigned int idx;
- if (amsk) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Failed to bucketize the following standards: 0x%llx",
- amsk);
- }
+ newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
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_enum_cnt = 0;
+ if (hdw->std_enum_names) {
+ kfree(hdw->std_enum_names);
+ hdw->std_enum_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++;
- }
-
- // 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);
- }
-}
-
-
-unsigned int pvr2_hdw_get_stdenum_count(struct pvr2_hdw *hdw)
-{
- 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;
+ "WARNING: Failed to identify any viable standards");
}
-
- // 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;
- }
+ hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
+ hdw->std_enum_names[0] = "none";
+ for (idx = 0; idx < std_cnt; idx++) {
+ hdw->std_enum_names[idx+1] =
+ newstd[idx].name;
}
-
- // Should never really get here, but just in case...
- hdw->std_id = 0;
+ // Set up the dynamic control for this standard
+ hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
+ hdw->std_info_enum.def.type_enum.count = std_cnt+1;
+ hdw->std_defs = newstd;
+ hdw->std_enum_cnt = std_cnt+1;
+ hdw->std_enum_cur = 0;
+ hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
}
-static int pvr2_ctl_set_stdcur(struct pvr2_ctrl *cptr,int val)
+int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
+ struct v4l2_standard *std,
+ unsigned int idx)
{
- 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);
+ int ret = -EINVAL;
+ if (!idx) return ret;
+ LOCK_TAKE(hdw->big_lock); do {
+ if (idx >= hdw->std_enum_cnt) break;
+ idx--;
+ memcpy(std,hdw->std_defs+idx,sizeof(*std));
+ ret = 0;
+ } while (0); LOCK_GIVE(hdw->big_lock);
+ return ret;
}
@@ -1956,14 +1959,14 @@ unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
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;
}
-/* 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)
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
+ unsigned int ctl_id)
{
struct pvr2_ctrl *cptr;
unsigned int idx;
@@ -1972,212 +1975,38 @@ struct pvr2_ctrl *pvr2_hdw_get_ctrl(struct pvr2_hdw *hdw,unsigned int ctl_id)
/* 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;
+ i = cptr->info->internal_id;
if (i && (i == ctl_id)) return cptr;
}
-
return 0;
}
-/* 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 (!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 (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 ((cptr->value != value) || (ctlchg != 0)) {
- cptr->value = value;
- cptr->dirty = !0;
- }
- return 0;
-}
-
-
-/* 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;
- 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;
-}
-
-
-/* Get the current value of the given control. */
-int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr)
+/* Given an ID, retrieve the control structure associated with it. */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
{
- 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;
-}
-
+ struct pvr2_ctrl *cptr;
+ unsigned int idx;
+ int i;
-/* Return the type of the given control (int, enum, or bit mask). */
-int pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
-{
- 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;
+ /* This could be made a lot more efficient, but for now... */
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ i = cptr->info->v4l_id;
+ if (i && (i == ctl_id)) return cptr;
}
- 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 0;
}
-/* 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)
+static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
{
- 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];
+ switch (tp) {
+ case pvr2_ctl_int: return "integer";
+ case pvr2_ctl_enum: return "enum";
+ case pvr2_ctl_bitmask: return "bitmask";
}
- return 0;
+ return "";
}
@@ -2193,64 +2022,33 @@ 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;
int commit_flag = 0;
-
- /* Let's see if the channel changed and we have to update the
- frequency because of it. This setup means one can tune the
- receiver either by just setting the channel (using the frequency
- table), or by directly programming the frequency. How do we
- resolve the obvious conflict here? The direct frequency takes
- priority; if directly set then we commit that value and force
- the channel to zero which is interpreted to mean "none". If on
- the other hand we see that the channel has been set and it's a
- legal value, then we copy that into the frequency. The metaphor
- here is similar to when you tune your digital radio: You an
- either set a frequency directly or punch up a pre-programmed
- station. Either way a frequency is set, and if you do use a
- preset, then the radio also shows you which preset it is - until
- you override that by directly entering a new frequency. */
- if (hdw->controls[PVR2_CID_FREQUENCY].dirty) {
- /* Frequency has been directly set, so clear out the
- channel. */
- hdw->controls[PVR2_CID_CHANNEL].value = 0;
- } else if (hdw->controls[PVR2_CID_CHANNEL].dirty) {
- int id = hdw->controls[PVR2_CID_CHANNEL].value;
- if ((id > 0) && (id <= FREQTABLE_SIZE)) {
- if (hdw->controls[PVR2_CID_FREQUENCY].value !=
- hdw->freqTable[id-1]) {
- hdw->controls[PVR2_CID_FREQUENCY].value =
- hdw->freqTable[id-1];
- hdw->controls[PVR2_CID_FREQUENCY].dirty = !0;
- }
- }
- }
+ char buf[100];
+ unsigned int bcnt,ccnt;
for (idx = 0; idx < CTRL_COUNT; idx++) {
cptr = hdw->controls + idx;
- if (!cptr->dirty) continue;
+ if (cptr->info->is_dirty == 0) continue;
+ if (!cptr->info->is_dirty(cptr)) continue;
if (!commit_flag) {
commit_flag = !0;
}
- 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>";
- }
- } else {
- ctl_value = "<integer>";
- }
+
+ bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
+ cptr->info->name);
+ value = 0;
+ cptr->info->get_value(cptr,&value);
+ pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
+ buf+bcnt,
+ sizeof(buf)-bcnt,&ccnt);
+ bcnt += ccnt;
+ bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
+ get_ctrl_typename(cptr->info->type));
pvr2_trace(PVR2_TRACE_CTL,
- "/*--TRACE_COMMIT--*/ \"%s\" <-- %d (%s)",
- ctl_name,value,ctl_value);
+ "/*--TRACE_COMMIT--*/ %.*s",
+ bcnt,buf);
}
if (!commit_flag) {
@@ -2261,40 +2059,40 @@ 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_STDCUR].dirty) {
+ if (hdw->std_dirty) {
/* Rewrite the vertical resolution to be appropriate to the
video standard that has been selected. */
int nvres;
- if (hdw->video_std_cur & V4L2_STD_525_60) {
+ if (hdw->std_mask_cur & V4L2_STD_525_60) {
nvres = 480;
} else {
nvres = 576;
}
- if (nvres != hdw->controls[PVR2_CID_VRES].value) {
- hdw->controls[PVR2_CID_VRES].value = nvres;
- hdw->controls[PVR2_CID_VRES].dirty = !0;
+ if (nvres != hdw->res_ver_val) {
+ hdw->res_ver_val = nvres;
+ hdw->res_ver_dirty = !0;
}
- if (!hdw->controls[PVR2_CID_INTERLACE].value) {
- hdw->controls[PVR2_CID_INTERLACE].value = 0;
- hdw->controls[PVR2_CID_INTERLACE].dirty = !0;
+ if (!hdw->interlace_val) {
+ hdw->interlace_val = 0;
+ hdw->interlace_dirty = !0;
}
}
- 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 ||
- hdw->controls[PVR2_CID_VBR].dirty ||
- hdw->controls[PVR2_CID_AVERAGEVIDEOBITRATE].dirty ||
- hdw->controls[PVR2_CID_PEAKVIDEOBITRATE].dirty ||
- hdw->controls[PVR2_CID_AUDIOBITRATE].dirty ||
- hdw->controls[PVR2_CID_SRATE].dirty ||
- hdw->controls[PVR2_CID_AUDIOLAYER].dirty ||
- hdw->controls[PVR2_CID_AUDIOCRC].dirty ||
- hdw->controls[PVR2_CID_AUDIOEMPHASIS].dirty) {
+ if (hdw->std_dirty ||
+ hdw->res_ver_dirty ||
+ hdw->res_hor_dirty ||
+ hdw->interlace_dirty ||
+ hdw->vbr_dirty ||
+ hdw->videobitrate_dirty ||
+ hdw->videopeak_dirty ||
+ hdw->audiobitrate_dirty ||
+ hdw->srate_dirty ||
+ hdw->audiolayer_dirty ||
+ hdw->audiocrc_dirty ||
+ hdw->audioemphasis_dirty) {
/* If any of this changes, then the encoder needs to be
reconfigured, and we need to reset the stream. */
- stale_subsys_mask |= PVR2_SUBSYS_ENC_CFG;
+ stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
stale_subsys_mask |= hdw->subsys_stream_mask;
}
@@ -2306,7 +2104,8 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
for (idx = 0; idx < CTRL_COUNT; idx++) {
cptr = hdw->controls + idx;
- cptr->dirty = 0;
+ if (!cptr->info->clear_dirty) continue;
+ cptr->info->clear_dirty(cptr);
}
/* Now execute i2c core update */
@@ -2374,7 +2173,7 @@ const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
{
unsigned int msk = 0;
- switch (hdw->controls[PVR2_CID_INPUT].value) {
+ switch (hdw->input_val) {
case PVR2_CVAL_INPUT_TV:
case PVR2_CVAL_INPUT_RADIO:
if (hdw->decoder_ctrl &&
@@ -2398,42 +2197,6 @@ unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr)
-{
- return cptr->hdw->subsys_enabled_mask;
-}
-
-
-static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val)
-{
- pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,~0,val);
- return 0;
-}
-
-
-static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr)
-{
- return cptr->hdw->subsys_stream_mask;
-}
-
-
-static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr,
- int val)
-{
- pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,~0,val);
- return 0;
-}
-
-
-static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr)
-{
- 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;
-}
-
-
int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
{
int result;
@@ -2449,13 +2212,6 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr)
-{
- return ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
- PVR2_SIGNAL_OK) ? 1 : 0);
-}
-
-
/* Return bit mask indicating signal status */
unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw)
{
@@ -3124,8 +2880,8 @@ int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
if (!status) {
hdw->subsys_enabled_mask =
((hdw->subsys_enabled_mask &
- ~PVR2_SUBSYS_USBSTREAM_RUN) |
- (runFl ? PVR2_SUBSYS_USBSTREAM_RUN : 0));
+ ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
+ (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
}
return status;
}