From f44c0bc49cbb5ee3bd7d89c602873840d40c8b25 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 26 Mar 2006 15:45:31 -0600 Subject: Get rid of static PVR2_CID_COUNT in pvrusb2 From: Mike Isely Eliminate the need to track the number pvrusb2 CIDs at compile time from within the pvrusb2 driver. This is part of a control structure cleanup. Signed-off-by: Mike Isely --- .../media/video/pvrusb2/pvrusb2-hdw-internal.h | 2 +- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 80 ++++++++++++++++++---- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 6 +- linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 2 +- 4 files changed, 73 insertions(+), 17 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 05e44385b..25854375b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -211,7 +211,7 @@ 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_ctl_state *controls; }; int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw, diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index ec2b5eeae..81a35a8e2 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -97,6 +97,7 @@ struct pvr2_ctl_def { int min_value; int skip_init; int default_value; + int is_valid; const char **value_defs_ptr; unsigned int value_defs_count; }; @@ -184,63 +185,73 @@ 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 struct pvr2_ctl_def control_defs[] = { [PVR2_CID_BRIGHTNESS] = { + .is_valid = !0, .name = "Brightness", .min_value = 0, .max_value = 255, .default_value = 128, }, [PVR2_CID_CONTRAST] = { + .is_valid = !0, .name = "Contrast", .min_value = 0, .max_value = 127, .default_value = 68, }, [PVR2_CID_SATURATION] = { + .is_valid = !0, .name = "Saturation", .min_value = 0, .max_value = 127, .default_value = 64, }, [PVR2_CID_HUE] = { + .is_valid = !0, .name = "Hue", .min_value = -128, .max_value = 127, .default_value = 0, }, [PVR2_CID_VOLUME] = { + .is_valid = !0, .name = "Volume", .min_value = 0, .max_value = 65535, .default_value = 65535, }, [PVR2_CID_BALANCE] = { + .is_valid = !0, .name = "Balance", .min_value = -32768, .max_value = 32767, .default_value = 0, }, [PVR2_CID_BASS] = { + .is_valid = !0, .name = "Bass", .min_value = -32768, .max_value = 32767, .default_value = 0, }, [PVR2_CID_TREBLE] = { + .is_valid = !0, .name = "Treble", .min_value = -32768, .max_value = 32767, .default_value = 0, }, [PVR2_CID_MUTE] = { + .is_valid = !0, .name = "Mute", .min_value = 0, .max_value = 1, .default_value = 0, }, [PVR2_CID_SRATE] = { + .is_valid = !0, .name = "Sample rate", .min_value = PVR2_CVAL_SRATE_MIN, .max_value = PVR2_CVAL_SRATE_MAX, @@ -248,6 +259,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = VDEF(control_values_srate), }, [PVR2_CID_AUDIOBITRATE] = { + .is_valid = !0, .name = "Audio Bitrate", .min_value = PVR2_CVAL_AUDIOBITRATE_MIN, .max_value = PVR2_CVAL_AUDIOBITRATE_MAX, @@ -255,12 +267,14 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = VDEF(control_values_audiobitrate), }, [PVR2_CID_AUDIOCRC] = { + .is_valid = !0, .name = "Audio CRC", .min_value = 0, .max_value = 1, .default_value = 1, }, [PVR2_CID_AUDIOEMPHASIS] = { + .is_valid = !0, .name = "Audio Emphasis", .min_value = PVR2_CVAL_AUDIOEMPHASIS_MIN, .max_value = PVR2_CVAL_AUDIOEMPHASIS_MAX, @@ -268,24 +282,28 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = VDEF(control_values_audioemphasis), }, [PVR2_CID_VBR] = { + .is_valid = !0, .name = "Variable video bitrate", .min_value = 0, .max_value = 1, .default_value = 0, }, [PVR2_CID_AVERAGEVIDEOBITRATE] = { + .is_valid = !0, .name = "Average video bitrate", .min_value = 1, .max_value = 20000000, .default_value = 6000000, }, [PVR2_CID_PEAKVIDEOBITRATE] = { + .is_valid = !0, .name = "Peak video bitrate", .min_value = 1, .max_value = 20000000, .default_value = 6000000, }, [PVR2_CID_VIDEOSTANDARD] = { + .is_valid = !0, .name = "Video Standard", .min_value = PVR2_CVAL_VIDEOSTANDARD_MIN, .max_value = PVR2_CVAL_VIDEOSTANDARD_MAX, @@ -293,6 +311,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = VDEF(control_values_videostandard), }, [PVR2_CID_INPUT] = { + .is_valid = !0, .name = "Video Source", .min_value = PVR2_CVAL_INPUT_MIN, .max_value = PVR2_CVAL_INPUT_MAX, @@ -300,6 +319,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = VDEF(control_values_input), }, [PVR2_CID_AUDIOMODE] = { + .is_valid = !0, .name = "Audio Mode", .min_value = PVR2_CVAL_AUDIOMODE_MIN, .max_value = PVR2_CVAL_AUDIOMODE_MAX, @@ -307,48 +327,56 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = VDEF(control_values_audiomode), }, [PVR2_CID_FREQUENCY] = { + .is_valid = !0, .name = "Tuner Frequency (Hz)", .min_value = 55250000L, .max_value = 850000000L, .default_value = 175250000L, }, [PVR2_CID_HRES] = { + .is_valid = !0, .name = "Horizontal capture resolution", .min_value = 320, .max_value = 720, .default_value = 720, }, [PVR2_CID_VRES] = { + .is_valid = !0, .name = "Vertical capture resolution", .min_value = 200, .max_value = 625, .default_value = 480, }, [PVR2_CID_INTERLACE] = { + .is_valid = !0, .name = "Interlace mode", .min_value = 0, .max_value = 1, .default_value = 0, }, [PVR2_CID_AUDIOLAYER] = { + .is_valid = !0, .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, .name = "Channel", .min_value = 0, .max_value = FREQTABLE_SIZE, .default_value = 0, }, [PVR2_CID_CHANPROG_ID] = { + .is_valid = !0, .name = "Channel Program ID", .min_value = 0, .max_value = FREQTABLE_SIZE, .default_value = 0, }, [PVR2_CID_CHANPROG_FREQ] = { + .is_valid = !0, .name = "Channel Program Frequency", .min_value = 55250000L, .max_value = 850000000L, @@ -357,18 +385,21 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = .get_func = pvr2_ctl_get_chanprog_id, }, [PVR2_CID_SIGNAL_PRESENT] = { + .is_valid = !0, .name = "Signal Present", .min_value = 0, .max_value = 1, .get_func = pvr2_ctl_get_signal, }, [PVR2_CID_STREAMING_ENABLED] = { + .is_valid = !0, .name = "Streaming Enabled", .min_value = 0, .max_value = 1, .get_func = pvr2_ctl_get_streaming, }, [PVR2_CID_HSM] = { + .is_valid = !0, .name = "USB Speed", .min_value = PVR2_CVAL_HSM_MIN, .max_value = PVR2_CVAL_HSM_MAX, @@ -376,6 +407,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = VDEF(control_values_hsm), }, [PVR2_CID_SUBSYS_MASK] = { + .is_valid = !0, .name = "Subsystem enabled mask", .min_value = 0, .max_value = 0x7fffffff, @@ -384,6 +416,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = .set_func = pvr2_ctl_set_subsys_mask, }, [PVR2_CID_SUBSYS_STREAM_MASK] = { + .is_valid = !0, .name = "Subsystem stream mask", .min_value = 0, .max_value = 0x7fffffff, @@ -395,6 +428,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = #undef VDEF +#define CTRL_COUNT (sizeof(control_defs)/sizeof(control_defs[0])) const char *pvr2_config_get_name(enum pvr2_config cfg) { @@ -1106,7 +1140,7 @@ 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++) { + for (idx = 0; idx < CTRL_COUNT; idx++) { if (control_defs[idx].skip_init) continue; pvr2_hdw_set_ctl_value_internal( hdw,idx,control_defs[idx].default_value); @@ -1259,6 +1293,9 @@ 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)); + hdw->controls = kmalloc(sizeof(struct pvr2_ctl_state) * CTRL_COUNT, + GFP_KERNEL); + if (!hdw->controls) goto fail; hdw->hdw_type = hdw_type; hdw->eeprom_addr = -1; @@ -1322,6 +1359,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 +1424,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) unit_pointers[hdw->unit_number] = 0; } } while (0); up(&pvr2_unit_sem); + kfree(hdw->controls); kfree(hdw); } @@ -1447,7 +1486,9 @@ int pvr2_hdw_get_ctl_value(struct pvr2_hdw *hdw,unsigned int ctl_id) { int ret = 0; - if (ctl_id >= PVR2_CID_COUNT) return 0; + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) 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); @@ -1462,7 +1503,8 @@ int pvr2_hdw_get_ctl_value(struct pvr2_hdw *hdw,unsigned int ctl_id) /* Return true if control is writable */ int pvr2_hdw_get_ctl_rw(struct pvr2_hdw *hdw,unsigned int ctl_id) { - if (ctl_id >= PVR2_CID_COUNT) return 0; + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) return 0; if (control_defs[ctl_id].get_func && !control_defs[ctl_id].set_func) { return 0; } @@ -1473,7 +1515,8 @@ int pvr2_hdw_get_ctl_rw(struct pvr2_hdw *hdw,unsigned int ctl_id) /* Retrieve legal minimum value for a given control */ int pvr2_hdw_get_ctl_min_value(struct pvr2_hdw *hdw,unsigned int ctl_id) { - if (ctl_id >= PVR2_CID_COUNT) return 0; + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) return 0; return control_defs[ctl_id].min_value; } @@ -1481,7 +1524,8 @@ int pvr2_hdw_get_ctl_min_value(struct pvr2_hdw *hdw,unsigned int ctl_id) /* Retrieve legal maximum value for a given control */ int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *hdw,unsigned int ctl_id) { - if (ctl_id >= PVR2_CID_COUNT) return 0; + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) return 0; return control_defs[ctl_id].max_value; } @@ -1492,7 +1536,8 @@ int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw, unsigned int ctl_id,int value) { int ret; - if (ctl_id >= PVR2_CID_COUNT) return -EINVAL; + if (ctl_id >= CTRL_COUNT) return -EINVAL; + if (!control_defs[ctl_id].is_valid) 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) { @@ -1532,7 +1577,8 @@ const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *hdw, int value) { struct pvr2_ctl_def *cdef; - if (ctl_id >= PVR2_CID_COUNT) return 0; + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) return 0; cdef = control_defs + ctl_id; if (! cdef->value_defs_ptr) return 0; if (value >= cdef->value_defs_count) return 0; @@ -1543,11 +1589,21 @@ const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *hdw, /* Retrieve string name for given control */ const char *pvr2_hdw_get_ctl_name(struct pvr2_hdw *hdw,unsigned int ctl_id) { - if (ctl_id >= PVR2_CID_COUNT) return 0; + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) return 0; return control_defs[ctl_id].name; } +/* Return true if control ID is a valid id */ +int pvr2_hdw_get_ctl_valid(struct pvr2_hdw *hdw,unsigned int ctl_id) +{ + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) return 0; + return !0; +} + + /* Commit all control changes made up to this point. Subsystems can be indirectly affected by these changes. For a given set of things being committed, we'll clear the affected subsystem bits and then once we're @@ -1595,7 +1651,7 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) } } - for (idx = 0; idx < PVR2_CID_COUNT; idx++) { + for (idx = 0; idx < CTRL_COUNT; idx++) { if (!hdw->controls[idx].dirty) continue; if (!commit_flag) { commit_flag = !0; @@ -1671,7 +1727,7 @@ 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++) { + for (idx = 0; idx < CTRL_COUNT; idx++) { hdw->controls[idx].dirty = 0; } @@ -1733,7 +1789,7 @@ void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw) through this value. */ unsigned int pvr2_hdw_get_ctl_count(struct pvr2_hdw *hdw) { - return PVR2_CID_COUNT; + return CTRL_COUNT; } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index aa6d9029a..6cc841b56 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -59,9 +59,6 @@ #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 @@ -234,6 +231,9 @@ int pvr2_hdw_set_ctl_value(struct pvr2_hdw *,unsigned int ctl_id,int value); /* Retrieve string name for given control */ const char *pvr2_hdw_get_ctl_name(struct pvr2_hdw *,unsigned int ctl_id); +/* Return true if control id is a valid id */ +int pvr2_hdw_get_ctl_valid(struct pvr2_hdw *,unsigned int ctl_id); + /* 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 *, diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index f82fd643c..6b81def26 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -30,7 +30,7 @@ #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__) -static char *item_names[PVR2_CID_COUNT] = { +static char *item_names[] = { [PVR2_CID_BRIGHTNESS] = "ctl_brightness", [PVR2_CID_CONTRAST] = "ctl_contrast", [PVR2_CID_SATURATION] = "ctl_saturation", -- cgit v1.2.3 From da1de2e42e2a5c0290c15edbbd4017176ff0b1c2 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 26 Mar 2006 15:46:35 -0600 Subject: Propagate default control values out to V4L apps from within pvrusb2 From: Mike Isely When a V4L app queries a pvrusb2 control, make sure we also tell it what the control's default value is. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 9 +++++++++ linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 3 +++ linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 2 ++ 3 files changed, 14 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 81a35a8e2..a0b0cd8aa 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1530,6 +1530,15 @@ int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *hdw,unsigned int ctl_id) } +/* Retrieve default value for a given control */ +int pvr2_hdw_get_ctl_default_value(struct pvr2_hdw *hdw,unsigned int ctl_id) +{ + if (ctl_id >= CTRL_COUNT) return 0; + if (!control_defs[ctl_id].is_valid) return 0; + return control_defs[ctl_id].default_value; +} + + /* 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, diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 6cc841b56..d7749138c 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -224,6 +224,9 @@ int pvr2_hdw_get_ctl_min_value(struct pvr2_hdw *,unsigned int ctl_id); /* Retrieve legal maximum value for a given control */ int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *,unsigned int ctl_id); +/* Retrieve legal maximum value for a given control */ +int pvr2_hdw_get_ctl_default_value(struct pvr2_hdw *,unsigned int ctl_id); + /* 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); diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index dd207fae4..4cdd08708 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -788,6 +788,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, 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); + vc->default_value = + pvr2_hdw_get_ctl_default_value(hdw,pvr2_id); vc->step = 1; ret = 0; break; -- cgit v1.2.3 From d213c7fd61512ba8605208f6b785829ff1da017b Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Tue, 28 Mar 2006 22:05:31 -0600 Subject: Major pvrusb2 rework to remove translations From: Mike Isely Rework entire internal controls interface to eliminate the need for visibly defined control IDs which must otherwise be translated by the V4L2 public interface. As part of this work, internal structures which mimiced various V4L2 structures (video standards, audio modes) have been reworked to actually use the native structures. This triggered a _significant_ rework for how video standards are dealt with (and what is in place now should be much more flexible and forgiving for various handling less-common video standards). Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-audio.c | 23 +- linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c | 44 +- linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h | 1 - .../drivers/media/video/pvrusb2/pvrusb2-encoder.c | 12 +- .../media/video/pvrusb2/pvrusb2-hdw-internal.h | 123 ++- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 956 ++++++++++++++++----- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 199 ++--- .../media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c | 30 +- linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 120 ++- linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 402 +++------ 10 files changed, 1134 insertions(+), 776 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c index 79395d540..ae34ff9e4 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..634095efc 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c @@ -204,7 +204,7 @@ 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); @@ -222,48 +222,6 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) -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 553bd2d7b..2de5b6c8f 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 25854375b..189075bbe 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; }; @@ -191,7 +294,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 +320,17 @@ struct pvr2_hdw { struct pvr2_audio_stat *audio_stat; /* Every last bit of controllable state */ - struct pvr2_ctl_state *controls; + 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 a0b0cd8aa..585f4ee0b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "pvrusb2.h" #include "pvrusb2-util.h" @@ -86,23 +87,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; - int is_valid; - 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", @@ -136,12 +120,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", }; @@ -154,12 +161,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", }; @@ -174,210 +180,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 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, - .name = "Brightness", + .desc = "Brightness", + .name = "brightness", .min_value = 0, .max_value = 255, .default_value = 128, }, [PVR2_CID_CONTRAST] = { + .id = V4L2_CID_CONTRAST, .is_valid = !0, - .name = "Contrast", + .desc = "Contrast", + .name = "contrast", .min_value = 0, .max_value = 127, .default_value = 68, }, [PVR2_CID_SATURATION] = { + .id = V4L2_CID_SATURATION, .is_valid = !0, - .name = "Saturation", + .desc = "Saturation", + .name = "saturation", .min_value = 0, .max_value = 127, .default_value = 64, }, [PVR2_CID_HUE] = { + .id = V4L2_CID_HUE, .is_valid = !0, - .name = "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, - .name = "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, - .name = "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, - .name = "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, - .name = "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, - .name = "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, - .name = "Sample rate", + .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, - .name = "Audio Bitrate", + .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, - .name = "Audio CRC", + .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, - .name = "Audio Emphasis", + .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, - .name = "Variable video bitrate", + .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, - .name = "Average video bitrate", + .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, - .name = "Peak video bitrate", + .desc = "Peak video bitrate", + .name = "video_peak_bitrate", .min_value = 1, .max_value = 20000000, .default_value = 6000000, }, - [PVR2_CID_VIDEOSTANDARD] = { + [PVR2_CID_STDAVAIL] = { .is_valid = !0, - .name = "Video Standard", - .min_value = PVR2_CVAL_VIDEOSTANDARD_MIN, - .max_value = PVR2_CVAL_VIDEOSTANDARD_MAX, - .default_value = PVR2_CVAL_VIDEOSTANDARD_NTSC_M, + .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, - .name = "Video Source", + .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] = { + .id = V4L2_CID_PVR_AUDIOMODE, .is_valid = !0, - .name = "Audio Mode", - .min_value = PVR2_CVAL_AUDIOMODE_MIN, - .max_value = PVR2_CVAL_AUDIOMODE_MAX, - .default_value = PVR2_CVAL_AUDIOMODE_STEREO, + .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] = { + .id = V4L2_CID_PVR_FREQUENCY, .is_valid = !0, - .name = "Tuner Frequency (Hz)", + .desc = "Tuner Frequency (Hz)", + .name = "frequency", .min_value = 55250000L, .max_value = 850000000L, .default_value = 175250000L, }, [PVR2_CID_HRES] = { + .id = V4L2_CID_PVR_HRES, .is_valid = !0, - .name = "Horizontal capture resolution", + .desc = "Horizontal capture resolution", + .name = "resolution_hor", .min_value = 320, .max_value = 720, .default_value = 720, }, [PVR2_CID_VRES] = { + .id = V4L2_CID_PVR_VRES, .is_valid = !0, - .name = "Vertical capture resolution", + .desc = "Vertical capture resolution", + .name = "resolution_ver", .min_value = 200, .max_value = 625, .default_value = 480, }, [PVR2_CID_INTERLACE] = { + .id = V4L2_CID_PVR_INTERLACE, .is_valid = !0, - .name = "Interlace mode", + .desc = "Interlace mode", + .name = "interlace", .min_value = 0, .max_value = 1, .default_value = 0, }, [PVR2_CID_AUDIOLAYER] = { .is_valid = !0, - .name = "Audio Layer", + .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, - .name = "Channel", + .desc = "Channel", + .name = "channel", .min_value = 0, .max_value = FREQTABLE_SIZE, .default_value = 0, }, [PVR2_CID_CHANPROG_ID] = { .is_valid = !0, - .name = "Channel Program ID", + .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, - .name = "Channel Program Frequency", + .desc = "Channel Program Frequency", + .name = "freq_table_value", .min_value = 55250000L, .max_value = 850000000L, .skip_init = !0, @@ -386,21 +447,24 @@ static struct pvr2_ctl_def control_defs[] = }, [PVR2_CID_SIGNAL_PRESENT] = { .is_valid = !0, - .name = "Signal Present", + .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, - .name = "Streaming Enabled", + .desc = "Streaming Enabled", + .name = "streaming_enabled", .min_value = 0, .max_value = 1, .get_func = pvr2_ctl_get_streaming, }, [PVR2_CID_HSM] = { .is_valid = !0, - .name = "USB Speed", + .desc = "USB Speed", + .name = "usb_speed", .min_value = PVR2_CVAL_HSM_MIN, .max_value = PVR2_CVAL_HSM_MAX, .get_func = pvr2_ctl_get_hsm, @@ -408,7 +472,8 @@ static struct pvr2_ctl_def control_defs[] = }, [PVR2_CID_SUBSYS_MASK] = { .is_valid = !0, - .name = "Subsystem enabled mask", + .desc = "Subsystem enabled mask", + .name = "debug_subsys_mask", .min_value = 0, .max_value = 0x7fffffff, .skip_init = !0, @@ -417,18 +482,33 @@ static struct pvr2_ctl_def control_defs[] = }, [PVR2_CID_SUBSYS_STREAM_MASK] = { .is_valid = !0, - .name = "Subsystem stream mask", + .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_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) { @@ -978,9 +1058,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; } @@ -1095,6 +1175,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 @@ -1141,9 +1222,11 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; for (idx = 0; idx < CTRL_COUNT; idx++) { - if (control_defs[idx].skip_init) continue; - pvr2_hdw_set_ctl_value_internal( - hdw,idx,control_defs[idx].default_value); + 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); @@ -1172,7 +1255,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); @@ -1293,11 +1390,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)); - hdw->controls = kmalloc(sizeof(struct pvr2_ctl_state) * CTRL_COUNT, + + // 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; @@ -1425,6 +1546,8 @@ 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); kfree(hdw); } @@ -1453,10 +1576,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; @@ -1470,149 +1594,584 @@ 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; + } + + 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; +} - if (ctl_id >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) 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; +// 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 >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) 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 >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) 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; } -/* Retrieve legal maximum value for a given control */ -int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *hdw,unsigned int ctl_id) +static int pvr2_ctl_get_stdenumcur(struct pvr2_ctrl *cptr) { - if (ctl_id >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) return 0; - return control_defs[ctl_id].max_value; + return cptr->hdw->std_id; } -/* Retrieve default value for a given control */ -int pvr2_hdw_get_ctl_default_value(struct pvr2_hdw *hdw,unsigned int ctl_id) +static int pvr2_ctl_get_stdavail(struct pvr2_ctrl *cptr) { - if (ctl_id >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) return 0; - return control_defs[ctl_id].default_value; + return (int)(cptr->hdw->video_std_avail); } -/* 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) +/* 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; +} + + +/* 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) +{ + 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 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 >= CTRL_COUNT) return -EINVAL; - if (!control_defs[ctl_id].is_valid) 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 >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) 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 >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) 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 true if control ID is a valid id */ -int pvr2_hdw_get_ctl_valid(struct pvr2_hdw *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 *cptr) { - if (ctl_id >= CTRL_COUNT) return 0; - if (!control_defs[ctl_id].is_valid) return 0; + 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; +} + + /* Commit all control changes made up to this point. Subsystems can be indirectly affected by these changes. For a given set of things being committed, we'll clear the affected subsystem bits and then once we're @@ -1625,6 +2184,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; @@ -1661,16 +2222,17 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) } for (idx = 0; idx < CTRL_COUNT; idx++) { - if (!hdw->controls[idx].dirty) continue; + 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 = ""; } @@ -1690,16 +2252,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) { @@ -1712,7 +2271,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 || @@ -1737,7 +2296,8 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) pvr2_i2c_core_check_stale(hdw); for (idx = 0; idx < CTRL_COUNT; idx++) { - hdw->controls[idx].dirty = 0; + cptr = hdw->controls + idx; + cptr->dirty = 0; } /* Now execute i2c core update */ @@ -1794,14 +2354,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 CTRL_COUNT; -} - - /* Return name for this driver instance */ const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) { @@ -1837,36 +2389,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; @@ -1888,10 +2440,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 d7749138c..4101f4097 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -21,86 +21,37 @@ #ifndef __PVRUSB2_HDW_H #define __PVRUSB2_HDW_H +#include "compat.h" #include +#include #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 - -/* 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 @@ -110,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 @@ -164,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, @@ -212,43 +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 true if control is writable */ -int pvr2_hdw_get_ctl_rw(struct pvr2_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 *); -/* Retrieve legal minimum value for a given control */ -int pvr2_hdw_get_ctl_min_value(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 maximum value for a given control */ -int pvr2_hdw_get_ctl_max_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_default_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 *); -/* Return true if control id is a valid id */ -int pvr2_hdw_get_ctl_valid(struct pvr2_hdw *,unsigned int ctl_id); +/* 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 *); -/* 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 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-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 +#include 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-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 6b81def26..0ded41fcb 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -30,41 +30,6 @@ #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__) -static char *item_names[] = { - [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; @@ -88,11 +53,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[25]; }; struct pvr2_sysfs_class { @@ -101,13 +67,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 +86,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 +102,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 +119,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 +137,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 +158,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 +166,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 +181,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 +201,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 +233,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 +271,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 +382,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 +443,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 +452,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 +503,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,7 +522,10 @@ 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); @@ -573,12 +569,10 @@ static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) 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); } } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 4cdd08708..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,24 +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); - vc->default_value = - pvr2_hdw_get_ctl_default_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; @@ -797,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; @@ -819,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; } -- cgit v1.2.3 From 0d7fd3cdc85eb7e7e64a735ee7242aad047f4d64 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Tue, 28 Mar 2006 23:36:32 -0600 Subject: Fix pvrusb2 kernel oops From: Mike Isely This problem was introduced by the previous change. It appears that if you try to create to sysfs entries of the same name in one directory, then sysfs gets very angry and causes a kernel oops when you later try to tear down those nodes. By not allocating enough space to hold the name, we were inadvertently causing a sysfs control file name collision... Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 0ded41fcb..c5d44aa6c 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -58,7 +58,7 @@ struct pvr2_sysfs_ctl_item { struct pvr2_sysfs_ctl_item *item_next; struct attribute *attr_gen[5]; struct attribute_group grp; - char name[25]; + char name[80]; }; struct pvr2_sysfs_class { -- cgit v1.2.3 From 896235d467ecdcaecf352dae6d1970fdda4caeec Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 29 Mar 2006 02:00:23 -0600 Subject: Enhance I2C debugging in pvrusb2 From: Mike Isely Enhance I2C debugging in pvrusb2 such that I2C data is printed when transactions are reported. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'linux') 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); } -- cgit v1.2.3 From df9faeeb73f7e2d40d144d32b07dbc8560b5e031 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 29 Mar 2006 02:01:58 -0600 Subject: Don't reset USB control state during pvrusb2 initialization From: Mike Isely Initialization failures in the pvrusb2 driver seem to coincide with attempts to reset parts of the USB core related to this device. This really should not be needed and I suspect it may be doing more harm than good. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 585f4ee0b..7b27d96ab 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1229,8 +1229,10 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) cptr->ctl_def->default_value); } +#if 0 // Suspect this is doing more harm than good pvr2_reset_ctl_endpoints(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; +#endif ret = pvr2_hdw_get_eeprom_addr(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; -- cgit v1.2.3 From ed85a3383b5c666eb560d2668f43ca85ed925e72 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 29 Mar 2006 23:02:51 +0200 Subject: Reverted sliced VBI API changes made in videodev2.h. From: Hans Verkuil The sliced VBI defines added in videodev2.h are removed. One define changed the meaning of a old define, thus breaking existing apps, another used more than 16 bits (the max size is u16), and many types were added that were untested and whose payload was undocumented. New types should be shown to exist 'in the wild' and the payload format must be documented in the V4L2 API spec. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx25840/cx25840-vbi.c | 6 +-- linux/drivers/media/video/saa7115.c | 6 +-- linux/drivers/media/video/tvp5150.c | 20 ++++---- linux/include/linux/videodev2.h | 64 +++---------------------- 4 files changed, 23 insertions(+), 73 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx25840/cx25840-vbi.c b/linux/drivers/media/video/cx25840/cx25840-vbi.c index e16be5b2e..658fcb260 100644 --- a/linux/drivers/media/video/cx25840/cx25840-vbi.c +++ b/linux/drivers/media/video/cx25840/cx25840-vbi.c @@ -153,7 +153,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) case VIDIOC_G_FMT: { static u16 lcr2vbi[] = { - 0, V4L2_SLICED_TELETEXT_PAL_B, 0, /* 1 */ + 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 0, V4L2_SLICED_WSS_625, 0, /* 4 */ V4L2_SLICED_CAPTION_525, /* 6 */ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ @@ -233,7 +233,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) for (i = 7; i <= 23; i++) { for (x = 0; x <= 1; x++) { switch (svbi->service_lines[1-x][i]) { - case V4L2_SLICED_TELETEXT_PAL_B: + case V4L2_SLICED_TELETEXT_B: lcr[i] |= 1 << (4 * x); break; case V4L2_SLICED_WSS_625: @@ -284,7 +284,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) switch (id2) { case 1: - id2 = V4L2_SLICED_TELETEXT_PAL_B; + id2 = V4L2_SLICED_TELETEXT_B; break; case 4: id2 = V4L2_SLICED_WSS_625; diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 8992de807..1ecfacea5 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -865,7 +865,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo case 0: lcr[i] |= 0xf << (4 * x); break; - case V4L2_SLICED_TELETEXT_PAL_B: + case V4L2_SLICED_TELETEXT_B: lcr[i] |= 1 << (4 * x); break; case V4L2_SLICED_CAPTION_525: @@ -894,7 +894,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) { static u16 lcr2vbi[] = { - 0, V4L2_SLICED_TELETEXT_PAL_B, 0, /* 1 */ + 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 0, V4L2_SLICED_CAPTION_525, /* 4 */ V4L2_SLICED_WSS_625, 0, /* 5 */ V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ @@ -1059,7 +1059,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client, /* decode payloads */ switch (id2) { case 1: - vbi->type = V4L2_SLICED_TELETEXT_PAL_B; + vbi->type = V4L2_SLICED_TELETEXT_B; break; case 4: if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 8a6c5c0d0..1a2cc873e 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -532,37 +532,37 @@ struct i2c_vbi_ram_value { static struct i2c_vbi_ram_value vbi_ram_default[] = { {0x010, /* Teletext, SECAM, WST System A */ - {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, + {0,6,23,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x030, /* Teletext, PAL, WST System B */ - {V4L2_SLICED_TELETEXT_PAL_B,6,22,1}, + {V4L2_SLICED_TELETEXT_B,6,22,1}, { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x050, /* Teletext, PAL, WST System C */ - {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, + {0,6,22,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x070, /* Teletext, NTSC, WST System B */ - {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, + {0,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x090, /* Tetetext, NTSC NABTS System C */ - {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, + {0,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } }, {0x0b0, /* Teletext, NTSC-J, NABTS System D */ - {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, + {0,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x0d0, /* Closed Caption, PAL/SECAM */ - {V4L2_SLICED_CAPTION_625,22,22,1}, + {0,22,22,1}, { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } }, @@ -577,17 +577,17 @@ static struct i2c_vbi_ram_value vbi_ram_default[] = 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } }, {0x130, /* Wide Screen Signal, NTSC C */ - {V4L2_SLICED_WSS_525,20,20,1}, + {0,20,20,1}, { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } }, {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ - {V4l2_SLICED_VITC_625,6,22,0}, + {0,6,22,0}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } }, {0x170, /* Vertical Interval Timecode (VITC), NTSC */ - {V4l2_SLICED_VITC_525,10,20,0}, + {0,10,20,0}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } }, diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index bd2e07390..eb9edd711 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -998,66 +998,16 @@ struct v4l2_sliced_vbi_format /* Teletext World System Teletext (WST), defined on ITU-R BT.653-2 */ -#define V4L2_SLICED_TELETEXT_PAL_B (0x000001) -#define V4L2_SLICED_TELETEXT_PAL_C (0x000002) -#define V4L2_SLICED_TELETEXT_NTSC_B (0x000010) -#define V4L2_SLICED_TELETEXT_SECAM (0x000020) - -/* Teletext North American Broadcast Teletext Specification - (NABTS), defined on ITU-R BT.653-2 */ -#define V4L2_SLICED_TELETEXT_NTSC_C (0x000040) -#define V4L2_SLICED_TELETEXT_NTSC_D (0x000080) - +#define V4L2_SLICED_TELETEXT_B (0x0001) /* Video Program System, defined on ETS 300 231*/ -#define V4L2_SLICED_VPS (0x000400) - +#define V4L2_SLICED_VPS (0x0400) /* Closed Caption, defined on EIA-608 */ -#define V4L2_SLICED_CAPTION_525 (0x001000) -#define V4L2_SLICED_CAPTION_625 (0x002000) - +#define V4L2_SLICED_CAPTION_525 (0x1000) /* Wide Screen System, defined on ITU-R BT1119.1 */ -#define V4L2_SLICED_WSS_625 (0x004000) - -/* Wide Screen System, defined on IEC 61880 */ -#define V4L2_SLICED_WSS_525 (0x008000) - -/* Vertical Interval Timecode (VITC), defined on SMPTE 12M */ -#define V4l2_SLICED_VITC_625 (0x010000) -#define V4l2_SLICED_VITC_525 (0x020000) - -#define V4L2_SLICED_TELETEXT_B (V4L2_SLICED_TELETEXT_PAL_B |\ - V4L2_SLICED_TELETEXT_NTSC_B) - -#define V4L2_SLICED_TELETEXT (V4L2_SLICED_TELETEXT_PAL_B |\ - V4L2_SLICED_TELETEXT_PAL_C |\ - V4L2_SLICED_TELETEXT_SECAM |\ - V4L2_SLICED_TELETEXT_NTSC_B |\ - V4L2_SLICED_TELETEXT_NTSC_C |\ - V4L2_SLICED_TELETEXT_NTSC_D) - -#define V4L2_SLICED_CAPTION (V4L2_SLICED_CAPTION_525 |\ - V4L2_SLICED_CAPTION_625) - -#define V4L2_SLICED_WSS (V4L2_SLICED_WSS_525 |\ - V4L2_SLICED_WSS_625) - -#define V4L2_SLICED_VITC (V4L2_SLICED_VITC_525 |\ - V4L2_SLICED_VITC_625) - -#define V4L2_SLICED_VBI_525 (V4L2_SLICED_TELETEXT_NTSC_B |\ - V4L2_SLICED_TELETEXT_NTSC_C |\ - V4L2_SLICED_TELETEXT_NTSC_D |\ - V4L2_SLICED_CAPTION_525 |\ - V4L2_SLICED_WSS_525 |\ - V4l2_SLICED_VITC_525) - -#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_PAL_B |\ - V4L2_SLICED_TELETEXT_PAL_C |\ - V4L2_SLICED_TELETEXT_SECAM |\ - V4L2_SLICED_VPS |\ - V4L2_SLICED_CAPTION_625 |\ - V4L2_SLICED_WSS_625 |\ - V4l2_SLICED_VITC_625) +#define V4L2_SLICED_WSS_625 (0x4000) + +#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) +#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) struct v4l2_sliced_vbi_cap { -- cgit v1.2.3 From f11510a3383a92e9158e7174c335e20707e5bc51 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 31 Mar 2006 00:50:34 +0200 Subject: Fix msp3400c and bttv stereo/mono/bilingual detection/handling From: Hans Verkuil - msp3400c did not detect the second carrier, thus being always mono. - properly mute the msp3400c while detecting the carrier. - fix checks on the presence of scart2/3 inputs and scart 2 output. - implement proper audio mode fallbacks for msp3400c/d, identical to the way msp3400g works. - MODE_STEREO no longer produces dual languages when set for a bilingual transmission, instead it falls back to LANG1. Use LANG1_LANG2 to hear both languages of a bilingual transmission. This is much more intuitive for the user and is in accordance with the preferred usage in the v4l2 specification. - bttv tried to implement v4l2 calls with v4l1 calls to the i2c devices, completely mangling the audmode/rxsubchans handling. v4l2 calls now do v4l2 calls to the i2c devices. - fixed broken i2c_vidiocschan in bttv. - add start/end lines to LOG_STATUS. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt8xx/bttv-driver.c | 147 +++++++++++++------------- linux/drivers/media/video/msp3400-driver.c | 54 ++++------ linux/drivers/media/video/msp3400-driver.h | 5 +- linux/drivers/media/video/msp3400-kthreads.c | 71 +++++++------ 4 files changed, 138 insertions(+), 139 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 0e1aae5d0..1e13ee966 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1044,14 +1044,12 @@ audio_input(struct bttv *btv, int input) static void i2c_vidiocschan(struct bttv *btv) { - struct video_channel c; + v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; - memset(&c,0,sizeof(c)); - c.norm = btv->tvnorm; - c.channel = btv->input; - bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); + bttv_call_i2c_clients(btv, VIDIOC_S_INPUT, &btv->input); + bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) - bttv_tda9880_setnorm(btv,c.norm); + bttv_tda9880_setnorm(btv,btv->tvnorm); } static int @@ -1210,11 +1208,27 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) break; if (i == BTTV_CTLS) return -EINVAL; - if (i >= 4 && i <= 8) { + if (btv->audio_hook && i >= 4 && i <= 8) { memset(&va,0,sizeof(va)); - bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); - if (btv->audio_hook) - btv->audio_hook(btv,&va,0); + btv->audio_hook(btv,&va,0); + switch (c->id) { + case V4L2_CID_AUDIO_MUTE: + c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0; + break; + case V4L2_CID_AUDIO_VOLUME: + c->value = va.volume; + break; + case V4L2_CID_AUDIO_BALANCE: + c->value = va.balance; + break; + case V4L2_CID_AUDIO_BASS: + c->value = va.bass; + break; + case V4L2_CID_AUDIO_TREBLE: + c->value = va.treble; + break; + } + return 0; } switch (c->id) { case V4L2_CID_BRIGHTNESS: @@ -1231,19 +1245,11 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) break; case V4L2_CID_AUDIO_MUTE: - c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0; - break; case V4L2_CID_AUDIO_VOLUME: - c->value = va.volume; - break; case V4L2_CID_AUDIO_BALANCE: - c->value = va.balance; - break; case V4L2_CID_AUDIO_BASS: - c->value = va.bass; - break; case V4L2_CID_AUDIO_TREBLE: - c->value = va.treble; + bttv_call_i2c_clients(btv,VIDIOC_G_CTRL,c); break; case V4L2_CID_PRIVATE_CHROMA_AGC: @@ -1295,11 +1301,35 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) break; if (i == BTTV_CTLS) return -EINVAL; - if (i >= 4 && i <= 8) { + if (btv->audio_hook && i >= 4 && i <= 8) { memset(&va,0,sizeof(va)); - bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); - if (btv->audio_hook) - btv->audio_hook(btv,&va,0); + btv->audio_hook(btv,&va,0); + switch (c->id) { + case V4L2_CID_AUDIO_MUTE: + if (c->value) { + va.flags |= VIDEO_AUDIO_MUTE; + audio_mute(btv, 1); + } else { + va.flags &= ~VIDEO_AUDIO_MUTE; + audio_mute(btv, 0); + } + break; + + case V4L2_CID_AUDIO_VOLUME: + va.volume = c->value; + break; + case V4L2_CID_AUDIO_BALANCE: + va.balance = c->value; + break; + case V4L2_CID_AUDIO_BASS: + va.bass = c->value; + break; + case V4L2_CID_AUDIO_TREBLE: + va.treble = c->value; + break; + } + btv->audio_hook(btv,&va,1); + return 0; } switch (c->id) { case V4L2_CID_BRIGHTNESS: @@ -1315,26 +1345,13 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) bt848_sat(btv,c->value); break; case V4L2_CID_AUDIO_MUTE: - if (c->value) { - va.flags |= VIDEO_AUDIO_MUTE; - audio_mute(btv, 1); - } else { - va.flags &= ~VIDEO_AUDIO_MUTE; - audio_mute(btv, 0); - } - break; - + audio_mute(btv, c->value); + /* fall through */ case V4L2_CID_AUDIO_VOLUME: - va.volume = c->value; - break; case V4L2_CID_AUDIO_BALANCE: - va.balance = c->value; - break; case V4L2_CID_AUDIO_BASS: - va.bass = c->value; - break; case V4L2_CID_AUDIO_TREBLE: - va.treble = c->value; + bttv_call_i2c_clients(btv,VIDIOC_S_CTRL,c); break; case V4L2_CID_PRIVATE_CHROMA_AGC: @@ -1390,11 +1407,6 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) default: return -EINVAL; } - if (i >= 4 && i <= 8) { - bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va); - if (btv->audio_hook) - btv->audio_hook(btv,&va,1); - } return 0; } @@ -1853,33 +1865,26 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&btv->lock); memset(t,0,sizeof(*t)); + t->rxsubchans = V4L2_TUNER_SUB_MONO; + bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); strcpy(t->name, "Television"); - t->type = V4L2_TUNER_ANALOG_TV; t->capability = V4L2_TUNER_CAP_NORM; - t->rxsubchans = V4L2_TUNER_SUB_MONO; + t->type = V4L2_TUNER_ANALOG_TV; if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) t->signal = 0xffff; - { - struct video_tuner tuner; - - memset(&tuner, 0, sizeof (tuner)); - tuner.rangehigh = 0xffffffffUL; - bttv_call_i2c_clients(btv, VIDIOCGTUNER, &tuner); - t->rangelow = tuner.rangelow; - t->rangehigh = tuner.rangehigh; - } - { + + if (btv->audio_hook) { /* Hmmm ... */ struct video_audio va; memset(&va, 0, sizeof(struct video_audio)); - bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); - if (btv->audio_hook) - btv->audio_hook(btv,&va,0); + btv->audio_hook(btv,&va,0); + t->audmode = V4L2_TUNER_MODE_MONO; + t->rxsubchans = V4L2_TUNER_SUB_MONO; if(va.mode & VIDEO_SOUND_STEREO) { - t->audmode = V4L2_TUNER_MODE_STEREO; - t->rxsubchans |= V4L2_TUNER_SUB_STEREO; + t->audmode = V4L2_TUNER_MODE_STEREO; + t->rxsubchans = V4L2_TUNER_SUB_STEREO; } - if(va.mode & VIDEO_SOUND_LANG1) { + if(va.mode & VIDEO_SOUND_LANG2) { t->audmode = V4L2_TUNER_MODE_LANG1; t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; @@ -1898,10 +1903,10 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) if (0 != t->index) return -EINVAL; mutex_lock(&btv->lock); - { + bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t); + if (btv->audio_hook) { struct video_audio va; memset(&va, 0, sizeof(struct video_audio)); - bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); if (t->audmode == V4L2_TUNER_MODE_MONO) va.mode = VIDEO_SOUND_MONO; else if (t->audmode == V4L2_TUNER_MODE_STEREO || @@ -1911,9 +1916,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) va.mode = VIDEO_SOUND_LANG1; else if (t->audmode == V4L2_TUNER_MODE_LANG2) va.mode = VIDEO_SOUND_LANG2; - bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va); - if (btv->audio_hook) - btv->audio_hook(btv,&va,1); + btv->audio_hook(btv,&va,1); } mutex_unlock(&btv->lock); return 0; @@ -1938,7 +1941,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&btv->lock); btv->freq = f->frequency; - bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq); + bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,f); if (btv->has_matchbox && btv->radio_user) tea5757_set_freq(btv,btv->freq); mutex_unlock(&btv->lock); @@ -1946,7 +1949,9 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) } case VIDIOC_LOG_STATUS: { + printk(KERN_INFO "bttv%d: ================= START STATUS CARD #%d =================\n", btv->c.nr, btv->c.nr); bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL); + printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr); return 0; } @@ -2896,12 +2901,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, return 0; } *c = bttv_ctls[i]; - if (i >= 4 && i <= 8) { + if (btv->audio_hook && i >= 4 && i <= 8) { struct video_audio va; memset(&va,0,sizeof(va)); - bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); - if (btv->audio_hook) - btv->audio_hook(btv,&va,0); + btv->audio_hook(btv,&va,0); switch (bttv_ctls[i].id) { case V4L2_CID_AUDIO_VOLUME: if (!(va.flags & VIDEO_AUDIO_VOLUME)) diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index b52e5bdea..6ef656765 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -302,19 +302,6 @@ void msp_set_scart(struct i2c_client *client, int in, int out) msp_write_dem(client, 0x40, state->i2s_mode); } -void msp_set_mute(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - v4l_dbg(1, msp_debug, client, "mute audio\n"); - msp_write_dsp(client, 0x0000, 0); - msp_write_dsp(client, 0x0007, 1); - if (state->has_scart2_out_volume) - msp_write_dsp(client, 0x0040, 1); - if (state->has_headphones) - msp_write_dsp(client, 0x0006, 0); -} - void msp_set_audio(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); @@ -383,7 +370,6 @@ static void msp_wake_thread(struct i2c_client *client) if (NULL == state->kthread) return; - msp_set_mute(client); state->watch_stereo = 0; state->restart = 1; wake_up_interruptible(&state->wq); @@ -427,19 +413,15 @@ int msp_sleep(struct msp_state *state, int timeout) /* ------------------------------------------------------------------------ */ -static int msp_mode_v4l2_to_v4l1(int rxsubchans) +static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) { - int mode = 0; - - if (rxsubchans & V4L2_TUNER_SUB_STEREO) - mode |= VIDEO_SOUND_STEREO; - if (rxsubchans & V4L2_TUNER_SUB_LANG2) - mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO; - if (rxsubchans & V4L2_TUNER_SUB_LANG1) - mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO; - if (mode == 0) - mode |= VIDEO_SOUND_MONO; - return mode; + if (rxsubchans == V4L2_TUNER_SUB_MONO) + return VIDEO_SOUND_MONO; + if (rxsubchans == V4L2_TUNER_SUB_STEREO) + return VIDEO_SOUND_STEREO; + if (audmode == V4L2_TUNER_MODE_LANG2) + return VIDEO_SOUND_LANG2; + return VIDEO_SOUND_LANG1; } static int msp_mode_v4l1_to_v4l2(int mode) @@ -658,7 +640,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) break; if (state->opmode == OPMODE_AUTOSELECT) msp_detect_stereo(client); - va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); + va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode); break; } @@ -673,7 +655,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) state->treble = va->treble; msp_set_audio(client); - if (va->mode != 0 && state->radio == 0) { + if (va->mode != 0 && state->radio == 0 && + state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) { state->audmode = msp_mode_v4l1_to_v4l2(va->mode); msp_set_audmode(client); } @@ -779,6 +762,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) if (state->radio) /* TODO: add mono/stereo support for radio */ break; + if (state->audmode == vt->audmode) + break; state->audmode = vt->audmode; /* only set audmode */ msp_set_audmode(client); @@ -962,7 +947,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) memset(state, 0, sizeof(*state)); state->v4l2_std = V4L2_STD_NTSC; - state->audmode = V4L2_TUNER_MODE_LANG1; + state->audmode = V4L2_TUNER_MODE_STEREO; state->volume = 58880; /* 0db gain */ state->balance = 32768; /* 0db gain */ state->bass = 32768; @@ -1010,13 +995,16 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) state->has_radio = msp_revision >= 'G'; /* Has headphones output: not for stripped down products */ state->has_headphones = msp_prod_lo < 5; + /* Has scart2 input: not in stripped down products of the '3' family */ + state->has_scart2 = msp_family >= 4 || msp_prod_lo < 7; + /* Has scart3 input: not in stripped down products of the '3' family */ + state->has_scart3 = msp_family >= 4 || msp_prod_lo < 5; /* Has scart4 input: not in pre D revisions, not in stripped D revs */ state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5); - /* Has scart2 and scart3 inputs and scart2 output: not in stripped - down products of the '3' family */ - state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; + /* Has scart2 output: not in stripped down products of the '3' family */ + state->has_scart2_out = msp_family >= 4 || msp_prod_lo < 5; /* Has scart2 a volume control? Not in pre-D revisions. */ - state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out; + state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart2_out; /* Has a configurable i2s out? */ state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7; /* Has subwoofer output: not in pre-D revs and not in stripped down products */ diff --git a/linux/drivers/media/video/msp3400-driver.h b/linux/drivers/media/video/msp3400-driver.h index 1b03cc5a9..90c2b1297 100644 --- a/linux/drivers/media/video/msp3400-driver.h +++ b/linux/drivers/media/video/msp3400-driver.h @@ -55,8 +55,10 @@ struct msp_state { u8 has_radio; u8 has_headphones; u8 has_ntsc_jp_d_k3; + u8 has_scart2; + u8 has_scart3; u8 has_scart4; - u8 has_scart23_in_scart2_out; + u8 has_scart2_out; u8 has_scart2_out_volume; u8 has_i2s_conf; u8 has_subwoofer; @@ -103,7 +105,6 @@ int msp_read_dem(struct i2c_client *client, int addr); int msp_read_dsp(struct i2c_client *client, int addr); int msp_reset(struct i2c_client *client); void msp_set_scart(struct i2c_client *client, int in, int out); -void msp_set_mute(struct i2c_client *client); void msp_set_audio(struct i2c_client *client); int msp_sleep(struct msp_state *state, int timeout); diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index 4b0d6340a..6a4137c81 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -176,7 +176,7 @@ static void msp_set_source(struct i2c_client *client, u16 src) msp_write_dsp(client, 0x000a, src); msp_write_dsp(client, 0x000b, src); msp_write_dsp(client, 0x000c, src); - if (state->has_scart23_in_scart2_out) + if (state->has_scart2_out) msp_write_dsp(client, 0x0041, src); } @@ -246,15 +246,22 @@ static void msp3400c_set_audmode(struct i2c_client *client) return; } - /* If no second language is available, switch to the first language */ - if ((audmode == V4L2_TUNER_MODE_LANG2 || - audmode == V4L2_TUNER_MODE_LANG1_LANG2) && - !(state->rxsubchans & V4L2_TUNER_SUB_LANG2)) - audmode = V4L2_TUNER_MODE_LANG1; - /* switch to stereo for stereo transmission, otherwise - keep first language */ - if (audmode == V4L2_TUNER_MODE_LANG1 && - (state->rxsubchans & V4L2_TUNER_SUB_STEREO)) + /* Note: for the C and D revs no NTSC stereo + SAP is possible as + the hardware does not support SAP. So the rxsubchans combination + of STEREO | LANG2 does not occur. */ + + /* switch to mono if only mono is available */ + if (state->rxsubchans == V4L2_TUNER_SUB_MONO) + audmode = V4L2_TUNER_MODE_MONO; + /* if bilingual */ + else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { + /* and mono or stereo, then fallback to lang1 */ + if (audmode == V4L2_TUNER_MODE_MONO || + audmode == V4L2_TUNER_MODE_STEREO) + audmode = V4L2_TUNER_MODE_LANG1; + } + /* if stereo, and audmode is not mono, then switch to stereo */ + else if (audmode != V4L2_TUNER_MODE_MONO) audmode = V4L2_TUNER_MODE_STEREO; /* switch demodulator */ @@ -314,6 +321,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) } /* switch audio */ + v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode); switch (audmode) { case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: @@ -489,8 +497,9 @@ int msp3400c_thread(void *data) continue; } - /* mute */ - msp_set_mute(client); + /* put into sane state (and mute) */ + msp_reset(client); + msp3400c_set_mode(client, MSP_MODE_AM_DETECT); val1 = val2 = 0; max1 = max2 = -1; @@ -573,7 +582,6 @@ int msp3400c_thread(void *data) /* B/G NICAM */ state->second = msp3400c_carrier_detect_55[max2].cdo; msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); - msp3400c_set_carrier(client, state->second, state->main); state->nicam_on = 1; state->watch_stereo = 1; } else { @@ -584,7 +592,6 @@ int msp3400c_thread(void *data) /* PAL I NICAM */ state->second = MSP_CARRIER(6.552); msp3400c_set_mode(client, MSP_MODE_FM_NICAM2); - msp3400c_set_carrier(client, state->second, state->main); state->nicam_on = 1; state->watch_stereo = 1; break; @@ -598,13 +605,11 @@ int msp3400c_thread(void *data) /* L NICAM or AM-mono */ state->second = msp3400c_carrier_detect_65[max2].cdo; msp3400c_set_mode(client, MSP_MODE_AM_NICAM); - msp3400c_set_carrier(client, state->second, state->main); state->watch_stereo = 1; } else if (max2 == 0 && state->has_nicam) { /* D/K NICAM */ state->second = msp3400c_carrier_detect_65[max2].cdo; msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); - msp3400c_set_carrier(client, state->second, state->main); state->nicam_on = 1; state->watch_stereo = 1; } else { @@ -616,13 +621,15 @@ int msp3400c_thread(void *data) no_second: state->second = msp3400c_carrier_detect_main[max1].cdo; msp3400c_set_mode(client, MSP_MODE_FM_TERRA); - msp3400c_set_carrier(client, state->second, state->main); state->rxsubchans = V4L2_TUNER_SUB_MONO; break; } + msp3400c_set_carrier(client, state->second, state->main); - /* unmute */ + /* unmute, restore misc registers */ msp_set_audio(client); + + msp_write_dsp(client, 0x13, state->acb); msp3400c_set_audmode(client); if (msp_debug) @@ -630,12 +637,12 @@ int msp3400c_thread(void *data) /* monitor tv audio mode, the first time don't wait so long to get a quick stereo/bilingual result */ - if (msp_sleep(state, 1000)) - goto restart; + count = 20; while (state->watch_stereo) { watch_stereo(client); - if (msp_sleep(state, 5000)) + if (msp_sleep(state, count ? 200 : 5000)) goto restart; + if (count) count--; } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); @@ -653,7 +660,7 @@ int msp3410d_thread(void *data) { struct i2c_client *client = data; struct msp_state *state = i2c_get_clientdata(client); - int val, i, std; + int val, i, std, count; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) msp_setup_thread(state); @@ -801,12 +808,12 @@ int msp3410d_thread(void *data) /* monitor tv audio mode, the first time don't wait so long to get a quick stereo/bilingual result */ - if (msp_sleep(state, 1000)) - goto restart; + count = 20; while (state->watch_stereo) { watch_stereo(client); - if (msp_sleep(state, 5000)) + if (msp_sleep(state, count ? 200 : 5000)) goto restart; + if (count) count--; } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); @@ -869,20 +876,20 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) source = 0; /* mono only */ matrix = 0x30; break; - case V4L2_TUNER_MODE_LANG1: - source = 3; /* stereo or A */ - matrix = 0x00; - break; case V4L2_TUNER_MODE_LANG2: source = 4; /* stereo or B */ matrix = 0x10; break; - case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: - default: source = 1; /* stereo or A|B */ matrix = 0x20; break; + case V4L2_TUNER_MODE_STEREO: + case V4L2_TUNER_MODE_LANG1: + default: + source = 3; /* stereo or A */ + matrix = 0x00; + break; } if (in == MSP_DSP_OUT_TUNER) @@ -909,7 +916,7 @@ static void msp34xxg_set_sources(struct i2c_client *client) msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf); msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf); msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf); - if (state->has_scart23_in_scart2_out) + if (state->has_scart2_out) msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf); msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf); } -- cgit v1.2.3 From 9875f670afe53a6edd3a2b7852b4ee592eef4160 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 31 Mar 2006 00:55:22 +0200 Subject: Move cx2341x.h to media/cx2341x.h From: Hans Verkuil This header is used by multiple drivers, so keep it in include/media so all drivers can access it. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx2341x.h | 121 --------------------- .../drivers/media/video/pvrusb2/pvrusb2-encoder.c | 2 +- linux/include/media/cx2341x.h | 121 +++++++++++++++++++++ 3 files changed, 122 insertions(+), 122 deletions(-) delete mode 100644 linux/drivers/media/video/cx2341x.h create mode 100644 linux/include/media/cx2341x.h (limited to 'linux') diff --git a/linux/drivers/media/video/cx2341x.h b/linux/drivers/media/video/cx2341x.h deleted file mode 100644 index 7e7dcc072..000000000 --- a/linux/drivers/media/video/cx2341x.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - cx23415/6 header containing common defines. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef CX2341X_H -#define CX2341X_H - -/* Firmware names */ -#define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw" -/* Decoder firmware for the cx23415 only */ -#define CX2341X_FIRM_DEC_FILENAME "v4l-cx2341x-dec.fw" - -/* Firmware API commands */ - -/* MPEG decoder API, specific to the cx23415 */ -#define CX2341X_DEC_PING_FW 0x00 -#define CX2341X_DEC_START_PLAYBACK 0x01 -#define CX2341X_DEC_STOP_PLAYBACK 0x02 -#define CX2341X_DEC_SET_PLAYBACK_SPEED 0x03 -#define CX2341X_DEC_STEP_VIDEO 0x05 -#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 0x08 -#define CX2341X_DEC_GET_XFER_INFO 0x09 -#define CX2341X_DEC_GET_DMA_STATUS 0x0a -#define CX2341X_DEC_SCHED_DMA_FROM_HOST 0x0b -#define CX2341X_DEC_PAUSE_PLAYBACK 0x0d -#define CX2341X_DEC_HALT_FW 0x0e -#define CX2341X_DEC_SET_STANDARD 0x10 -#define CX2341X_DEC_GET_VERSION 0x11 -#define CX2341X_DEC_SET_STREAM_INPUT 0x14 -#define CX2341X_DEC_GET_TIMING_INFO 0x15 -#define CX2341X_DEC_SET_AUDIO_MODE 0x16 -#define CX2341X_DEC_SET_EVENT_NOTIFICATION 0x17 -#define CX2341X_DEC_SET_DISPLAY_BUFFERS 0x18 -#define CX2341X_DEC_EXTRACT_VBI 0x19 -#define CX2341X_DEC_SET_DECODER_SOURCE 0x1a -#define CX2341X_DEC_SET_AUDIO_OUTPUT 0x1b -#define CX2341X_DEC_SET_AV_DELAY 0x1c -#define CX2341X_DEC_SET_PREBUFFERING 0x1e - -/* MPEG encoder API */ -#define CX2341X_ENC_PING_FW 0x80 -#define CX2341X_ENC_START_CAPTURE 0x81 -#define CX2341X_ENC_STOP_CAPTURE 0x82 -#define CX2341X_ENC_SET_AUDIO_ID 0x89 -#define CX2341X_ENC_SET_VIDEO_ID 0x8b -#define CX2341X_ENC_SET_PCR_ID 0x8d -#define CX2341X_ENC_SET_FRAME_RATE 0x8f -#define CX2341X_ENC_SET_FRAME_SIZE 0x91 -#define CX2341X_ENC_SET_BIT_RATE 0x95 -#define CX2341X_ENC_SET_GOP_PROPERTIES 0x97 -#define CX2341X_ENC_SET_ASPECT_RATIO 0x99 -#define CX2341X_ENC_SET_DNR_FILTER_MODE 0x9b -#define CX2341X_ENC_SET_DNR_FILTER_PROPS 0x9d -#define CX2341X_ENC_SET_CORING_LEVELS 0x9f -#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 0xa1 -#define CX2341X_ENC_SET_3_2_PULLDOWN 0xb1 -#define CX2341X_ENC_SET_VBI_LINE 0xb7 -#define CX2341X_ENC_SET_STREAM_TYPE 0xb9 -#define CX2341X_ENC_SET_OUTPUT_PORT 0xbb -#define CX2341X_ENC_SET_AUDIO_PROPERTIES 0xbd -#define CX2341X_ENC_HALT_FW 0xc3 -#define CX2341X_ENC_GET_VERSION 0xc4 -#define CX2341X_ENC_SET_GOP_CLOSURE 0xc5 -#define CX2341X_ENC_GET_SEQ_END 0xc6 -#define CX2341X_ENC_SET_PGM_INDEX_INFO 0xc7 -#define CX2341X_ENC_SET_VBI_CONFIG 0xc8 -#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 0xc9 -#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_10 0xca -#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_9 0xcb -#define CX2341X_ENC_SCHED_DMA_TO_HOST 0xcc -#define CX2341X_ENC_INITIALIZE_INPUT 0xcd -#define CX2341X_ENC_SET_FRAME_DROP_RATE 0xd0 -#define CX2341X_ENC_PAUSE_ENCODER 0xd2 -#define CX2341X_ENC_REFRESH_INPUT 0xd3 -#define CX2341X_ENC_SET_COPYRIGHT 0xd4 -#define CX2341X_ENC_SET_EVENT_NOTIFICATION 0xd5 -#define CX2341X_ENC_SET_NUM_VSYNC_LINES 0xd6 -#define CX2341X_ENC_SET_PLACEHOLDER 0xd7 -#define CX2341X_ENC_MUTE_VIDEO 0xd9 -#define CX2341X_ENC_MUTE_AUDIO 0xda -#define CX2341X_ENC_UNKNOWN 0xdb -#define CX2341X_ENC_MISC 0xdc - -/* OSD API, specific to the cx23415 */ -#define CX2341X_OSD_GET_FRAMEBUFFER 0x41 -#define CX2341X_OSD_GET_PIXEL_FORMAT 0x42 -#define CX2341X_OSD_SET_PIXEL_FORMAT 0x43 -#define CX2341X_OSD_GET_STATE 0x44 -#define CX2341X_OSD_SET_STATE 0x45 -#define CX2341X_OSD_GET_OSD_COORDS 0x46 -#define CX2341X_OSD_SET_OSD_COORDS 0x47 -#define CX2341X_OSD_GET_SCREEN_COORDS 0x48 -#define CX2341X_OSD_SET_SCREEN_COORDS 0x49 -#define CX2341X_OSD_GET_GLOBAL_ALPHA 0x4a -#define CX2341X_OSD_SET_GLOBAL_ALPHA 0x4b -#define CX2341X_OSD_SET_BLEND_COORDS 0x4c -#define CX2341X_OSD_GET_FLICKER_STATE 0x4f -#define CX2341X_OSD_SET_FLICKER_STATE 0x50 -#define CX2341X_OSD_BLT_COPY 0x52 -#define CX2341X_OSD_BLT_FILL 0x53 -#define CX2341X_OSD_BLT_TEXT 0x54 -#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 0x56 -#define CX2341X_OSD_SET_CHROMA_KEY 0x60 -#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 0x61 -#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 0x62 - -#endif /* CX2341X_H */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 553bd2d7b..b85ef5059 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -22,7 +22,7 @@ #include // for linux/firmware.h #include -#include "cx2341x.h" +#include #include "pvrusb2-util.h" #include "pvrusb2-encoder.h" #include "pvrusb2-hdw-internal.h" diff --git a/linux/include/media/cx2341x.h b/linux/include/media/cx2341x.h new file mode 100644 index 000000000..7e7dcc072 --- /dev/null +++ b/linux/include/media/cx2341x.h @@ -0,0 +1,121 @@ +/* + cx23415/6 header containing common defines. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CX2341X_H +#define CX2341X_H + +/* Firmware names */ +#define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw" +/* Decoder firmware for the cx23415 only */ +#define CX2341X_FIRM_DEC_FILENAME "v4l-cx2341x-dec.fw" + +/* Firmware API commands */ + +/* MPEG decoder API, specific to the cx23415 */ +#define CX2341X_DEC_PING_FW 0x00 +#define CX2341X_DEC_START_PLAYBACK 0x01 +#define CX2341X_DEC_STOP_PLAYBACK 0x02 +#define CX2341X_DEC_SET_PLAYBACK_SPEED 0x03 +#define CX2341X_DEC_STEP_VIDEO 0x05 +#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 0x08 +#define CX2341X_DEC_GET_XFER_INFO 0x09 +#define CX2341X_DEC_GET_DMA_STATUS 0x0a +#define CX2341X_DEC_SCHED_DMA_FROM_HOST 0x0b +#define CX2341X_DEC_PAUSE_PLAYBACK 0x0d +#define CX2341X_DEC_HALT_FW 0x0e +#define CX2341X_DEC_SET_STANDARD 0x10 +#define CX2341X_DEC_GET_VERSION 0x11 +#define CX2341X_DEC_SET_STREAM_INPUT 0x14 +#define CX2341X_DEC_GET_TIMING_INFO 0x15 +#define CX2341X_DEC_SET_AUDIO_MODE 0x16 +#define CX2341X_DEC_SET_EVENT_NOTIFICATION 0x17 +#define CX2341X_DEC_SET_DISPLAY_BUFFERS 0x18 +#define CX2341X_DEC_EXTRACT_VBI 0x19 +#define CX2341X_DEC_SET_DECODER_SOURCE 0x1a +#define CX2341X_DEC_SET_AUDIO_OUTPUT 0x1b +#define CX2341X_DEC_SET_AV_DELAY 0x1c +#define CX2341X_DEC_SET_PREBUFFERING 0x1e + +/* MPEG encoder API */ +#define CX2341X_ENC_PING_FW 0x80 +#define CX2341X_ENC_START_CAPTURE 0x81 +#define CX2341X_ENC_STOP_CAPTURE 0x82 +#define CX2341X_ENC_SET_AUDIO_ID 0x89 +#define CX2341X_ENC_SET_VIDEO_ID 0x8b +#define CX2341X_ENC_SET_PCR_ID 0x8d +#define CX2341X_ENC_SET_FRAME_RATE 0x8f +#define CX2341X_ENC_SET_FRAME_SIZE 0x91 +#define CX2341X_ENC_SET_BIT_RATE 0x95 +#define CX2341X_ENC_SET_GOP_PROPERTIES 0x97 +#define CX2341X_ENC_SET_ASPECT_RATIO 0x99 +#define CX2341X_ENC_SET_DNR_FILTER_MODE 0x9b +#define CX2341X_ENC_SET_DNR_FILTER_PROPS 0x9d +#define CX2341X_ENC_SET_CORING_LEVELS 0x9f +#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 0xa1 +#define CX2341X_ENC_SET_3_2_PULLDOWN 0xb1 +#define CX2341X_ENC_SET_VBI_LINE 0xb7 +#define CX2341X_ENC_SET_STREAM_TYPE 0xb9 +#define CX2341X_ENC_SET_OUTPUT_PORT 0xbb +#define CX2341X_ENC_SET_AUDIO_PROPERTIES 0xbd +#define CX2341X_ENC_HALT_FW 0xc3 +#define CX2341X_ENC_GET_VERSION 0xc4 +#define CX2341X_ENC_SET_GOP_CLOSURE 0xc5 +#define CX2341X_ENC_GET_SEQ_END 0xc6 +#define CX2341X_ENC_SET_PGM_INDEX_INFO 0xc7 +#define CX2341X_ENC_SET_VBI_CONFIG 0xc8 +#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 0xc9 +#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_10 0xca +#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_9 0xcb +#define CX2341X_ENC_SCHED_DMA_TO_HOST 0xcc +#define CX2341X_ENC_INITIALIZE_INPUT 0xcd +#define CX2341X_ENC_SET_FRAME_DROP_RATE 0xd0 +#define CX2341X_ENC_PAUSE_ENCODER 0xd2 +#define CX2341X_ENC_REFRESH_INPUT 0xd3 +#define CX2341X_ENC_SET_COPYRIGHT 0xd4 +#define CX2341X_ENC_SET_EVENT_NOTIFICATION 0xd5 +#define CX2341X_ENC_SET_NUM_VSYNC_LINES 0xd6 +#define CX2341X_ENC_SET_PLACEHOLDER 0xd7 +#define CX2341X_ENC_MUTE_VIDEO 0xd9 +#define CX2341X_ENC_MUTE_AUDIO 0xda +#define CX2341X_ENC_UNKNOWN 0xdb +#define CX2341X_ENC_MISC 0xdc + +/* OSD API, specific to the cx23415 */ +#define CX2341X_OSD_GET_FRAMEBUFFER 0x41 +#define CX2341X_OSD_GET_PIXEL_FORMAT 0x42 +#define CX2341X_OSD_SET_PIXEL_FORMAT 0x43 +#define CX2341X_OSD_GET_STATE 0x44 +#define CX2341X_OSD_SET_STATE 0x45 +#define CX2341X_OSD_GET_OSD_COORDS 0x46 +#define CX2341X_OSD_SET_OSD_COORDS 0x47 +#define CX2341X_OSD_GET_SCREEN_COORDS 0x48 +#define CX2341X_OSD_SET_SCREEN_COORDS 0x49 +#define CX2341X_OSD_GET_GLOBAL_ALPHA 0x4a +#define CX2341X_OSD_SET_GLOBAL_ALPHA 0x4b +#define CX2341X_OSD_SET_BLEND_COORDS 0x4c +#define CX2341X_OSD_GET_FLICKER_STATE 0x4f +#define CX2341X_OSD_SET_FLICKER_STATE 0x50 +#define CX2341X_OSD_BLT_COPY 0x52 +#define CX2341X_OSD_BLT_FILL 0x53 +#define CX2341X_OSD_BLT_TEXT 0x54 +#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 0x56 +#define CX2341X_OSD_SET_CHROMA_KEY 0x60 +#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 0x61 +#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 0x62 + +#endif /* CX2341X_H */ -- cgit v1.2.3 From 950e8155e83cdf480a41449cf024494b6ec25e69 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 31 Mar 2006 00:57:28 +0200 Subject: Previous change for cx2341X boards broke the remote support From: Hans Verkuil Partially revert previous change to fix IR support. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ir-kbd-i2c.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index ab1c47648..15ce0ff08 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -410,7 +410,6 @@ static int ir_probe(struct i2c_adapter *adap) */ static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; - static const int probe_cx2341x[] = { 0x18, 0x7a, -1}; static const int probe_saa7134[] = { 0x7a, 0x47, -1 }; static const int probe_em28XX[] = { 0x30, 0x47, -1 }; const int *probe = NULL; @@ -423,7 +422,7 @@ static int ir_probe(struct i2c_adapter *adap) probe = probe_bttv; break; case I2C_HW_B_CX2341X: - probe = probe_cx2341x; + probe = probe_bttv; break; case I2C_HW_SAA7134: probe = probe_saa7134; -- cgit v1.2.3 From 376fb9365c967e7d2bb2aee61e01685595bf1111 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Thu, 30 Mar 2006 22:14:40 -0600 Subject: Make parts of pvrusb2 compile-time options (sysfs and debugifc) From: Mike Isely Arrange things in pvrusb2 so that the sysfs-using component doesn't have to be compiled in. Control this with new CONFIG_VIDEO_PVRUSB2_SYSFS variable. This will allow the driver to still be used even if sysfs has not been compiled into the kernel. Also arrange things similarly in pvrusb2 for the debug interface, which is something that normally should not need to be built but is valuable for bug chasing. This is controlled now with CONFIG_VIDEO_PVRUSB2_DEBUGIFC. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-main.c | 10 ++++++++++ linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 14 ++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'linux') 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 " #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 c5d44aa6c..053c0b24c 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -26,14 +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__) 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; @@ -42,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; @@ -531,6 +537,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) 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); @@ -565,6 +572,7 @@ 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) @@ -608,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); @@ -684,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 */ } @@ -755,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; @@ -787,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 */ /* -- cgit v1.2.3 From 012c447c3dd586921468215450cb6cce65052a3c Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Thu, 30 Mar 2006 22:16:09 -0600 Subject: pvrusb2 driver initialization tweak From: Mike Isely Make permanent the removal of the call to pvr2_reset_ctl_endpoints(). It is known positively now that this step was both unneeded and caused harm to communication with the hardware during driver initialization. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 7b27d96ab..32bdaeba7 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1229,10 +1229,9 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) cptr->ctl_def->default_value); } -#if 0 // Suspect this is doing more harm than good - pvr2_reset_ctl_endpoints(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; -#endif + // 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; -- cgit v1.2.3 From 401def2d2cdb15034aa721cc524c9d7c70d3ddcd Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Thu, 30 Mar 2006 22:51:33 -0600 Subject: Clean up comments in pvrusb2-eeprom.c From: Mike Isely Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c | 72 +--------------------- 1 file changed, 2 insertions(+), 70 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c index 634095efc..78bc968c0 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c @@ -27,57 +27,8 @@ #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 */ - /* Read and analyze data in the eeprom. Use tveeprom to figure out @@ -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; @@ -211,17 +154,6 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) return 0; } - - -/* END DIRECT METHOD, V4L ONLY */ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - - - - - - - /* Stuff for Emacs to see, in order to encourage consistent editing style: *** Local Variables: *** -- cgit v1.2.3 From 0bce98602d455b54f9e8f4915f7288e0b4b6bdb8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 31 Mar 2006 01:47:58 -0500 Subject: Kconfig: add menu options for pvrusb2 sysfs and debug interface support From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/video/pvrusb2/Kconfig | 27 +++++++++++++++++++++++++++ linux/drivers/media/video/pvrusb2/Makefile | 7 +++++-- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig index 9824ad267..b22ab7f5f 100644 --- a/linux/drivers/media/video/pvrusb2/Kconfig +++ b/linux/drivers/media/video/pvrusb2/Kconfig @@ -12,3 +12,30 @@ config VIDEO_PVRUSB2 To compile this driver as a module, choose M here: the module will be called pvrusb2 + +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..b0d3064ef 100644 --- a/linux/drivers/media/video/pvrusb2/Makefile +++ b/linux/drivers/media/video/pvrusb2/Makefile @@ -1,11 +1,14 @@ +obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o +obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.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-context.o pvrusb2-io.o pvrusb2-ioread.o \ pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ - pvrusb2-ioread.o pvrusb2-debugifc.o + $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o -- cgit v1.2.3 From 0932c037375ef26f5d0cfbec3742519e0f0d5cae Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Apr 2006 20:27:52 +0200 Subject: More msp3400 and bttv fixes From: Hans Verkuil - remove obsolete VIDIOC_S_INPUT i2c call in bttv - translate VIDIOCSFREQ to VIDIOC_S_FREQUENCY in i2c call - improve muting during carrier scan in msp3400 - don't start scan unless really needed. - no longer reset chip for msp3400c/d. - remove v4l2 check in tuner-core (radio stops after using the TV) - add missing VIDIOC_INT_ strings in v4l2-common.c Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt8xx/bttv-driver.c | 13 +++--- linux/drivers/media/video/msp3400-driver.c | 32 +++++++------- linux/drivers/media/video/msp3400-driver.h | 1 + linux/drivers/media/video/msp3400-kthreads.c | 60 ++++++++++----------------- linux/drivers/media/video/tuner-core.c | 6 +++ linux/drivers/media/video/v4l2-common.c | 8 +++- 6 files changed, 62 insertions(+), 58 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 1e13ee966..ea9f82586 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1046,7 +1046,6 @@ i2c_vidiocschan(struct bttv *btv) { v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; - bttv_call_i2c_clients(btv, VIDIOC_S_INPUT, &btv->input); bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) bttv_tda9880_setnorm(btv,btv->tvnorm); @@ -1629,12 +1628,16 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) } case VIDIOCSFREQ: { - unsigned long *freq = arg; + struct v4l2_frequency freq; + + memset(&freq, 0, sizeof(freq)); + freq.frequency = *(unsigned long *)arg; mutex_lock(&btv->lock); - btv->freq=*freq; - bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq); + freq.type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + btv->freq = *(unsigned long *)arg; + bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,&freq); if (btv->has_matchbox && btv->radio_user) - tea5757_set_freq(btv,*freq); + tea5757_set_freq(btv,*(unsigned long *)arg); mutex_unlock(&btv->lock); return 0; } diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index 6ef656765..be3a3bb70 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -307,17 +307,19 @@ void msp_set_audio(struct i2c_client *client) struct msp_state *state = i2c_get_clientdata(client); int bal = 0, bass, treble, loudness; int val = 0; + int reallymuted = state->muted | state->scan_in_progress; - if (!state->muted) + if (!reallymuted) val = (state->volume * 0x7f / 65535) << 8; - v4l_dbg(1, msp_debug, client, "mute=%s volume=%d\n", - state->muted ? "on" : "off", state->volume); + v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n", + state->muted ? "on" : "off", state->scan_in_progress ? "yes" : "no", + state->volume); msp_write_dsp(client, 0x0000, val); - msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); + msp_write_dsp(client, 0x0007, reallymuted ? 0x1 : (val | 0x1)); if (state->has_scart2_out_volume) - msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1)); + msp_write_dsp(client, 0x0040, reallymuted ? 0x1 : (val | 0x1)); if (state->has_headphones) msp_write_dsp(client, 0x0006, val); if (!state->has_sound_processing) @@ -723,21 +725,23 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) int sc_in = rt->input & 0x7; int sc1_out = rt->output & 0xf; int sc2_out = (rt->output >> 4) & 0xf; - u16 val; + u16 val, reg; + if (state->routing.input == rt->input && + state->routing.output == rt->output) + break; state->routing = *rt; - if (state->opmode == OPMODE_AUTOSELECT) { - val = msp_read_dem(client, 0x30) & ~0x100; - msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0)); - } else { - val = msp_read_dem(client, 0xbb) & ~0x100; - msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0)); - } msp_set_scart(client, sc_in, 0); msp_set_scart(client, sc1_out, 1); msp_set_scart(client, sc2_out, 2); msp_set_audmode(client); - msp_wake_thread(client); + reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; + val = msp_read_dem(client, reg); + if (tuner != ((val >> 8) & 1)) { + msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); + /* wake thread when a new tuner input is chosen */ + msp_wake_thread(client); + } break; } diff --git a/linux/drivers/media/video/msp3400-driver.h b/linux/drivers/media/video/msp3400-driver.h index 90c2b1297..3e26d7b4d 100644 --- a/linux/drivers/media/video/msp3400-driver.h +++ b/linux/drivers/media/video/msp3400-driver.h @@ -86,6 +86,7 @@ struct msp_state { int volume, muted; int balance, loudness; int bass, treble; + int scan_in_progress; /* thread */ struct task_struct *kthread; diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index 6a4137c81..714047178 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -389,7 +389,7 @@ static int msp3400c_detect_stereo(struct i2c_client *client) if (val > 32767) val -= 65536; v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val); - if (val > 4096) { + if (val > 8192) { rxsubchans = V4L2_TUNER_SUB_STEREO; } else if (val < -4096) { rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; @@ -493,12 +493,14 @@ int msp3400c_thread(void *data) if (state->radio || MSP_MODE_EXTERN == state->mode) { /* no carrier scan, just unmute */ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); + state->scan_in_progress = 0; msp_set_audio(client); continue; } - /* put into sane state (and mute) */ - msp_reset(client); + /* mute audio */ + state->scan_in_progress = 1; + msp_set_audio(client); msp3400c_set_mode(client, MSP_MODE_AM_DETECT); val1 = val2 = 0; @@ -506,10 +508,6 @@ int msp3400c_thread(void *data) state->watch_stereo = 0; state->nicam_on = 0; - /* some time for the tuner to sync */ - if (msp_sleep(state, 200)) - goto restart; - /* carrier detect pass #1 -- main carrier */ cd = msp3400c_carrier_detect_main; count = ARRAY_SIZE(msp3400c_carrier_detect_main); @@ -621,28 +619,26 @@ int msp3400c_thread(void *data) no_second: state->second = msp3400c_carrier_detect_main[max1].cdo; msp3400c_set_mode(client, MSP_MODE_FM_TERRA); - state->rxsubchans = V4L2_TUNER_SUB_MONO; break; } msp3400c_set_carrier(client, state->second, state->main); - /* unmute, restore misc registers */ - msp_set_audio(client); - - msp_write_dsp(client, 0x13, state->acb); + /* unmute */ + state->scan_in_progress = 0; msp3400c_set_audmode(client); + msp_set_audio(client); if (msp_debug) msp3400c_print_mode(client); /* monitor tv audio mode, the first time don't wait so long to get a quick stereo/bilingual result */ - count = 20; + count = 3; while (state->watch_stereo) { - watch_stereo(client); - if (msp_sleep(state, count ? 200 : 5000)) + if (msp_sleep(state, count ? 1000 : 5000)) goto restart; if (count) count--; + watch_stereo(client); } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); @@ -685,16 +681,14 @@ int msp3410d_thread(void *data) if (state->mode == MSP_MODE_EXTERN) { /* no carrier scan needed, just unmute */ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); + state->scan_in_progress = 0; msp_set_audio(client); continue; } - /* put into sane state (and mute) */ - msp_reset(client); - - /* some time for the tuner to sync */ - if (msp_sleep(state,200)) - goto restart; + /* mute audio */ + state->scan_in_progress = 1; + msp_set_audio(client); /* start autodetect. Note: autodetect is not supported for NTSC-M and radio, hence we force the standard in those cases. */ @@ -734,6 +728,7 @@ int msp3410d_thread(void *data) state->main = msp_stdlist[i].main; state->second = msp_stdlist[i].second; state->std = val; + state->rxsubchans = V4L2_TUNER_SUB_MONO; if (msp_amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) && (val != 0x0009)) { @@ -755,20 +750,17 @@ int msp3410d_thread(void *data) else state->mode = MSP_MODE_FM_NICAM1; /* just turn on stereo */ - state->rxsubchans = V4L2_TUNER_SUB_STEREO; state->nicam_on = 1; state->watch_stereo = 1; break; case 0x0009: state->mode = MSP_MODE_AM_NICAM; - state->rxsubchans = V4L2_TUNER_SUB_MONO; state->nicam_on = 1; state->watch_stereo = 1; break; case 0x0020: /* BTSC */ /* The pre-'G' models only have BTSC-mono */ state->mode = MSP_MODE_BTSC; - state->rxsubchans = V4L2_TUNER_SUB_MONO; break; case 0x0040: /* FM radio */ state->mode = MSP_MODE_FM_RADIO; @@ -778,15 +770,12 @@ int msp3410d_thread(void *data) msp3400c_set_mode(client, MSP_MODE_FM_RADIO); msp3400c_set_carrier(client, MSP_CARRIER(10.7), MSP_CARRIER(10.7)); - /* scart routing (this doesn't belong here I think) */ - msp_set_scart(client,SCART_IN2,0); break; case 0x0002: case 0x0003: case 0x0004: case 0x0005: state->mode = MSP_MODE_FM_TERRA; - state->rxsubchans = V4L2_TUNER_SUB_MONO; state->watch_stereo = 1; break; } @@ -800,20 +789,19 @@ int msp3410d_thread(void *data) if (state->has_i2s_conf) msp_write_dem(client, 0x40, state->i2s_mode); - /* unmute, restore misc registers */ - msp_set_audio(client); - - msp_write_dsp(client, 0x13, state->acb); + /* unmute */ msp3400c_set_audmode(client); + state->scan_in_progress = 0; + msp_set_audio(client); /* monitor tv audio mode, the first time don't wait so long to get a quick stereo/bilingual result */ - count = 20; + count = 3; while (state->watch_stereo) { - watch_stereo(client); - if (msp_sleep(state, count ? 200 : 5000)) + if (msp_sleep(state, count ? 1000 : 5000)) goto restart; if (count) count--; + watch_stereo(client); } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); @@ -934,10 +922,6 @@ static void msp34xxg_reset(struct i2c_client *client) msp_reset(client); - /* make sure that input/output is muted (paranoid mode) */ - /* ACB, mute DSP input, mute SCART 1 */ - msp_write_dsp(client, 0x13, 0x0f20); - if (state->has_i2s_conf) msp_write_dem(client, 0x40, state->i2s_mode); diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 87581654f..15282bbbb 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -615,10 +615,16 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, static inline int check_v4l2(struct tuner *t) { + /* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for + TV, v4l1 for radio), until that is fixed this code is disabled. + Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2) + first. */ +#if 0 if (t->using_v4l2) { tuner_dbg ("ignore v4l1 call\n"); return EINVAL; } +#endif return 0; } diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index ae5538212..5f71edf32 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -337,6 +337,7 @@ static const char *v4l2_int_ioctls[] = { [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", [_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG", + [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", [_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER", [_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER", [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", @@ -345,7 +346,12 @@ static const char *v4l2_int_ioctls[] = { [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", [_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT", - [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ" + [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", + [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", + [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING" }; #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) -- cgit v1.2.3 From 75ba9961e3fc167c48412d75bc01d55fab89cac0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Apr 2006 21:00:18 +0200 Subject: Keep experimental SLICED_VBI defines under an #if 0 From: Hans Verkuil As per request by Mauro the experimental SLICED_VBI defines are back under placed under an #if 0. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/tvp5150.c | 26 +++++++++----- linux/include/linux/videodev2.h | 67 +++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 9 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 1a2cc873e..543516347 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -531,41 +531,47 @@ struct i2c_vbi_ram_value { static struct i2c_vbi_ram_value vbi_ram_default[] = { + /* FIXME: Current api doesn't handle all VBI types, those not + yet supported are placed under #if 0 */ +#if 0 /* keep */ {0x010, /* Teletext, SECAM, WST System A */ - {0,6,23,1}, + {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } }, +#endif {0x030, /* Teletext, PAL, WST System B */ {V4L2_SLICED_TELETEXT_B,6,22,1}, { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } }, +#if 0 /* keep */ {0x050, /* Teletext, PAL, WST System C */ - {0,6,22,1}, + {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x070, /* Teletext, NTSC, WST System B */ - {0,10,21,1}, + {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x090, /* Tetetext, NTSC NABTS System C */ - {0,10,21,1}, + {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } }, {0x0b0, /* Teletext, NTSC-J, NABTS System D */ - {0,10,21,1}, + {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, {0x0d0, /* Closed Caption, PAL/SECAM */ - {0,22,22,1}, + {V4L2_SLICED_CAPTION_625,22,22,1}, { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } }, +#endif {0x0f0, /* Closed Caption, NTSC */ {V4L2_SLICED_CAPTION_525,21,21,1}, { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, @@ -576,21 +582,23 @@ static struct i2c_vbi_ram_value vbi_ram_default[] = { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } }, +#if 0 /* keep */ {0x130, /* Wide Screen Signal, NTSC C */ - {0,20,20,1}, + {V4L2_SLICED_WSS_525,20,20,1}, { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } }, {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ - {0,6,22,0}, + {V4l2_SLICED_VITC_625,6,22,0}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } }, {0x170, /* Vertical Interval Timecode (VITC), NTSC */ - {0,10,20,0}, + {V4l2_SLICED_VITC_525,10,20,0}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } }, +#endif {0x190, /* Video Program System (VPS), PAL */ {V4L2_SLICED_VPS,16,16,0}, { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index eb9edd711..b87334d72 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -1009,6 +1009,73 @@ struct v4l2_sliced_vbi_format #define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) #define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) +#if 0 +/* FIXME: Currently unused defines, needs to be discussed further */ + +/* Teletext World System Teletext + (WST), defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_PAL_B (0x000001) +#define V4L2_SLICED_TELETEXT_PAL_C (0x000002) +#define V4L2_SLICED_TELETEXT_NTSC_B (0x000010) +#define V4L2_SLICED_TELETEXT_SECAM (0x000020) + +/* Teletext North American Broadcast Teletext Specification + (NABTS), defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_NTSC_C (0x000040) +#define V4L2_SLICED_TELETEXT_NTSC_D (0x000080) + +/* Video Program System, defined on ETS 300 231*/ +#define V4L2_SLICED_VPS (0x000400) + +/* Closed Caption, defined on EIA-608 */ +#define V4L2_SLICED_CAPTION_525 (0x001000) +#define V4L2_SLICED_CAPTION_625 (0x002000) + +/* Wide Screen System, defined on ITU-R BT1119.1 */ +#define V4L2_SLICED_WSS_625 (0x004000) + +/* Wide Screen System, defined on IEC 61880 */ +#define V4L2_SLICED_WSS_525 (0x008000) + +/* Vertical Interval Timecode (VITC), defined on SMPTE 12M */ +#define V4l2_SLICED_VITC_625 (0x010000) +#define V4l2_SLICED_VITC_525 (0x020000) + +#define V4L2_SLICED_TELETEXT_B (V4L2_SLICED_TELETEXT_PAL_B |\ + V4L2_SLICED_TELETEXT_NTSC_B) + +#define V4L2_SLICED_TELETEXT (V4L2_SLICED_TELETEXT_PAL_B |\ + V4L2_SLICED_TELETEXT_PAL_C |\ + V4L2_SLICED_TELETEXT_SECAM |\ + V4L2_SLICED_TELETEXT_NTSC_B |\ + V4L2_SLICED_TELETEXT_NTSC_C |\ + V4L2_SLICED_TELETEXT_NTSC_D) + +#define V4L2_SLICED_CAPTION (V4L2_SLICED_CAPTION_525 |\ + V4L2_SLICED_CAPTION_625) + +#define V4L2_SLICED_WSS (V4L2_SLICED_WSS_525 |\ + V4L2_SLICED_WSS_625) + +#define V4L2_SLICED_VITC (V4L2_SLICED_VITC_525 |\ + V4L2_SLICED_VITC_625) + +#define V4L2_SLICED_VBI_525 (V4L2_SLICED_TELETEXT_NTSC_B |\ + V4L2_SLICED_TELETEXT_NTSC_C |\ + V4L2_SLICED_TELETEXT_NTSC_D |\ + V4L2_SLICED_CAPTION_525 |\ + V4L2_SLICED_WSS_525 |\ + V4l2_SLICED_VITC_525) + +#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_PAL_B |\ + V4L2_SLICED_TELETEXT_PAL_C |\ + V4L2_SLICED_TELETEXT_SECAM |\ + V4L2_SLICED_VPS |\ + V4L2_SLICED_CAPTION_625 |\ + V4L2_SLICED_WSS_625 |\ + V4l2_SLICED_VITC_625) +#endif + struct v4l2_sliced_vbi_cap { __u16 service_set; -- cgit v1.2.3 From 1d6852ba00b82d0342468dc905f33226d7e9860b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Apr 2006 21:06:55 +0200 Subject: Add back the msp_sleep that waits for the tuner to settle down From: Hans Verkuil I removed a msp_sleep call that is really needed, otherwise the second carrier is not detected correctly. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/msp3400-kthreads.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index 714047178..aaaa26219 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -508,6 +508,10 @@ int msp3400c_thread(void *data) state->watch_stereo = 0; state->nicam_on = 0; + /* wait for tuner to settle down after a channel change */ + if (msp_sleep(state, 200)) + goto restart; + /* carrier detect pass #1 -- main carrier */ cd = msp3400c_carrier_detect_main; count = ARRAY_SIZE(msp3400c_carrier_detect_main); @@ -699,6 +703,10 @@ int msp3410d_thread(void *data) state->watch_stereo = 0; state->nicam_on = 0; + /* wait for tuner to settle down after a channel change */ + if (msp_sleep(state, 200)) + goto restart; + if (msp_debug) v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n", msp_standard_std_name(std), std); -- cgit v1.2.3 From 8929143e56ef440073aef532a80f620b6fafdb65 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Apr 2006 21:40:21 +0200 Subject: Remove obsolete commands from tvp5150.c From: Hans Verkuil - Remove old DECODER_ commands from tvp5150.c, replacing them with newer ones if appropriate. - Small VIDIOC_G_TUNER fixes in msp3400 and tuner. - Fix VIDIOC_S_TUNER support in em28xx. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/em28xx/em28xx-video.c | 31 +----- linux/drivers/media/video/msp3400-driver.c | 2 +- linux/drivers/media/video/tuner-core.c | 2 + linux/drivers/media/video/tvp5150.c | 122 +----------------------- 4 files changed, 11 insertions(+), 146 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 748fd6200..60feda020 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1207,26 +1207,16 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, case VIDIOC_G_TUNER: { struct v4l2_tuner *t = arg; - int status = 0; if (0 != t->index) return -EINVAL; memset(t, 0, sizeof(*t)); strcpy(t->name, "Tuner"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM; - t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ -/* t->signal = 0xffff;*/ -/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/ - /* No way to get signal strength? */ mutex_lock(&dev->lock); - em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, - &status); + /* let clients fill in the remainder of this struct */ + em28xx_i2c_call_clients(dev, cmd, t); mutex_unlock(&dev->lock); - t->signal = - (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; - em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal, t->afc); return 0; @@ -1234,26 +1224,13 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, case VIDIOC_S_TUNER: { struct v4l2_tuner *t = arg; - int status = 0; if (0 != t->index) return -EINVAL; - memset(t, 0, sizeof(*t)); - strcpy(t->name, "Tuner"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM; - t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ -/* t->signal = 0xffff; */ - /* No way to get signal strength? */ mutex_lock(&dev->lock); - em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, - &status); + /* let clients handle this */ + em28xx_i2c_call_clients(dev, cmd, t); mutex_unlock(&dev->lock); - t->signal = - (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; - - em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n", - t->signal, t->afc); return 0; } case VIDIOC_G_FREQUENCY: diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index be3a3bb70..79e2bdb11 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -755,7 +755,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) msp_detect_stereo(client); vt->audmode = state->audmode; vt->rxsubchans = state->rxsubchans; - vt->capability = V4L2_TUNER_CAP_STEREO | + vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; break; } diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 15282bbbb..35ba614c0 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -807,6 +807,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) switch_v4l2(); tuner->type = t->mode; + if (t->mode == V4L2_TUNER_ANALOG_TV) + tuner->capability |= V4L2_TUNER_CAP_NORM; if (t->mode != V4L2_TUNER_RADIO) { tuner->rangelow = tv_range[0] * 16; tuner->rangehigh = tv_range[1] * 16; diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 543516347..aa7139089 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -907,7 +907,6 @@ static int tvp5150_command(struct i2c_client *c, case 0: case VIDIOC_INT_RESET: - case DECODER_INIT: tvp5150_reset(c); break; case VIDIOC_S_STD: @@ -1053,99 +1052,15 @@ static int tvp5150_command(struct i2c_client *c, #endif case VIDIOC_LOG_STATUS: - case DECODER_DUMP: dump_reg(c); break; - case DECODER_GET_CAPABILITIES: + case VIDIOC_G_TUNER: { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | - VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR; - cap->inputs = 3; - cap->outputs = 1; - break; - } - case DECODER_GET_STATUS: - { - int *iarg = arg; - int status; - int res=0; - status = tvp5150_read(c, 0x88); - if(status&0x08){ - res |= DECODER_STATUS_COLOR; - } - if(status&0x04 && status&0x02){ - res |= DECODER_STATUS_GOOD; - } - *iarg=res; - break; - } - - case DECODER_SET_GPIO: - break; - - case DECODER_SET_VBI_BYPASS: - break; - - case DECODER_SET_NORM: - { - int *iarg = arg; - - switch (*iarg) { - - case VIDEO_MODE_NTSC: - break; - - case VIDEO_MODE_PAL: - break; - - case VIDEO_MODE_SECAM: - break; - - case VIDEO_MODE_AUTO: - break; - - default: - return -EINVAL; - - } - decoder->norm = *iarg; - break; - } - case DECODER_SET_INPUT: - { - int *iarg = arg; - if (*iarg < 0 || *iarg > 3) { - return -EINVAL; - } - - decoder->input = *iarg; - tvp5150_selmux(c, decoder->input); - - break; - } - case DECODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } - break; - } - case DECODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - decoder->enable = (*iarg != 0); - - tvp5150_selmux(c, decoder->input); + struct v4l2_tuner *vt = arg; + int status = tvp5150_read(c, 0x88); + vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0; break; } case VIDIOC_QUERYCTRL: @@ -1191,35 +1106,6 @@ static int tvp5150_command(struct i2c_client *c, return -EINVAL; } - case DECODER_SET_PICTURE: - { - struct video_picture *pic = arg; - if (decoder->bright != pic->brightness) { - /* We want 0 to 255 we get 0-65535 */ - decoder->bright = pic->brightness; - tvp5150_write(c, TVP5150_BRIGHT_CTL, - decoder->bright >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 255 we get 0-65535 */ - decoder->contrast = pic->contrast; - tvp5150_write(c, TVP5150_CONTRAST_CTL, - decoder->contrast >> 8); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 255 we get 0-65535 */ - decoder->sat = pic->colour; - tvp5150_write(c, TVP5150_SATURATION_CTL, - decoder->contrast >> 8); - } - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - tvp5150_write(c, TVP5150_HUE_CTL, - (decoder->hue - 32768) >> 8); - } - break; - } default: return -EINVAL; } -- cgit v1.2.3 From 29fafe9bd09810fa43e5db62eebc23b985f68180 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 1 Apr 2006 16:00:41 -0500 Subject: Kconfig: fix VP-3054 Secondary I2C Bus build configuration menu dependencies From: Michael Krufky This patch fixes a dependency problem that affected the indentation order within the individual frontend selection support menus for cx88-dvb. - created a boolean dependency link for VIDEO_CX88_VP3054, so that it's tristate value will be the same as that of VIDEO_CX88_DVB. - VIDEO_CX88_VP3054 is automatically selected by VIDEO_CX88_DVB_ALL_FRONTENDS, but is otherwise selected by VIDEO_CX88_DVB_VP3054, offered as an option under VIDEO_CX88_DVB_MT352 Signed-off-by: Michael Krufky --- linux/drivers/media/video/cx88/Kconfig | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'linux') 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, -- cgit v1.2.3 From dbe2e81959f002660345a0b09161b230df7765cf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Apr 2006 23:03:23 +0200 Subject: Make msp3400 routing defines more consistent From: Hans Verkuil Renamed various msp3400 routing defines to be more consistent and less confusing. Esp. the MSP_DSP_OUT defines were confusing since it is really a DSP input. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt8xx/bttv-driver.c | 12 ++--- linux/drivers/media/video/em28xx/em28xx-cards.c | 4 +- linux/drivers/media/video/em28xx/em28xx-video.c | 2 +- linux/drivers/media/video/msp3400-kthreads.c | 4 +- linux/drivers/media/video/pvrusb2/pvrusb2-audio.c | 10 ++-- linux/include/media/msp3400.h | 60 +++++++++++------------ 6 files changed, 46 insertions(+), 46 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index ea9f82586..9586f91e3 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -994,12 +994,12 @@ audio_mux(struct bttv *btv, int input, int mute) For now this is sufficient. */ switch (input) { case TVAUDIO_INPUT_RADIO: - route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1, - MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); + route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, + MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; case TVAUDIO_INPUT_EXTERN: - route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, - MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); + route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, + MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; case TVAUDIO_INPUT_INTERN: /* Yes, this is the same input as for RADIO. I doubt @@ -1007,8 +1007,8 @@ audio_mux(struct bttv *btv, int input, int mute) input is the BTTV_BOARD_AVERMEDIA98. I wonder how that was tested. My guess is that the whole INTERN input does not work. */ - route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1, - MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); + route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, + MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; case TVAUDIO_INPUT_TUNER: default: diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 3622019e3..7892587d7 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -152,8 +152,8 @@ struct em28xx_board em28xx_boards[] = { },{ .type = EM28XX_VMUX_SVIDEO, .vmux = 2, - .amux = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, - MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART), + .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, + MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), }}, }, #ifdef CONFIG_XC3028 diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 60feda020..840178958 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -247,7 +247,7 @@ static void video_mux(struct em28xx *dev, int index) if (dev->i2s_speed) em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); route.input = dev->ctl_ainput; - route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA); + route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); /* Note: this is msp3400 specific */ em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route); ainput = EM28XX_AUDIO_SRC_TUNER; diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index aaaa26219..d016a3310 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -888,11 +888,11 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) break; } - if (in == MSP_DSP_OUT_TUNER) + if (in == MSP_DSP_IN_TUNER) source = (source << 8) | 0x20; /* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14 instead of 11, 12, 13. So we add one for that msp version. */ - else if (in >= MSP_DSP_OUT_MAIN_AVC && state->has_dolby_pro_logic) + else if (in >= MSP_DSP_IN_MAIN_AVC && state->has_dolby_pro_logic) source = ((in + 1) << 8) | matrix; else source = (in << 8) | matrix; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c index 79395d540..031412327 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c @@ -74,7 +74,7 @@ static void set_stereo(struct pvr2_msp3400_handler *ctxt) } route.input = MSP_INPUT_DEFAULT; - route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA); + route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); switch (hdw->controls[PVR2_CID_INPUT].value) { case PVR2_CVAL_INPUT_TV: break; @@ -83,14 +83,14 @@ static void set_stereo(struct pvr2_msp3400_handler *ctxt) we're still using the tuner. */ /* HV: actually it is more likely to be the SCART2 input if the ivtv experience is any indication. */ - route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1, - MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); + route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, + MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; case PVR2_CVAL_INPUT_SVIDEO: case PVR2_CVAL_INPUT_COMPOSITE: /* SCART 1 input */ - route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, - MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); + route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, + MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; } pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); diff --git a/linux/include/media/msp3400.h b/linux/include/media/msp3400.h index 0be61a021..6ab854931 100644 --- a/linux/include/media/msp3400.h +++ b/linux/include/media/msp3400.h @@ -80,16 +80,16 @@ */ /* SCART input to DSP selection */ -#define MSP_IN_SCART_1 0 /* Pin SC1_IN */ -#define MSP_IN_SCART_2 1 /* Pin SC2_IN */ -#define MSP_IN_SCART_3 2 /* Pin SC3_IN */ -#define MSP_IN_SCART_4 3 /* Pin SC4_IN */ +#define MSP_IN_SCART1 0 /* Pin SC1_IN */ +#define MSP_IN_SCART2 1 /* Pin SC2_IN */ +#define MSP_IN_SCART3 2 /* Pin SC3_IN */ +#define MSP_IN_SCART4 3 /* Pin SC4_IN */ #define MSP_IN_MONO 6 /* Pin MONO_IN */ #define MSP_IN_MUTE 7 /* Mute DSP input */ #define MSP_SCART_TO_DSP(in) (in) /* Tuner input to demodulator and DSP selection */ -#define MSP_IN_TUNER_1 0 /* Analog Sound IF input pin ANA_IN1 */ -#define MSP_IN_TUNER_2 1 /* Analog Sound IF input pin ANA_IN2 */ +#define MSP_IN_TUNER1 0 /* Analog Sound IF input pin ANA_IN1 */ +#define MSP_IN_TUNER2 1 /* Analog Sound IF input pin ANA_IN2 */ #define MSP_TUNER_TO_DSP(in) ((in) << 3) /* The msp has up to 5 DSP outputs, each output can independently select @@ -109,14 +109,14 @@ DSP. This is currently not implemented. Also not implemented is the multi-channel capable I2S3 input of the 44x0G. If someone can demonstrate a need for one of those features then additional support can be added. */ -#define MSP_DSP_OUT_TUNER 0 /* Tuner output */ -#define MSP_DSP_OUT_SCART 2 /* SCART output */ -#define MSP_DSP_OUT_I2S1 5 /* I2S1 output */ -#define MSP_DSP_OUT_I2S2 6 /* I2S2 output */ -#define MSP_DSP_OUT_I2S3 7 /* I2S3 output */ -#define MSP_DSP_OUT_MAIN_AVC 11 /* MAIN AVC processed output */ -#define MSP_DSP_OUT_MAIN 12 /* MAIN output */ -#define MSP_DSP_OUT_AUX 13 /* AUX output */ +#define MSP_DSP_IN_TUNER 0 /* Tuner DSP input */ +#define MSP_DSP_IN_SCART 2 /* SCART DSP input */ +#define MSP_DSP_IN_I2S1 5 /* I2S1 DSP input */ +#define MSP_DSP_IN_I2S2 6 /* I2S2 DSP input */ +#define MSP_DSP_IN_I2S3 7 /* I2S3 DSP input */ +#define MSP_DSP_IN_MAIN_AVC 11 /* MAIN AVC processed DSP input */ +#define MSP_DSP_IN_MAIN 12 /* MAIN DSP input */ +#define MSP_DSP_IN_AUX 13 /* AUX DSP input */ #define MSP_DSP_TO_MAIN(in) ((in) << 4) #define MSP_DSP_TO_AUX(in) ((in) << 8) #define MSP_DSP_TO_SCART1(in) ((in) << 12) @@ -125,16 +125,16 @@ /* Output SCART select: the SCART outputs can select which input to use. */ -#define MSP_OUT_SCART1 0 /* SCART1 input, bypassing the DSP */ -#define MSP_OUT_SCART2 1 /* SCART2 input, bypassing the DSP */ -#define MSP_OUT_SCART3 2 /* SCART3 input, bypassing the DSP */ -#define MSP_OUT_SCART4 3 /* SCART4 input, bypassing the DSP */ -#define MSP_OUT_SCART1_DA 4 /* DSP SCART1 output */ -#define MSP_OUT_SCART2_DA 5 /* DSP SCART2 output */ -#define MSP_OUT_MONO 6 /* MONO input, bypassing the DSP */ -#define MSP_OUT_MUTE 7 /* MUTE output */ -#define MSP_OUT_TO_SCART1(in) (in) -#define MSP_OUT_TO_SCART2(in) ((in) << 4) +#define MSP_SC_IN_SCART1 0 /* SCART1 input, bypassing the DSP */ +#define MSP_SC_IN_SCART2 1 /* SCART2 input, bypassing the DSP */ +#define MSP_SC_IN_SCART3 2 /* SCART3 input, bypassing the DSP */ +#define MSP_SC_IN_SCART4 3 /* SCART4 input, bypassing the DSP */ +#define MSP_SC_IN_DSP_SCART1 4 /* DSP SCART1 input */ +#define MSP_SC_IN_DSP_SCART2 5 /* DSP SCART2 input */ +#define MSP_SC_IN_MONO 6 /* MONO input, bypassing the DSP */ +#define MSP_SC_IN_MUTE 7 /* MUTE output */ +#define MSP_SC_TO_SCART1(in) (in) +#define MSP_SC_TO_SCART2(in) ((in) << 4) /* Shortcut macros */ #define MSP_INPUT(sc, t, main_aux_src, sc_i2s_src) \ @@ -145,14 +145,14 @@ MSP_DSP_TO_SCART1(sc_i2s_src) | \ MSP_DSP_TO_SCART2(sc_i2s_src) | \ MSP_DSP_TO_I2S(sc_i2s_src)) -#define MSP_INPUT_DEFAULT MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, \ - MSP_DSP_OUT_TUNER, MSP_DSP_OUT_TUNER) +#define MSP_INPUT_DEFAULT MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \ + MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER) #define MSP_OUTPUT(sc) \ - (MSP_OUT_TO_SCART1(sc) | \ - MSP_OUT_TO_SCART2(sc)) + (MSP_SC_TO_SCART1(sc) | \ + MSP_SC_TO_SCART2(sc)) /* This equals the RESET position of the msp3400 ACB register */ -#define MSP_OUTPUT_DEFAULT (MSP_OUT_TO_SCART1(MSP_OUT_SCART3) | \ - MSP_OUT_TO_SCART2(MSP_OUT_SCART1_DA)) +#define MSP_OUTPUT_DEFAULT (MSP_SC_TO_SCART1(MSP_SC_IN_SCART3) | \ + MSP_SC_TO_SCART2(MSP_SC_IN_DSP_SCART1)) /* Tuner inputs vs. msp version */ /* Chip TUNER_1 TUNER_2 -- cgit v1.2.3 From cbea0cdfe46b67fb696b0a045e8ace7dddf4ca49 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 1 Apr 2006 20:36:50 -0600 Subject: Split out PVR USB2 model 24xxx hardware support to a config option From: Mike Isely Since there are lingering stability problems with support of the newer PVR USB2 model 24xxx series hardware, I have isolate those changes with a config option. This commit leaves that option off. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/Kconfig | 18 ++++++++++++++++++ linux/drivers/media/video/pvrusb2/Makefile | 6 +++++- .../drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 2 ++ linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 8 ++++++++ .../media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | 4 ++++ 5 files changed, 37 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig index b22ab7f5f..629dc4e05 100644 --- a/linux/drivers/media/video/pvrusb2/Kconfig +++ b/linux/drivers/media/video/pvrusb2/Kconfig @@ -13,6 +13,24 @@ 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 diff --git a/linux/drivers/media/video/pvrusb2/Makefile b/linux/drivers/media/video/pvrusb2/Makefile index b0d3064ef..53fccce4f 100644 --- a/linux/drivers/media/video/pvrusb2/Makefile +++ b/linux/drivers/media/video/pvrusb2/Makefile @@ -1,13 +1,17 @@ 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-context.o pvrusb2-io.o pvrusb2-ioread.o \ - pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.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-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 189075bbe..9c5f0f74c 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -199,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 diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 32bdaeba7..f0de1e154 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -38,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 { } }; @@ -46,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}; @@ -625,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; @@ -636,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 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; -- cgit v1.2.3 From 6499c4b8ab1554b94358bc6d69709e1c22d8b606 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Apr 2006 04:14:57 -0300 Subject: Fix some errors on bttv_risc_overlay From: Duncan Sands There are tree mistakes on bttv_risc_overlay. 1) When skip_odd is true, the number of lines for which instructions are written is (height+1)/2, not height/2. 2) This occurs when clipping: the number of instruction bytes written can be as much as 8 + 12*nclips, not 8 + 8*nclips, as currently estimated. 3) Coverity check were wrong with nskips=0, since it means that it can clipped at most one line. Signed-off-by: Duncan Sands Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt8xx/bttv-risc.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-risc.c b/linux/drivers/media/video/bt8xx/bttv-risc.c index 53dfe0f4d..4401d7320 100644 --- a/linux/drivers/media/video/bt8xx/bttv-risc.c +++ b/linux/drivers/media/video/bt8xx/bttv-risc.c @@ -234,7 +234,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, const struct bttv_format *fmt, struct bttv_overlay *ov, int skip_even, int skip_odd) { - int instructions,rc,line,maxy,start,end,skip,nskips; + int dwords,rc,line,maxy,start,end,skip,nskips; struct btcx_skiplist *skips; u32 *rp,ri,ra; u32 addr; @@ -243,12 +243,12 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL))) return -ENOMEM; - /* estimate risc mem: worst case is (clip+1) * lines instructions + /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions + sync + jump (all 2 dwords) */ - instructions = (ov->nclips + 1) * - ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height); - instructions += 2; - if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) { + dwords = (3 * ov->nclips + 2) * + ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height); + dwords += 4; + if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) { kfree(skips); return rc; } @@ -277,8 +277,6 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, if (line > maxy) btcx_calc_skips(line, ov->w.width, &maxy, skips, &nskips, ov->clips, ov->nclips); - else - nskips = 0; /* write out risc code */ for (start = 0, skip = 0; start < ov->w.width; start = end) { -- cgit v1.2.3 From ccc9a7ea538fa702d897eead24eefc64bd4960d9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Apr 2006 04:51:51 -0300 Subject: Kernel-sync patch From: Mauro Carvalho Chehab Mostly because of documentation renames from mkfrufy. Also, a small fix at cpia2. kernel-sync Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 14 +++++++------- linux/drivers/media/video/cpia2/cpia2.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 911da5210..98f7201cd 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -439,8 +439,8 @@ config USB_OV511 depends on USB && VIDEO_DEV ---help--- Say Y here if you want to connect this type of camera to your - computer's USB port. See for more - information and for a list of supported cameras. + computer's USB port. See + for more information and for a list of supported cameras. To compile this driver as a module, choose M here: the module will be called ov511. @@ -450,8 +450,8 @@ config USB_SE401 depends on USB && VIDEO_DEV ---help--- Say Y here if you want to connect this type of camera to your - computer's USB port. See for more - information and for a list of supported cameras. + computer's USB port. See + for more information and for a list of supported cameras. To compile this driver as a module, choose M here: the module will be called se401. @@ -464,8 +464,8 @@ config USB_STV680 ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. This includes the Pencam line of cameras. - See for more information and for - a list of supported cameras. + See for more information + and for a list of supported cameras. To compile this driver as a module, choose M here: the module will be called stv680. @@ -483,7 +483,7 @@ config USB_W9968CF resolutions and framerates, but cannot be included in the official Linux kernel for performance purposes. - See for more informations. + See for more info. To compile this driver as a module, choose M here: the module will be called w9968cf. diff --git a/linux/drivers/media/video/cpia2/cpia2.h b/linux/drivers/media/video/cpia2/cpia2.h index 7480c1827..a53056c82 100644 --- a/linux/drivers/media/video/cpia2/cpia2.h +++ b/linux/drivers/media/video/cpia2/cpia2.h @@ -462,7 +462,7 @@ int cpia2_init_camera(struct camera_data *cam); int cpia2_allocate_buffers(struct camera_data *cam); void cpia2_free_buffers(struct camera_data *cam); long cpia2_read(struct camera_data *cam, - char __user *buf, unsigned long count, int noblock); + char *buf, unsigned long count, int noblock); unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, poll_table *wait); int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma); -- cgit v1.2.3 From 3b4a71877b2fb7be1919cc2e0b1699e6b30e30a7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 2 Apr 2006 13:21:02 +0200 Subject: Improve line-in handling From: Hans Verkuil - improve handling of the EXTERN input: don't start an unnecessary carrier scan - improve the LOG_STATUS output - ensure that a carrier scan is started again when switching back to the tuner. - set correct prescale for L-NICAM Signed-off-by: Hans Verkuil --- linux/drivers/media/video/msp3400-driver.c | 23 +++++++++++----- linux/drivers/media/video/msp3400-kthreads.c | 40 +++++++++++++++++++--------- 2 files changed, 45 insertions(+), 18 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index 79e2bdb11..837894adb 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -726,22 +726,31 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) int sc1_out = rt->output & 0xf; int sc2_out = (rt->output >> 4) & 0xf; u16 val, reg; + int i; + int extern_input = 1; if (state->routing.input == rt->input && state->routing.output == rt->output) break; state->routing = *rt; + /* check if the tuner input is used */ + for (i = 0; i < 5; i++) { + if (((rt->input >> (4 + i * 4)) & 0xf) == 0) + extern_input = 0; + } + if (extern_input) + state->mode = MSP_MODE_EXTERN; + else + state->mode = MSP_MODE_AM_DETECT; msp_set_scart(client, sc_in, 0); msp_set_scart(client, sc1_out, 1); msp_set_scart(client, sc2_out, 2); msp_set_audmode(client); reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; val = msp_read_dem(client, reg); - if (tuner != ((val >> 8) & 1)) { - msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); - /* wake thread when a new tuner input is chosen */ - msp_wake_thread(client); - } + msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); + /* wake thread when a new input is chosen */ + msp_wake_thread(client); break; } @@ -846,7 +855,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) case MSP_MODE_EXTERN: p = "External input"; break; default: p = "unknown"; break; } - if (state->opmode == OPMODE_MANUAL) { + if (state->mode == MSP_MODE_EXTERN) { + v4l_info(client, "Mode: %s\n", p); + } else if (state->opmode == OPMODE_MANUAL) { v4l_info(client, "Mode: %s (%s%s)\n", p, (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index d016a3310..20702d71a 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -250,19 +250,21 @@ static void msp3400c_set_audmode(struct i2c_client *client) the hardware does not support SAP. So the rxsubchans combination of STEREO | LANG2 does not occur. */ - /* switch to mono if only mono is available */ - if (state->rxsubchans == V4L2_TUNER_SUB_MONO) - audmode = V4L2_TUNER_MODE_MONO; - /* if bilingual */ - else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { - /* and mono or stereo, then fallback to lang1 */ - if (audmode == V4L2_TUNER_MODE_MONO || - audmode == V4L2_TUNER_MODE_STEREO) - audmode = V4L2_TUNER_MODE_LANG1; + if (state->mode != MSP_MODE_EXTERN) { + /* switch to mono if only mono is available */ + if (state->rxsubchans == V4L2_TUNER_SUB_MONO) + audmode = V4L2_TUNER_MODE_MONO; + /* if bilingual */ + else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { + /* and mono or stereo, then fallback to lang1 */ + if (audmode == V4L2_TUNER_MODE_MONO || + audmode == V4L2_TUNER_MODE_STEREO) + audmode = V4L2_TUNER_MODE_LANG1; + } + /* if stereo, and audmode is not mono, then switch to stereo */ + else if (audmode != V4L2_TUNER_MODE_MONO) + audmode = V4L2_TUNER_MODE_STEREO; } - /* if stereo, and audmode is not mono, then switch to stereo */ - else if (audmode != V4L2_TUNER_MODE_MONO) - audmode = V4L2_TUNER_MODE_STEREO; /* switch demodulator */ switch (state->mode) { @@ -494,6 +496,7 @@ int msp3400c_thread(void *data) /* no carrier scan, just unmute */ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); state->scan_in_progress = 0; + state->rxsubchans = V4L2_TUNER_SUB_STEREO; msp_set_audio(client); continue; } @@ -986,6 +989,14 @@ int msp34xxg_thread(void *data) #endif break; + if (state->mode == MSP_MODE_EXTERN) { + /* no carrier scan needed, just unmute */ + v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); + state->scan_in_progress = 0; + msp_set_audio(client); + continue; + } + /* setup the chip*/ msp34xxg_reset(client); state->std = state->radio ? 0x40 : msp_standard; @@ -1017,6 +1028,11 @@ int msp34xxg_thread(void *data) v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n", msp_standard_std_name(state->std), state->std); + if (state->std == 9) { + /* AM NICAM mode */ + msp_write_dsp(client, 0x0e, 0x7c00); + } + /* unmute: dispatch sound to scart output, set scart volume */ msp_set_audio(client); -- cgit v1.2.3 From 33ba11f17dbf2c000c797475db2c6b68b7d33662 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 2 Apr 2006 13:42:32 +0200 Subject: Delimit LOG_STATUS output with standardized lines From: Hans Verkuil Add standard lines before/after the LOG_STATUS output: this allows easy reading and parsing from the kernel log with e.g. ivtvctl (to be added to v4l-dvb at a later date). Signed-off-by: Hans Verkuil --- linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index fe7045e8f..56d15c10d 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -673,7 +673,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_LOG_STATUS: { + int nr = pvr2_hdw_get_unit_number(hdw); + + printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); pvr2_hdw_trigger_module_log(hdw); + printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); + ret = 0; break; } -- cgit v1.2.3 From 1022e152b0486dbbc19e49c9bbbdec12a0637418 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Apr 2006 09:07:01 -0300 Subject: [PATCH] mark f_ops const in the inode From: Arjan van de Ven Mark the f_ops members of inodes as const, as well as fix the ripple-through this causes by places that copy this f_ops and then "do stuff" with it. kernel-sync Signed-off-by: Arjan van de Ven Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- linux/drivers/media/dvb/dvb-core/dvbdev.c | 2 +- linux/drivers/media/video/videodev.c | 2 +- linux/include/linux/videodev2.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 123ea8344..85d6a6c65 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -93,7 +93,7 @@ static int dvb_device_open(struct inode *inode, struct file *file) if (dvbdev && dvbdev->fops) { int err = 0; - struct file_operations *old_fops; + const struct file_operations *old_fops; file->private_data = dvbdev; old_fops = file->f_op; diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 8747de34a..e54b8d9f7 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -111,7 +111,7 @@ static int video_open(struct inode *inode, struct file *file) unsigned int minor = iminor(inode); int err = 0; struct video_device *vfl; - struct file_operations *old_fops; + const struct file_operations *old_fops; if(minor>=VIDEO_NUM_DEVICES) return -ENODEV; diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index b87334d72..922980c61 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -84,7 +84,7 @@ struct video_device int minor; /* device ops + callbacks */ - struct file_operations *fops; + const struct file_operations *fops; void (*release)(struct video_device *vfd); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -- cgit v1.2.3 From f538287daa555411910d95317990cce75e57225a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Apr 2006 09:35:05 -0300 Subject: cpia2: fix function prototype From: Randy Dunlap Fix address space warning (from sparse): drivers/media/video/cpia2/cpia2_core.c:2355:6: error: symbol 'cpia2_read' redeclared with different type (originally declared at drivers/media/video/cpia2/cpia2.h:458) - incompatible argument 2 (different address spaces) kernel-sync Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cpia2/cpia2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cpia2/cpia2.h b/linux/drivers/media/video/cpia2/cpia2.h index a53056c82..7480c1827 100644 --- a/linux/drivers/media/video/cpia2/cpia2.h +++ b/linux/drivers/media/video/cpia2/cpia2.h @@ -462,7 +462,7 @@ int cpia2_init_camera(struct camera_data *cam); int cpia2_allocate_buffers(struct camera_data *cam); void cpia2_free_buffers(struct camera_data *cam); long cpia2_read(struct camera_data *cam, - char *buf, unsigned long count, int noblock); + char __user *buf, unsigned long count, int noblock); unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, poll_table *wait); int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma); -- cgit v1.2.3 From 6c14e144cdc5613c2d56f1a991b87366184c634c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Apr 2006 09:36:36 -0300 Subject: Sync I2C ID's From: Mauro Carvalho Chehab kernel-sync Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/i2c-id.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux') diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h index 679b46a6a..c8b81f419 100644 --- a/linux/include/linux/i2c-id.h +++ b/linux/include/linux/i2c-id.h @@ -108,6 +108,10 @@ #define I2C_DRIVERID_UPD64083 78 /* upd64083 video processor */ #define I2C_DRIVERID_UPD64031A 79 /* upd64031a video processor */ #define I2C_DRIVERID_SAA717X 80 /* saa717x video encoder */ +#define I2C_DRIVERID_DS1672 81 /* Dallas/Maxim DS1672 RTC */ +#define I2C_DRIVERID_X1205 82 /* Xicor/Intersil X1205 RTC */ +#define I2C_DRIVERID_PCF8563 83 /* Philips PCF8563 RTC */ +#define I2C_DRIVERID_RS5C372 84 /* Ricoh RS5C372 RTC */ #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ -- cgit v1.2.3 From 7d27e5f3b2bbe8ca82a41dce5203a67d7595ab09 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 2 Apr 2006 17:50:42 +0200 Subject: Add support for VIDIOC_INT_S_CRYSTAL_FREQ internal command. From: Hans Verkuil Some saa7115-based cards use a different crystal frequency and a different audio clock generation. Add a new VIDIOC_INT_S_CRYSTAL_FREQ command to be able to set these values. Also change the default APLL setting to 0. It makes no sense to have the audio clock independent from the video clock, this can lead to audio/video synchronization problems. Setting this to 0 is also consistent with the old saa7114.c source and the way the Hauppauge Windows driver sets it. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7115.c | 51 +++++++++++++++++++++++++++------ linux/drivers/media/video/v4l2-common.c | 9 +++++- linux/include/media/saa7115.h | 11 ++++++- linux/include/media/v4l2-common.h | 11 +++++++ 4 files changed, 72 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 1ecfacea5..6c40aa397 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -83,6 +83,10 @@ struct saa7115_state { int sat; enum v4l2_chip_ident ident; u32 audclk_freq; + u32 crystal_freq; + u8 ucgc; + u8 cgcdiv; + u8 apll; }; /* ----------------------------------------------------------------------- */ @@ -388,10 +392,6 @@ static const unsigned char saa7113_init_auto_input[] = { #endif static const unsigned char saa7115_init_misc[] = { - 0x38, 0x03, /* audio stuff */ - 0x39, 0x10, - 0x3a, 0x08, - 0x81, 0x01, /* reg 0x15,0x16 define blanking window */ 0x82, 0x00, 0x83, 0x01, /* I port settings */ @@ -597,6 +597,7 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) u32 acni; u32 hz; u64 f; + u8 acc = 0; /* reg 0x3a, audio clock control */ v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); @@ -604,18 +605,34 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) if (freq < 32000 || freq > 48000) return -EINVAL; + /* The saa7113 has no audio clock */ + if (state->ident == V4L2_IDENT_SAA7113) + return 0; + /* hz is the refresh rate times 100 */ hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ acpf = (25600 * freq) / hz; /* acni = (256 * freq * 2^23) / crystal_frequency = (freq * 2^(8+23)) / crystal_frequency = - (freq << 31) / 32.11 MHz */ + (freq << 31) / crystal_frequency */ f = freq; f = f << 31; - do_div(f, 32110000); + do_div(f, state->crystal_freq); acni = f; + if (state->ucgc) { + acpf = acpf * state->cgcdiv / 16; + acni = acni * state->cgcdiv / 16; + acc = 0x80; + if (state->cgcdiv == 3) + acc |= 0x40; + } + if (state->apll) + acc |= 0x08; + saa7115_write(client, 0x38, 0x03); + saa7115_write(client, 0x39, 0x10); + saa7115_write(client, 0x3a, acc); saa7115_write(client, 0x30, acpf & 0xff); saa7115_write(client, 0x31, (acpf >> 8) & 0xff); saa7115_write(client, 0x32, (acpf >> 16) & 0x03); @@ -1273,6 +1290,21 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar } break; + case VIDIOC_INT_S_CRYSTAL_FREQ: + { + struct v4l2_crystal_freq *freq = arg; + + if (freq->freq != SAA7115_FREQ_32_11_MHZ && + freq->freq != SAA7115_FREQ_24_576_MHZ) + return -EINVAL; + state->crystal_freq = freq->freq; + state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4; + state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0; + state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0; + saa7115_set_audio_clock_freq(client, state->audclk_freq); + break; + } + case VIDIOC_INT_DECODE_VBI_LINE: saa7115_decode_vbi_line(client, arg); break; @@ -1422,10 +1454,13 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) v4l_dbg(1, debug, client, "writing init values\n"); /* init to 60hz/48khz */ - if (state->ident == V4L2_IDENT_SAA7113) + if (state->ident == V4L2_IDENT_SAA7113) { + state->crystal_freq = SAA7115_FREQ_24_576_MHZ; saa7115_writeregs(client, saa7113_init_auto_input); - else + } else { + state->crystal_freq = SAA7115_FREQ_32_11_MHZ; saa7115_writeregs(client, saa7115_init_auto_input); + } saa7115_writeregs(client, saa7115_init_misc); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 5f71edf32..4b7ef8350 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -351,7 +351,8 @@ static const char *v4l2_int_ioctls[] = { [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING" + [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ" }; #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) @@ -698,6 +699,12 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); break; } + case VIDIOC_INT_S_CRYSTAL_FREQ: + { + struct v4l2_crystal_freq *p=arg; + printk ("%s: freq=%u, flags=0x%x\n", s, p->freq, p->flags); + break; + } case VIDIOC_G_SLICED_VBI_CAP: { struct v4l2_sliced_vbi_cap *p=arg; diff --git a/linux/include/media/saa7115.h b/linux/include/media/saa7115.h index 6b4836f3f..9f0e2285a 100644 --- a/linux/include/media/saa7115.h +++ b/linux/include/media/saa7115.h @@ -1,5 +1,5 @@ /* - saa7115.h - definition for saa7113/4/5 inputs + saa7115.h - definition for saa7113/4/5 inputs and frequency flags Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl) @@ -33,5 +33,14 @@ #define SAA7115_SVIDEO2 8 #define SAA7115_SVIDEO3 9 +/* SAA7115 v4l2_crystal_freq frequency values */ +#define SAA7115_FREQ_32_11_MHZ 32110000 /* 32.11 MHz crystal, SAA7114/5 only */ +#define SAA7115_FREQ_24_576_MHZ 24576000 /* 24.576 MHz crystal */ + +/* SAA7115 v4l2_crystal_freq audio clock control flags */ +#define SAA7115_FREQ_FL_UCGC (1 << 0) /* SA 3A[7], UCGC, SAA7115 only */ +#define SAA7115_FREQ_FL_CGCDIV (1 << 1) /* SA 3A[6], CGCDIV, SAA7115 only */ +#define SAA7115_FREQ_FL_APLL (1 << 2) /* SA 3A[3], APLL, SAA7114/5 only */ + #endif diff --git a/linux/include/media/v4l2-common.h b/linux/include/media/v4l2-common.h index 60c0bc91e..6ffa8eabb 100644 --- a/linux/include/media/v4l2-common.h +++ b/linux/include/media/v4l2-common.h @@ -217,4 +217,15 @@ struct v4l2_routing { #define VIDIOC_INT_S_VIDEO_ROUTING _IOW ('d', 111, struct v4l2_routing) #define VIDIOC_INT_G_VIDEO_ROUTING _IOR ('d', 112, struct v4l2_routing) +struct v4l2_crystal_freq { + u32 freq; /* frequency in Hz of the crystal */ + u32 flags; /* device specific flags */ +}; + +/* Sets the frequency of the crystal used to generate the clocks. + An extra flags field allows device specific configuration regarding + clock frequency dividers, etc. If not used, then set flags to 0. + If the frequency is not supported, then -EINVAL is returned. */ +#define VIDIOC_INT_S_CRYSTAL_FREQ _IOW ('d', 113, struct v4l2_crystal_freq) + #endif /* V4L2_COMMON_H_ */ -- cgit v1.2.3 From cb228051a31b5d0f78a3b3e7e8a960d1658afcf5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 2 Apr 2006 18:35:00 +0200 Subject: Fix video input setting of em28xx, use _INT_S_VIDEO_ROUTING in tvp5150 From: Hans Verkuil - Use new routing input defines in em28xx-cards.c - Fix S-Video settings for tvp5150-based cards (input was copied from saa7115 based cards and worked only because S-Video was selected in the default: case) - Replace VIDIOC_S_INPUT by VIDIOC_INT_S_VIDEO_ROUTING in em28xx-video.c - Remove the now obsolete VIDIOC_S_INPUT handler in saa7115.c - Add VIDIOC_INT_G/S_VIDEO_ROUTING in tvp5150.c - Add new media/tvp5150.h with the routing defines. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/em28xx/em28xx-cards.c | 76 +++++++++++++------------ linux/drivers/media/video/em28xx/em28xx-video.c | 18 +++--- linux/drivers/media/video/saa7115.c | 28 --------- linux/drivers/media/video/tvp5150.c | 45 +++++++++------ linux/include/media/tvp5150.h | 34 +++++++++++ 5 files changed, 113 insertions(+), 88 deletions(-) create mode 100644 linux/include/media/tvp5150.h (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 7892587d7..6b5a8a6b1 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -30,6 +30,8 @@ #include "compat.h" #include #include +#include +#include #include #include #include @@ -47,11 +49,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -65,11 +67,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -83,11 +85,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -101,15 +103,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 2, + .vmux = SAA7115_COMPOSITE2, .amux = 1, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -123,15 +125,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 2, + .vmux = SAA7115_COMPOSITE2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -147,11 +149,11 @@ struct em28xx_board em28xx_boards[] = { /*FIXME: S-Video not tested */ .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 0, + .vmux = TVP5150_COMPOSITE0, .amux = MSP_INPUT_DEFAULT, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 2, + .vmux = TVP5150_SVIDEO, .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), }}, @@ -167,15 +169,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_TVP5150, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 2, + .vmux = TVP5150_COMPOSITE1, .amux = 1, },{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 0, + .vmux = TVP5150_COMPOSITE0, .amux = 0, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = TVP5150_SVIDEO, .amux = 1, }}, }, @@ -189,15 +191,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_TVP5150, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 0, + .vmux = TVP5150_COMPOSITE0, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 2, + .vmux = TVP5150_COMPOSITE1, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = TVP5150_SVIDEO, .amux = 1, }}, }, @@ -213,15 +215,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_TVP5150, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 0, + .vmux = TVP5150_COMPOSITE0, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 2, + .vmux = TVP5150_COMPOSITE1, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = TVP5150_SVIDEO, .amux = 1, }}, }, @@ -236,15 +238,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7114, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 4, + .vmux = SAA7115_COMPOSITE4, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -259,15 +261,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 2, + .vmux = SAA7115_COMPOSITE2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -282,15 +284,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 2, + .vmux = SAA7115_COMPOSITE2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -305,15 +307,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = 2, + .vmux = SAA7115_COMPOSITE2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, @@ -325,11 +327,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, + .vmux = SAA7115_COMPOSITE0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, + .vmux = SAA7115_SVIDEO3, .amux = 1, }}, }, diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 840178958..836e7c7e5 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -192,8 +192,12 @@ static int em28xx_config(struct em28xx *dev) static void em28xx_config_i2c(struct em28xx *dev) { struct v4l2_frequency f; + struct v4l2_routing route; + + route.input = INPUT(dev->ctl_input)->vmux; + route.output = 0; em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); - em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input); + em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); /* configure tuner */ @@ -231,19 +235,19 @@ static void em28xx_empty_framequeues(struct em28xx *dev) static void video_mux(struct em28xx *dev, int index) { - int input, ainput; + int ainput; + struct v4l2_routing route; - input = INPUT(index)->vmux; + route.input = INPUT(index)->vmux; + route.output = 0; dev->ctl_input = index; dev->ctl_ainput = INPUT(index)->amux; - em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input); + em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); - em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); + em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,route.input,dev->ctl_ainput); if (dev->has_msp34xx) { - struct v4l2_routing route; - if (dev->i2s_speed) em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); route.input = dev->ctl_ainput; diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 6c40aa397..ea7c7c65b 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1251,34 +1251,6 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar break; } - case VIDIOC_G_INPUT: - *(int *)arg = state->input; - break; - - case VIDIOC_S_INPUT: - v4l_dbg(1, debug, client, "decoder set input %d\n", *iarg); - /* inputs from 0-9 are available */ - if (*iarg < 0 || *iarg > 9) { - return -EINVAL; - } - - if (state->input == *iarg) - break; - v4l_dbg(1, debug, client, "now setting %s input\n", - *iarg >= 6 ? "S-Video" : "Composite"); - state->input = *iarg; - - /* select mode */ - saa7115_write(client, 0x02, - (saa7115_read(client, 0x02) & 0xf0) | - state->input); - - /* bypass chrominance trap for modes 6..9 */ - saa7115_write(client, 0x09, - (saa7115_read(client, 0x09) & 0x7f) | - (state->input < 6 ? 0x0 : 0x80)); - break; - case VIDIOC_STREAMON: case VIDIOC_STREAMOFF: v4l_dbg(1, debug, client, "%s output\n", diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index aa7139089..7cafcd52b 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -11,6 +11,7 @@ #include #include #include +#include #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #include #include @@ -116,7 +117,7 @@ struct tvp5150 { struct i2c_client *client; v4l2_std_id norm; /* Current set standard */ - int input; + struct v4l2_routing route; int enable; int bright; int contrast; @@ -314,29 +315,26 @@ static void dump_reg(struct i2c_client *c) /**************************************************************************** Basic functions ****************************************************************************/ -enum tvp5150_input { - TVP5150_ANALOG_CH0 = 0, - TVP5150_SVIDEO = 1, - TVP5150_ANALOG_CH1 = 2, - TVP5150_BLACK_SCREEN = 8 -}; -static inline void tvp5150_selmux(struct i2c_client *c, - enum tvp5150_input input) +static inline void tvp5150_selmux(struct i2c_client *c) { int opmode=0; - struct tvp5150 *decoder = i2c_get_clientdata(c); + int input = 0; - if (!decoder->enable) - input |= TVP5150_BLACK_SCREEN; + if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable) + input = 8; switch (input) { - case TVP5150_ANALOG_CH0: - case TVP5150_ANALOG_CH1: + case TVP5150_COMPOSITE1: + input |= 2; + /* fall through */ + case TVP5150_COMPOSITE0: opmode=0x30; /* TV Mode */ break; + case TVP5150_SVIDEO: default: + input |= 1; opmode=0; /* Auto Mode */ break; } @@ -839,7 +837,7 @@ static inline void tvp5150_reset(struct i2c_client *c) tvp5150_vdp_init(c, vbi_ram_default); /* Selects decoder input */ - tvp5150_selmux(c, decoder->input); + tvp5150_selmux(c); /* Initializes TVP5150 to stream enabled values */ tvp5150_write_inittab(c, tvp5150_init_enable); @@ -909,6 +907,21 @@ static int tvp5150_command(struct i2c_client *c, case VIDIOC_INT_RESET: tvp5150_reset(c); break; + case VIDIOC_INT_G_VIDEO_ROUTING: + { + struct v4l2_routing *route = arg; + + *route = decoder->route; + break; + } + case VIDIOC_INT_S_VIDEO_ROUTING: + { + struct v4l2_routing *route = arg; + + decoder->route = *route; + tvp5150_selmux(c); + break; + } case VIDIOC_S_STD: if (decoder->norm == *(v4l2_std_id *)arg) break; @@ -1167,7 +1180,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, rv = i2c_attach_client(c); core->norm = V4L2_STD_ALL; /* Default is autodetect */ - core->input = 2; + core->route.input = TVP5150_COMPOSITE1; core->enable = 1; core->bright = 32768; core->contrast = 32768; diff --git a/linux/include/media/tvp5150.h b/linux/include/media/tvp5150.h new file mode 100644 index 000000000..72bd2a2b8 --- /dev/null +++ b/linux/include/media/tvp5150.h @@ -0,0 +1,34 @@ +/* + tvp5150.h - definition for tvp5150 inputs + + Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _TVP5150_H_ +#define _TVP5150_H_ + +/* TVP5150 HW inputs */ +#define TVP5150_COMPOSITE0 0 +#define TVP5150_COMPOSITE1 1 +#define TVP5150_SVIDEO 2 + +/* TVP5150 HW outputs */ +#define TVP5150_NORMAL 0 +#define TVP5150_BLACK_SCREEN 1 + +#endif + -- cgit v1.2.3 From 8f854188187cc4a15f5f3f775fd4aa0b1eff2457 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 2 Apr 2006 18:11:10 -0400 Subject: removed trailing newlines From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/common/ir-functions.c | 1 - linux/drivers/media/common/ir-keymaps.c | 1 - 2 files changed, 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/ir-functions.c b/linux/drivers/media/common/ir-functions.c index 8b7dd6e3e..3b988b012 100644 --- a/linux/drivers/media/common/ir-functions.c +++ b/linux/drivers/media/common/ir-functions.c @@ -278,4 +278,3 @@ EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); * c-basic-offset: 8 * End: */ - diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index 03c4a7c50..1cdd5b0df 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -1476,4 +1476,3 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); - -- cgit v1.2.3 From b1afc839e4484e8b37d6a818f7135d9fb3f476dd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Apr 2006 22:40:33 -0300 Subject: Clean up some cruft in or51132 frontend From: Trent Piepho There is some old code in the or51133 firmware loading function that has no effect. Left a comment to in case it helps someone trying to reverse engineer the chip. kernel-sync with V4L/DVB (3708a) Signed-off-by: Trent Piepho Signed-off-by: Andrew de Quincey Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/or51132.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c index 80e0f2812..dca1de555 100644 --- a/linux/drivers/media/dvb/frontends/or51132.c +++ b/linux/drivers/media/dvb/frontends/or51132.c @@ -106,9 +106,8 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware { struct or51132_state* state = fe->demodulator_priv; static u8 run_buf[] = {0x7F,0x01}; - static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; - u8 rec_buf[14]; - u8 cmd_buf[14]; + u8 rec_buf[8]; + u8 cmd_buf[3]; u32 firmwareAsize, firmwareBsize; int i,ret; @@ -157,7 +156,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x10; cmd_buf[1] = 0x10; cmd_buf[2] = 0x00; - cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,3))) { @@ -167,8 +165,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x04; cmd_buf[1] = 0x17; - cmd_buf[2] = 0x00; - cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,2))) { @@ -178,8 +174,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x00; cmd_buf[1] = 0x00; - cmd_buf[2] = 0x00; - cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,2))) { @@ -189,7 +183,11 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware for(i=0;i<4;i++) { msleep(20); /* 20ms */ - get_ver_buf[4] = i+1; + /* One apon a time, this command might have had something + to do with getting the firmware version, but it's + not used anymore: + {0x04,0x00,0x30,0x00,i+1} */ + /* Read 8 bytes, two bytes at a time */ if ((ret = i2c_readbytes(state,state->config->demod_address, &rec_buf[i*2],2))) { printk(KERN_WARNING @@ -208,7 +206,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x10; cmd_buf[1] = 0x00; cmd_buf[2] = 0x00; - cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,3))) { -- cgit v1.2.3 From 30b707f350a19c509cef7bc77307e7103ff0905c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 3 Apr 2006 00:29:09 -0400 Subject: fix spelling error / typo in comments From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/or51132.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c index dca1de555..a2a19aeb3 100644 --- a/linux/drivers/media/dvb/frontends/or51132.c +++ b/linux/drivers/media/dvb/frontends/or51132.c @@ -183,7 +183,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware for(i=0;i<4;i++) { msleep(20); /* 20ms */ - /* One apon a time, this command might have had something + /* Once upon a time, this command might have had something to do with getting the firmware version, but it's not used anymore: {0x04,0x00,0x30,0x00,i+1} */ -- cgit v1.2.3 From e375e2853810cf2cc8f734369c90b7c007d72a3f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 3 Apr 2006 07:53:40 -0300 Subject: Change all emails to the currently used one. From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt8xx/bttv-cards.c | 2 +- linux/drivers/media/video/cx88/cx88-alsa.c | 4 ++-- linux/drivers/media/video/em28xx/em28xx-cards.c | 2 +- linux/drivers/media/video/em28xx/em28xx-core.c | 2 +- linux/drivers/media/video/em28xx/em28xx-i2c.c | 2 +- linux/drivers/media/video/em28xx/em28xx-input.c | 2 +- linux/drivers/media/video/em28xx/em28xx-video.c | 4 ++-- linux/drivers/media/video/em28xx/em28xx.h | 2 +- linux/drivers/media/video/tea5761.c | 2 +- linux/drivers/media/video/tea5767.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 51e47b7cc..f3e3c624d 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -2786,7 +2786,7 @@ struct tvcard bttv_tvcards[] = { }, /* ---- card 0x88---------------------------------- */ [BTTV_BOARD_ACORP_Y878F] = { - /* Mauro Carvalho Chehab */ + /* Mauro Carvalho Chehab */ .name = "Acorp Y878F", .video_inputs = 3, .audio_inputs = 1, diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index 80aef2421..df82e8251 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -5,7 +5,7 @@ * PCI function #1 of the cx2388x. * * (c) 2005,2006 Ricardo Cerqueira - * (c) 2005 Mauro Carvalho Chehab + * (c) 2005 Mauro Carvalho Chehab * Based on a dummy cx88 module by Gerd Knorr * Based on dummy.c by Jaroslav Kysela * @@ -137,7 +137,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); MODULE_AUTHOR("Ricardo Cerqueira"); -MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_AUTHOR("Mauro Carvalho Chehab "); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," "{{Conexant,23882}," diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 6b5a8a6b1..84b764b7d 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index febf1188e..91422b642 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index b531f2839..c077c39c2 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify diff --git a/linux/drivers/media/video/em28xx/em28xx-input.c b/linux/drivers/media/video/em28xx/em28xx-input.c index a8d3cd4b0..38fe35da8 100644 --- a/linux/drivers/media/video/em28xx/em28xx-input.c +++ b/linux/drivers/media/video/em28xx/em28xx-input.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 836e7c7e5..1093a68f0 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer Some parts based on SN9C10x PC Camera Controllers GPL driver made @@ -49,7 +49,7 @@ #define DRIVER_AUTHOR "Ludovico Cavedon , " \ "Markus Rechberger , " \ - "Mauro Carvalho Chehab , " \ + "Mauro Carvalho Chehab , " \ "Sascha Sommer " #define DRIVER_NAME "em28xx" diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index c560ab329..97744214b 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -3,7 +3,7 @@ Copyright (C) 2005 Markus Rechberger Ludovico Cavedon - Mauro Carvalho Chehab + Mauro Carvalho Chehab Based on the em2800 driver from Sascha Sommer diff --git a/linux/drivers/media/video/tea5761.c b/linux/drivers/media/video/tea5761.c index 785cd105d..a0f075ed7 100644 --- a/linux/drivers/media/video/tea5761.c +++ b/linux/drivers/media/video/tea5761.c @@ -4,7 +4,7 @@ * * $Id: tea5761.c,v 1.5 2006/01/11 21:01:01 hverkuil Exp $ * - * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) + * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) * This code is placed under the terms of the GNU General Public License * */ diff --git a/linux/drivers/media/video/tea5767.c b/linux/drivers/media/video/tea5767.c index e8bf32ec1..43fe70fec 100644 --- a/linux/drivers/media/video/tea5767.c +++ b/linux/drivers/media/video/tea5767.c @@ -4,7 +4,7 @@ * * $Id: tea5767.c,v 1.36 2006/01/15 17:04:52 hverkuil Exp $ * - * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) + * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) * This code is placed under the terms of the GNU General Public License * * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa -- cgit v1.2.3 From cc7536722d24a3deec8ac51616e26f5dc267f112 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 3 Apr 2006 23:49:27 -0400 Subject: fix warning: assignment discards qualifiers from pointer target type From: Michael Krufky The following warning in all kernels < 2.6.17 is caused by changeset a875912f0aada25949e3201bcd97e177040fa782 : http://linuxtv.org/hg/v4l-dvb?cmd=changeset;node=a875912f0aad videodev.c: In function 'video_open': videodev.c:131: warning: assignment discards qualifiers from pointer target type videodev.c:136: warning: assignment discards qualifiers from pointer target type dvbdev.c: In function 'dvb_device_open': dvbdev.c:105: warning: assignment discards qualifiers from pointer target type This changeset restores backwards-compatability. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-core/dvbdev.c | 4 ++++ linux/drivers/media/video/videodev.c | 4 ++++ linux/include/linux/videodev2.h | 4 ++++ 3 files changed, 12 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 85d6a6c65..9b824c31b 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -93,7 +93,11 @@ static int dvb_device_open(struct inode *inode, struct file *file) if (dvbdev && dvbdev->fops) { int err = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) const struct file_operations *old_fops; +#else + struct file_operations *old_fops; +#endif file->private_data = dvbdev; old_fops = file->f_op; diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index e54b8d9f7..c6d0825c8 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -111,7 +111,11 @@ static int video_open(struct inode *inode, struct file *file) unsigned int minor = iminor(inode); int err = 0; struct video_device *vfl; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) const struct file_operations *old_fops; +#else + struct file_operations *old_fops; +#endif if(minor>=VIDEO_NUM_DEVICES) return -ENODEV; diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 922980c61..54b8aca85 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -84,7 +84,11 @@ struct video_device int minor; /* device ops + callbacks */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) const struct file_operations *fops; +#else + struct file_operations *fops; +#endif void (*release)(struct video_device *vfd); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -- cgit v1.2.3 From 9fea63f4c39cf81e86921ea4a0c440029f6d49b9 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 4 Apr 2006 00:56:30 -0400 Subject: Fix spelling From: Trent Piepho It's "Terrestrial" Signed-off-by: Trent Piepho --- linux/drivers/media/dvb/frontends/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 37d5e0af1..6d90ff3f7 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -157,7 +157,7 @@ config DVB_STV0297 help A DVB-C tuner module. Say Y when you want to support this frontend. -comment "ATSC (North American/Korean Terresterial DTV) frontends" +comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" depends on DVB_CORE config DVB_NXT200X -- cgit v1.2.3 From 5bf059bca09b4e3a492a700b31cab1577c77d2ce Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 4 Apr 2006 13:30:29 +0100 Subject: Avoid unnecessary firmware re-loads in or51132 frontend From: Trent Piepho As QAM_64, QAM_256, and QAM_AUTO all use the same firmware, switching between these modulations doesn't require a firmware re-load. This also fixes a mishandled error condition, in which the firmware file is loaded into the kernel, the clock mode is changed, but then the firmware upload to the device fails. The modulation change is aborted, but the clock mode would still be changed. Signed-off-by: Trent Piepho Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/frontends/or51132.c | 81 +++++++++++++++++------------ 1 file changed, 49 insertions(+), 32 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c index a2a19aeb3..56d1109b9 100644 --- a/linux/drivers/media/dvb/frontends/or51132.c +++ b/linux/drivers/media/dvb/frontends/or51132.c @@ -310,6 +310,25 @@ static int or51132_setmode(struct dvb_frontend* fe) return 0; } +/* Some modulations use the same firmware. This classifies modulations + by the firmware they use. */ +#define MOD_FWCLASS_UNKNOWN 0 +#define MOD_FWCLASS_VSB 1 +#define MOD_FWCLASS_QAM 2 +static int modulation_fw_class(fe_modulation_t modulation) +{ + switch(modulation) { + case VSB_8: + return MOD_FWCLASS_VSB; + case QAM_AUTO: + case QAM_64: + case QAM_256: + return MOD_FWCLASS_QAM; + default: + return MOD_FWCLASS_UNKNOWN; + } +} + static int or51132_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) { @@ -317,45 +336,40 @@ static int or51132_set_parameters(struct dvb_frontend* fe, u8 buf[4]; struct or51132_state* state = fe->demodulator_priv; const struct firmware *fw; - - /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { - case VSB_8: + const char *fwname; + int clock_mode; + + /* Upload new firmware only if we need a different one */ + if (modulation_fw_class(state->current_modulation) != + modulation_fw_class(param->u.vsb.modulation)) { + switch(modulation_fw_class(param->u.vsb.modulation)) { + case MOD_FWCLASS_VSB: dprintk("set_parameters VSB MODE\n"); - printk("or51132: Waiting for firmware upload(%s)...\n", - OR51132_VSB_FIRMWARE); - ret = request_firmware(&fw, OR51132_VSB_FIRMWARE, - &state->i2c->dev); - if (ret){ - printk(KERN_WARNING "or51132: No firmware up" - "loaded(timeout or file not found?)\n"); - return ret; - } + fwname = OR51132_VSB_FIRMWARE; + /* Set non-punctured clock for VSB */ - state->config->set_ts_params(fe, 0); + clock_mode = 0; break; - case QAM_AUTO: - case QAM_64: - case QAM_256: + case MOD_FWCLASS_QAM: dprintk("set_parameters QAM MODE\n"); - printk("or51132: Waiting for firmware upload(%s)...\n", - OR51132_QAM_FIRMWARE); - ret = request_firmware(&fw, OR51132_QAM_FIRMWARE, - &state->i2c->dev); - if (ret){ - printk(KERN_WARNING "or51132: No firmware up" - "loaded(timeout or file not found?)\n"); - return ret; - } + fwname = OR51132_QAM_FIRMWARE; + /* Set punctured clock for QAM */ - state->config->set_ts_params(fe, 1); + clock_mode = 1; break; default: - printk("or51132:Modulation type(%d) UNSUPPORTED\n", + printk("or51132: Modulation type(%d) UNSUPPORTED\n", param->u.vsb.modulation); return -1; - }; + } + printk("or51132: Waiting for firmware upload(%s)...\n", + fwname); + ret = request_firmware(&fw, fwname, &state->i2c->dev); + if (ret) { + printk(KERN_WARNING "or51132: No firmware up" + "loaded(timeout or file not found?)\n"); + return ret; + } ret = or51132_load_firmware(fe, fw); release_firmware(fw); if (ret) { @@ -364,7 +378,10 @@ static int or51132_set_parameters(struct dvb_frontend* fe, return ret; } printk("or51132: Firmware upload complete.\n"); - + state->config->set_ts_params(fe, clock_mode); + } + /* Change only if we are actually changing the modulation */ + if (state->current_modulation != param->u.vsb.modulation) { state->current_modulation = param->u.vsb.modulation; or51132_setmode(fe); } @@ -373,7 +390,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe, param->frequency, 0); dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); - if (i2c_writebytes(state, state->config->pll_address ,buf, 4)) + if (i2c_writebytes(state, state->config->pll_address, buf, 4)) printk(KERN_WARNING "or51132: set_parameters error " "writing to tuner\n"); -- cgit v1.2.3 From d8eae1def78bd2a6dfa017145311a249c7aa3bc6 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 4 Apr 2006 13:30:33 +0100 Subject: Remove a wee bit of cruft From: Trent Piepho A few lines that do nothing in the or51132 frontend, removed. Signed-off-by: Trent Piepho Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/frontends/or51132.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c index 56d1109b9..619856b07 100644 --- a/linux/drivers/media/dvb/frontends/or51132.c +++ b/linux/drivers/media/dvb/frontends/or51132.c @@ -240,7 +240,7 @@ static int or51132_sleep(struct dvb_frontend* fe) static int or51132_setmode(struct dvb_frontend* fe) { struct or51132_state* state = fe->demodulator_priv; - unsigned char cmd_buf[4]; + unsigned char cmd_buf[3]; dprintk("setmode %d\n",(int)state->current_modulation); /* set operation mode in Receiver 1 register; */ @@ -260,7 +260,6 @@ static int or51132_setmode(struct dvb_frontend* fe) default: printk("setmode:Modulation set to unsupported value\n"); }; - cmd_buf[3] = 0x00; if (i2c_writebytes(state,state->config->demod_address, cmd_buf,3)) { printk(KERN_WARNING "or51132: set_mode error 1\n"); @@ -298,7 +297,6 @@ static int or51132_setmode(struct dvb_frontend* fe) default: printk("setmode: Modulation set to unsupported value\n"); }; - cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if (i2c_writebytes(state,state->config->demod_address, cmd_buf,3)) { -- cgit v1.2.3 From 90f7453adee2bcad39c6630b760358eb799f238d Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Tue, 4 Apr 2006 13:41:47 +0100 Subject: Fix mutex in dvb_register_device to work. From: Andrew de Quincey This mutex is meant to stop two devices getting the same ID. dvbdev_get_free_id() scans the list of already allocated devices to find a free id. Unfortunately, since the mutex is unlocked before the card is added to the above list, it is still possible for two of them to get the same id. Solution: move the mutex after the list_add. Its debatable whether this mutex lock is actually needed, but I'm unwilling to just remove it in case something does depend on it. Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/dvb-core/dvbdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 9b824c31b..041ed7fd1 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -230,8 +230,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENOMEM; } - mutex_unlock(&dvbdev_register_lock); - memcpy(dvbdev, template, sizeof(struct dvb_device)); dvbdev->type = type; dvbdev->id = id; @@ -242,6 +240,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, list_add_tail (&dvbdev->list_head, &adap->device_list); + mutex_unlock(&dvbdev_register_lock); + devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), S_IFCHR | S_IRUSR | S_IWUSR, "dvb/adapter%d/%s%d", adap->num, dnames[type], id); -- cgit v1.2.3 From 6d5c9c64cf281711f099edb4b42cae8c9db6b7d9 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 5 Apr 2006 18:09:45 +0100 Subject: Fix TT budget-ci 1.1 CI slots From: Andrew de Quincey It turns out the firmware on the TT budget-ci 1.1 slots doesn't generate interrupts. This patch adds support for this using polling mode on these slots. Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 105 ++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 20 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 5f91036f5..e64a609cf 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -71,6 +71,7 @@ struct budget_ci { struct tasklet_struct msp430_irq_tasklet; struct tasklet_struct ciintf_irq_tasklet; int slot_status; + int ci_irq; struct dvb_ca_en50221 ca; char ir_dev_name[50]; u8 tuner_pll_address; /* used for philips_tdm1316l configs */ @@ -276,8 +277,10 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) if (slot != 0) return -EINVAL; - // trigger on RISING edge during reset so we know when READY is re-asserted - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); + if (budget_ci->ci_irq) { + // trigger on RISING edge during reset so we know when READY is re-asserted + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); + } budget_ci->slot_status = SLOTSTATUS_RESET; ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); msleep(1); @@ -370,11 +373,50 @@ static void ciintf_interrupt(unsigned long data) } } +static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) +{ + struct budget_ci *budget_ci = (struct budget_ci *) ca->data; + unsigned int flags; + + // ensure we don't get spurious IRQs during initialisation + if (!budget_ci->budget.ci_present) + return -EINVAL; + + // read the CAM status + flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); + if (flags & CICONTROL_CAMDETECT) { + // mark it as present if it wasn't before + if (budget_ci->slot_status & SLOTSTATUS_NONE) { + budget_ci->slot_status = SLOTSTATUS_PRESENT; + } + + // during a RESET, we check if we can read from IO memory to see when CAM is ready + if (budget_ci->slot_status & SLOTSTATUS_RESET) { + if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) { + budget_ci->slot_status = SLOTSTATUS_READY; + } + } + } else { + budget_ci->slot_status = SLOTSTATUS_NONE; + } + + if (budget_ci->slot_status != SLOTSTATUS_NONE) { + if (budget_ci->slot_status & SLOTSTATUS_READY) { + return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; + } + return DVB_CA_EN50221_POLL_CAM_PRESENT; + } + + return 0; +} + static int ciintf_init(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; int flags; int result; + int ci_version; + int ca_flags; memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221)); @@ -382,16 +424,29 @@ static int ciintf_init(struct budget_ci *budget_ci) saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800); // test if it is there - if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) { + ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0); + if ((ci_version & 0xa0) != 0xa0) { result = -ENODEV; goto error; } + // determine whether a CAM is present or not flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); budget_ci->slot_status = SLOTSTATUS_NONE; if (flags & CICONTROL_CAMDETECT) budget_ci->slot_status = SLOTSTATUS_PRESENT; + // version 0xa2 of the CI firmware doesn't generate interrupts + if (ci_version == 0xa2) { + ca_flags = 0; + budget_ci->ci_irq = 0; + } else { + ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | + DVB_CA_EN50221_FLAG_IRQ_FR | + DVB_CA_EN50221_FLAG_IRQ_DA; + budget_ci->ci_irq = 1; + } + // register CI interface budget_ci->ca.owner = THIS_MODULE; budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem; @@ -401,23 +456,27 @@ static int ciintf_init(struct budget_ci *budget_ci) budget_ci->ca.slot_reset = ciintf_slot_reset; budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; + budget_ci->ca.poll_slot_status = ciintf_poll_slot_status; budget_ci->ca.data = budget_ci; if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, &budget_ci->ca, - DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | - DVB_CA_EN50221_FLAG_IRQ_FR | - DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) { + ca_flags, 1)) != 0) { printk("budget_ci: CI interface detected, but initialisation failed.\n"); goto error; } + // Setup CI slot IRQ - tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - } else { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); + if (budget_ci->ci_irq) { + tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); + if (budget_ci->slot_status != SLOTSTATUS_NONE) { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); + } else { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); + } + saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); } - saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); + + // enable interface ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET, 1, 0); @@ -426,10 +485,12 @@ static int ciintf_init(struct budget_ci *budget_ci) budget_ci->budget.ci_present = 1; // forge a fake CI IRQ so the CAM state is setup correctly - flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; - if (budget_ci->slot_status != SLOTSTATUS_NONE) - flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); + if (budget_ci->ci_irq) { + flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; + if (budget_ci->slot_status != SLOTSTATUS_NONE) + flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; + dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); + } return 0; @@ -443,9 +504,13 @@ static void ciintf_deinit(struct budget_ci *budget_ci) struct saa7146_dev *saa = budget_ci->budget.dev; // disable CI interrupts - saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03); - saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ciintf_irq_tasklet); + if (budget_ci->ci_irq) { + saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03); + saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); + tasklet_kill(&budget_ci->ciintf_irq_tasklet); + } + + // reset interface ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); msleep(1); ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, @@ -473,7 +538,7 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) if (*isr & MASK_10) ttpci_budget_irq10_handler(dev, isr); - if ((*isr & MASK_03) && (budget_ci->budget.ci_present)) + if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) tasklet_schedule(&budget_ci->ciintf_irq_tasklet); } -- cgit v1.2.3 From 7c0ef076eb4257ba9803b2312a5e734101900d4b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 5 Apr 2006 16:36:51 -0300 Subject: Remove DMX_GET_EVENT and associated data structures From: Andreas Oberritter The ioctl DMX_GET_EVENT has never been implemented. I guess no software is using it because of its lack of implementation. Future software won't use it, too, because this API doesn't make much sense the way it is: Frontend events have their own different API. Scrambling events can't be generated in a useful way by the hardware I know of. Signed-off-by: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dmxdev.c | 3 --- linux/include/linux/dvb/dmx.h | 26 -------------------------- 2 files changed, 29 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index 04578df3f..988499dfd 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -872,9 +872,6 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&dmxdevfilter->mutex); break; - case DMX_GET_EVENT: - break; - case DMX_GET_PES_PIDS: if (!dmxdev->demux->get_pes_pids) { ret = -EINVAL; diff --git a/linux/include/linux/dvb/dmx.h b/linux/include/linux/dvb/dmx.h index 2787b8a22..c6a2353c4 100644 --- a/linux/include/linux/dvb/dmx.h +++ b/linux/include/linux/dvb/dmx.h @@ -88,20 +88,6 @@ typedef enum #define DMX_PES_PCR DMX_PES_PCR0 -typedef enum -{ - DMX_SCRAMBLING_EV, - DMX_FRONTEND_EV -} dmx_event_t; - - -typedef enum -{ - DMX_SCRAMBLING_OFF, - DMX_SCRAMBLING_ON -} dmx_scrambling_status_t; - - typedef struct dmx_filter { __u8 filter[DMX_FILTER_SIZE]; @@ -132,17 +118,6 @@ struct dmx_pes_filter_params __u32 flags; }; - -struct dmx_event -{ - dmx_event_t event; - time_t timeStamp; - union - { - dmx_scrambling_status_t scrambling; - } u; -}; - typedef struct dmx_caps { __u32 caps; int num_decoders; @@ -171,7 +146,6 @@ struct dmx_stc { #define DMX_SET_FILTER _IOW('o', 43, struct dmx_sct_filter_params) #define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params) #define DMX_SET_BUFFER_SIZE _IO('o', 45) -#define DMX_GET_EVENT _IOR('o', 46, struct dmx_event) #define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5]) #define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t) #define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t) -- cgit v1.2.3