aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2009-03-06 23:57:25 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:38 -0400
commit27764726a8fa72a7e8a7cdccbe9e4425747a96fa (patch)
tree86415f280dd8423781d17ce723e245cfaa2b60fb
parent5e430ca5d25e99f99c055bc43f8f140722a643b8 (diff)
V4L/DVB (11194): pvrusb2: Implement mechanism to force a full sub-device update
When a pvrusb2 driver instance first initializes, we need to be sure to send out a complete state update for everything to all attached modules. The old i2c layer did this by keeping a separate mask of "stale" bits for each attached module - and setting that mask to all stale when that module attaches. But the new sub-device adaptation I've implemented here no longer has per-module stale bits. So instead there's now a global "force dirty" bit that is set upon instance initialization, before the sub-devices are attached. After the first update, this bit is cleared, allowing for normal update-on-dirty behavior. In this manner, we ensure that all sub-devices have been properly synchronized at initialization. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c21
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c2
6 files changed, 17 insertions, 13 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 52966414327..aca6b1d1561 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -184,7 +184,7 @@ int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
184 184
185void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) 185void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
186{ 186{
187 if (hdw->input_dirty) { 187 if (hdw->input_dirty || hdw->force_dirty) {
188 struct v4l2_routing route; 188 struct v4l2_routing route;
189 const struct routing_scheme *sp; 189 const struct routing_scheme *sp;
190 unsigned int sid = hdw->hdw_desc->signal_routing_scheme; 190 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 725f391cda5..5adbf00323e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -325,7 +325,7 @@ int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
325void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) 325void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
326{ 326{
327 pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update..."); 327 pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
328 if (hdw->input_dirty) { 328 if (hdw->input_dirty || hdw->force_dirty) {
329 struct v4l2_routing route; 329 struct v4l2_routing route;
330 enum cx25840_video_input vid_input; 330 enum cx25840_video_input vid_input;
331 enum cx25840_audio_input aud_input; 331 enum cx25840_audio_input aud_input;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 299bf58ad77..2afbd9bcedd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -288,6 +288,7 @@ struct pvr2_hdw {
288 wait_queue_head_t state_wait_data; 288 wait_queue_head_t state_wait_data;
289 289
290 290
291 int force_dirty; /* consider all controls dirty if true */
291 int flag_ok; /* device in known good state */ 292 int flag_ok; /* device in known good state */
292 int flag_disconnected; /* flag_ok == 0 due to disconnect */ 293 int flag_disconnected; /* flag_ok == 0 due to disconnect */
293 int flag_init_ok; /* true if structure is fully initialized */ 294 int flag_init_ok; /* true if structure is fully initialized */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 89d5bb4f88b..1fb9ca560ac 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2185,6 +2185,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
2185 2185
2186 if (!pvr2_hdw_dev_ok(hdw)) return; 2186 if (!pvr2_hdw_dev_ok(hdw)) return;
2187 2187
2188 hdw->force_dirty = !0;
2189
2188 if (!hdw->hdw_desc->flag_no_powerup) { 2190 if (!hdw->hdw_desc->flag_no_powerup) {
2189 pvr2_hdw_cmd_powerup(hdw); 2191 pvr2_hdw_cmd_powerup(hdw);
2190 if (!pvr2_hdw_dev_ok(hdw)) return; 2192 if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -2935,7 +2937,7 @@ static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
2935} 2937}
2936 2938
2937#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \ 2939#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \
2938 if ((hdw)->lab##_dirty) { \ 2940 if ((hdw)->lab##_dirty || (hdw)->force_dirty) { \
2939 pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \ 2941 pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \
2940 } 2942 }
2941 2943
@@ -2949,7 +2951,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
2949 2951
2950 pvr2_trace(PVR2_TRACE_CHIPS, "subdev update..."); 2952 pvr2_trace(PVR2_TRACE_CHIPS, "subdev update...");
2951 2953
2952 if (hdw->tuner_updated) { 2954 if (hdw->tuner_updated || hdw->force_dirty) {
2953 struct tuner_setup setup; 2955 struct tuner_setup setup;
2954 pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)", 2956 pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
2955 hdw->tuner_type); 2957 hdw->tuner_type);
@@ -2962,7 +2964,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
2962 } 2964 }
2963 } 2965 }
2964 2966
2965 if (hdw->input_dirty || hdw->std_dirty) { 2967 if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) {
2966 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard"); 2968 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard");
2967 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { 2969 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
2968 v4l2_device_call_all(&hdw->v4l2_dev, 0, 2970 v4l2_device_call_all(&hdw->v4l2_dev, 0,
@@ -2987,14 +2989,14 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
2987 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass); 2989 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass);
2988 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble); 2990 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble);
2989 2991
2990 if (hdw->input_dirty || hdw->audiomode_dirty) { 2992 if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
2991 struct v4l2_tuner vt; 2993 struct v4l2_tuner vt;
2992 memset(&vt, 0, sizeof(vt)); 2994 memset(&vt, 0, sizeof(vt));
2993 vt.audmode = hdw->audiomode_val; 2995 vt.audmode = hdw->audiomode_val;
2994 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); 2996 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
2995 } 2997 }
2996 2998
2997 if (hdw->freqDirty) { 2999 if (hdw->freqDirty || hdw->force_dirty) {
2998 unsigned long fv; 3000 unsigned long fv;
2999 struct v4l2_frequency freq; 3001 struct v4l2_frequency freq;
3000 fv = pvr2_hdw_get_cur_freq(hdw); 3002 fv = pvr2_hdw_get_cur_freq(hdw);
@@ -3019,7 +3021,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
3019 s_frequency, &freq); 3021 s_frequency, &freq);
3020 } 3022 }
3021 3023
3022 if (hdw->res_hor_dirty || hdw->res_ver_dirty) { 3024 if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) {
3023 struct v4l2_format fmt; 3025 struct v4l2_format fmt;
3024 memset(&fmt, 0, sizeof(fmt)); 3026 memset(&fmt, 0, sizeof(fmt));
3025 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 3027 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -3030,7 +3032,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
3030 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt); 3032 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt);
3031 } 3033 }
3032 3034
3033 if (hdw->srate_dirty) { 3035 if (hdw->srate_dirty || hdw->force_dirty) {
3034 u32 val; 3036 u32 val;
3035 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d", 3037 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d",
3036 hdw->srate_val); 3038 hdw->srate_val);
@@ -3061,7 +3063,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
3061 (*fp)(hdw, sd); 3063 (*fp)(hdw, sd);
3062 } 3064 }
3063 3065
3064 if (hdw->tuner_signal_stale && hdw->cropcap_stale) { 3066 if (hdw->tuner_signal_stale || hdw->cropcap_stale) {
3065 pvr2_hdw_status_poll(hdw); 3067 pvr2_hdw_status_poll(hdw);
3066 } 3068 }
3067} 3069}
@@ -3075,7 +3077,7 @@ static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
3075 unsigned int idx; 3077 unsigned int idx;
3076 struct pvr2_ctrl *cptr; 3078 struct pvr2_ctrl *cptr;
3077 int value; 3079 int value;
3078 int commit_flag = 0; 3080 int commit_flag = hdw->force_dirty;
3079 char buf[100]; 3081 char buf[100];
3080 unsigned int bcnt,ccnt; 3082 unsigned int bcnt,ccnt;
3081 3083
@@ -3260,6 +3262,7 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
3260 pvr2_subdev_update(hdw); 3262 pvr2_subdev_update(hdw);
3261 3263
3262 hdw->tuner_updated = 0; 3264 hdw->tuner_updated = 0;
3265 hdw->force_dirty = 0;
3263 for (idx = 0; idx < hdw->control_cnt; idx++) { 3266 for (idx = 0; idx < hdw->control_cnt; idx++) {
3264 cptr = hdw->controls + idx; 3267 cptr = hdw->controls + idx;
3265 if (!cptr->info->clear_dirty) continue; 3268 if (!cptr->info->clear_dirty) continue;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index c7a1621cf14..4e0c0881b7b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -249,7 +249,7 @@ int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
249 249
250void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) 250void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
251{ 251{
252 if (hdw->input_dirty) { 252 if (hdw->input_dirty || hdw->force_dirty) {
253 struct v4l2_routing route; 253 struct v4l2_routing route;
254 const struct routing_scheme *sp; 254 const struct routing_scheme *sp;
255 unsigned int sid = hdw->hdw_desc->signal_routing_scheme; 255 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index a099bf1641e..0068566876e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -162,7 +162,7 @@ int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
162 162
163void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) 163void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
164{ 164{
165 if (hdw->input_dirty) { 165 if (hdw->input_dirty || hdw->force_dirty) {
166 struct v4l2_routing route; 166 struct v4l2_routing route;
167 167
168 memset(&route, 0, sizeof(route)); 168 memset(&route, 0, sizeof(route));