aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c24
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h16
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c99
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c19
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c22
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.h3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c85
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c13
12 files changed, 144 insertions, 165 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 122496f36845..5d30c9366144 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -31,7 +31,6 @@ struct pvr2_msp3400_handler {
31 struct pvr2_hdw *hdw; 31 struct pvr2_hdw *hdw;
32 struct pvr2_i2c_client *client; 32 struct pvr2_i2c_client *client;
33 struct pvr2_i2c_handler i2c_handler; 33 struct pvr2_i2c_handler i2c_handler;
34 struct pvr2_audio_stat astat;
35 unsigned long stale_mask; 34 unsigned long stale_mask;
36}; 35};
37 36
@@ -126,27 +125,9 @@ static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
126} 125}
127 126
128 127
129/* This reads back the current signal type */
130static int get_audio_status(struct pvr2_msp3400_handler *ctxt)
131{
132 struct v4l2_tuner vt;
133 int stat;
134
135 memset(&vt,0,sizeof(vt));
136 stat = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
137 if (stat < 0) return stat;
138
139 ctxt->hdw->flag_stereo = (vt.audmode & V4L2_TUNER_MODE_STEREO) != 0;
140 ctxt->hdw->flag_bilingual =
141 (vt.audmode & V4L2_TUNER_MODE_LANG2) != 0;
142 return 0;
143}
144
145
146static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt) 128static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
147{ 129{
148 ctxt->client->handler = NULL; 130 ctxt->client->handler = NULL;
149 ctxt->hdw->audio_stat = NULL;
150 kfree(ctxt); 131 kfree(ctxt);
151} 132}
152 133
@@ -169,7 +150,6 @@ static const struct pvr2_i2c_handler_functions msp3400_funcs = {
169int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) 150int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
170{ 151{
171 struct pvr2_msp3400_handler *ctxt; 152 struct pvr2_msp3400_handler *ctxt;
172 if (hdw->audio_stat) return 0;
173 if (cp->handler) return 0; 153 if (cp->handler) return 0;
174 154
175 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); 155 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
@@ -180,13 +160,9 @@ int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
180 ctxt->i2c_handler.func_table = &msp3400_funcs; 160 ctxt->i2c_handler.func_table = &msp3400_funcs;
181 ctxt->client = cp; 161 ctxt->client = cp;
182 ctxt->hdw = hdw; 162 ctxt->hdw = hdw;
183 ctxt->astat.ctxt = ctxt;
184 ctxt->astat.status = (int (*)(void *))get_audio_status;
185 ctxt->astat.detach = (void (*)(void *))pvr2_msp3400_detach;
186 ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/ 163 ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/
187 sizeof(msp3400_ops[0]))) - 1; 164 sizeof(msp3400_ops[0]))) - 1;
188 cp->handler = &ctxt->i2c_handler; 165 cp->handler = &ctxt->i2c_handler;
189 hdw->audio_stat = &ctxt->astat;
190 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up", 166 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
191 cp->client->addr); 167 cp->client->addr);
192 return !0; 168 return !0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index c2a154e4ec59..a3357bf2a1af 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -199,18 +199,6 @@ static int decoder_detect(struct pvr2_i2c_client *cp)
199} 199}
200 200
201 201
202static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt)
203{
204 struct v4l2_tuner vt;
205 int ret;
206
207 memset(&vt,0,sizeof(vt));
208 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
209 if (ret < 0) return -EINVAL;
210 return vt.signal ? 1 : 0;
211}
212
213
214static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, 202static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
215 char *buf,unsigned int cnt) 203 char *buf,unsigned int cnt)
216{ 204{
@@ -252,7 +240,6 @@ int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
252 ctxt->ctrl.ctxt = ctxt; 240 ctxt->ctrl.ctxt = ctxt;
253 ctxt->ctrl.detach = (void (*)(void *))decoder_detach; 241 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
254 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; 242 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
255 ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
256 ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset; 243 ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
257 ctxt->client = cp; 244 ctxt->client = cp;
258 ctxt->hdw = hdw; 245 ctxt->hdw = hdw;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index b9df52c882a8..bc911ff75306 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -137,17 +137,10 @@ struct pvr2_ctrl {
137}; 137};
138 138
139 139
140struct pvr2_audio_stat {
141 void *ctxt;
142 void (*detach)(void *);
143 int (*status)(void *);
144};
145
146struct pvr2_decoder_ctrl { 140struct pvr2_decoder_ctrl {
147 void *ctxt; 141 void *ctxt;
148 void (*detach)(void *); 142 void (*detach)(void *);
149 void (*enable)(void *,int); 143 void (*enable)(void *,int);
150 int (*tuned)(void *);
151 void (*force_reset)(void *); 144 void (*force_reset)(void *);
152}; 145};
153 146
@@ -266,6 +259,10 @@ struct pvr2_hdw {
266 unsigned int freqSelector; /* 0=radio 1=television */ 259 unsigned int freqSelector; /* 0=radio 1=television */
267 int freqDirty; 260 int freqDirty;
268 261
262 /* Current tuner info - this information is polled from the I2C bus */
263 struct v4l2_tuner tuner_signal_info;
264 int tuner_signal_stale;
265
269 /* Video standard handling */ 266 /* Video standard handling */
270 v4l2_std_id std_mask_eeprom; // Hardware supported selections 267 v4l2_std_id std_mask_eeprom; // Hardware supported selections
271 v4l2_std_id std_mask_avail; // Which standards we may select from 268 v4l2_std_id std_mask_avail; // Which standards we may select from
@@ -297,11 +294,6 @@ struct pvr2_hdw {
297 294
298 enum pvr2_config config; 295 enum pvr2_config config;
299 296
300 /* Information about what audio signal we're hearing */
301 int flag_stereo;
302 int flag_bilingual;
303 struct pvr2_audio_stat *audio_stat;
304
305 /* Control state needed for cx2341x module */ 297 /* Control state needed for cx2341x module */
306 struct cx2341x_mpeg_params enc_cur_state; 298 struct cx2341x_mpeg_params enc_cur_state;
307 struct cx2341x_mpeg_params enc_ctl_state; 299 struct cx2341x_mpeg_params enc_ctl_state;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 2de595112224..4672199ae92d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -264,7 +264,6 @@ static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
264static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); 264static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
265static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); 265static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
266static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw); 266static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
267static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw);
268static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); 267static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
269static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); 268static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
270static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw); 269static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw);
@@ -623,8 +622,34 @@ static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
623 622
624static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) 623static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
625{ 624{
626 *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) & 625 struct pvr2_hdw *hdw = cptr->hdw;
627 PVR2_SIGNAL_OK) ? 1 : 0); 626 pvr2_i2c_core_status_poll(hdw);
627 *vp = hdw->tuner_signal_info.signal;
628 return 0;
629}
630
631static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
632{
633 int val = 0;
634 unsigned int subchan;
635 struct pvr2_hdw *hdw = cptr->hdw;
636 if (hdw->tuner_signal_stale) {
637 pvr2_i2c_core_status_poll(hdw);
638 }
639 subchan = hdw->tuner_signal_info.rxsubchans;
640 if (subchan & V4L2_TUNER_SUB_MONO) {
641 val |= (1 << V4L2_TUNER_MODE_MONO);
642 }
643 if (subchan & V4L2_TUNER_SUB_STEREO) {
644 val |= (1 << V4L2_TUNER_MODE_STEREO);
645 }
646 if (subchan & V4L2_TUNER_SUB_LANG1) {
647 val |= (1 << V4L2_TUNER_MODE_LANG1);
648 }
649 if (subchan & V4L2_TUNER_SUB_LANG2) {
650 val |= (1 << V4L2_TUNER_MODE_LANG2);
651 }
652 *vp = val;
628 return 0; 653 return 0;
629} 654}
630 655
@@ -898,7 +923,20 @@ static const struct pvr2_ctl_info control_defs[] = {
898 .desc = "Signal Present", 923 .desc = "Signal Present",
899 .name = "signal_present", 924 .name = "signal_present",
900 .get_value = ctrl_signal_get, 925 .get_value = ctrl_signal_get,
901 DEFBOOL, 926 DEFINT(0,65535),
927 },{
928 .desc = "Audio Modes Present",
929 .name = "audio_modes_present",
930 .get_value = ctrl_audio_modes_present_get,
931 /* For this type we "borrow" the V4L2_TUNER_MODE enum from
932 v4l. Nothing outside of this module cares about this,
933 but I reuse it in order to also reuse the
934 control_values_audiomode string table. */
935 DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
936 (1 << V4L2_TUNER_MODE_STEREO)|
937 (1 << V4L2_TUNER_MODE_LANG1)|
938 (1 << V4L2_TUNER_MODE_LANG2)),
939 control_values_audiomode),
902 },{ 940 },{
903 .desc = "Video Standards Available Mask", 941 .desc = "Video Standards Available Mask",
904 .name = "video_standard_mask_available", 942 .name = "video_standard_mask_available",
@@ -1957,6 +1995,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1957 hdw,pvr2_device_names[hdw_type]); 1995 hdw,pvr2_device_names[hdw_type]);
1958 if (!hdw) goto fail; 1996 if (!hdw) goto fail;
1959 memset(hdw,0,sizeof(*hdw)); 1997 memset(hdw,0,sizeof(*hdw));
1998 hdw->tuner_signal_stale = !0;
1960 cx2341x_fill_defaults(&hdw->enc_ctl_state); 1999 cx2341x_fill_defaults(&hdw->enc_ctl_state);
1961 2000
1962 hdw->control_cnt = CTRLDEF_COUNT; 2001 hdw->control_cnt = CTRLDEF_COUNT;
@@ -2179,9 +2218,6 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2179 pvr2_stream_destroy(hdw->vid_stream); 2218 pvr2_stream_destroy(hdw->vid_stream);
2180 hdw->vid_stream = NULL; 2219 hdw->vid_stream = NULL;
2181 } 2220 }
2182 if (hdw->audio_stat) {
2183 hdw->audio_stat->detach(hdw->audio_stat->ctxt);
2184 }
2185 if (hdw->decoder_ctrl) { 2221 if (hdw->decoder_ctrl) {
2186 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt); 2222 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2187 } 2223 }
@@ -2547,34 +2583,6 @@ const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2547} 2583}
2548 2584
2549 2585
2550/* Return bit mask indicating signal status */
2551static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
2552{
2553 unsigned int msk = 0;
2554 switch (hdw->input_val) {
2555 case PVR2_CVAL_INPUT_TV:
2556 case PVR2_CVAL_INPUT_RADIO:
2557 if (hdw->decoder_ctrl &&
2558 hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {
2559 msk |= PVR2_SIGNAL_OK;
2560 if (hdw->audio_stat &&
2561 hdw->audio_stat->status(hdw->audio_stat->ctxt)) {
2562 if (hdw->flag_stereo) {
2563 msk |= PVR2_SIGNAL_STEREO;
2564 }
2565 if (hdw->flag_bilingual) {
2566 msk |= PVR2_SIGNAL_SAP;
2567 }
2568 }
2569 }
2570 break;
2571 default:
2572 msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;
2573 }
2574 return msk;
2575}
2576
2577
2578int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) 2586int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2579{ 2587{
2580 int result; 2588 int result;
@@ -2590,14 +2598,25 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2590} 2598}
2591 2599
2592 2600
2593/* Return bit mask indicating signal status */ 2601/* Execute poll of tuner status */
2594unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw) 2602void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
2595{ 2603{
2596 unsigned int msk = 0;
2597 LOCK_TAKE(hdw->big_lock); do { 2604 LOCK_TAKE(hdw->big_lock); do {
2598 msk = pvr2_hdw_get_signal_status_internal(hdw); 2605 pvr2_i2c_core_status_poll(hdw);
2599 } while (0); LOCK_GIVE(hdw->big_lock); 2606 } while (0); LOCK_GIVE(hdw->big_lock);
2600 return msk; 2607}
2608
2609
2610/* Return information about the tuner */
2611int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2612{
2613 LOCK_TAKE(hdw->big_lock); do {
2614 if (hdw->tuner_signal_stale) {
2615 pvr2_i2c_core_status_poll(hdw);
2616 }
2617 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2618 } while (0); LOCK_GIVE(hdw->big_lock);
2619 return 0;
2601} 2620}
2602 2621
2603 2622
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index d803f24cc9e0..dc7a3ba8dd18 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -44,12 +44,6 @@
44#define PVR2_CVAL_INPUT_COMPOSITE 2 44#define PVR2_CVAL_INPUT_COMPOSITE 2
45#define PVR2_CVAL_INPUT_RADIO 3 45#define PVR2_CVAL_INPUT_RADIO 3
46 46
47/* Values that pvr2_hdw_get_signal_status() returns */
48#define PVR2_SIGNAL_OK 0x0001
49#define PVR2_SIGNAL_STEREO 0x0002
50#define PVR2_SIGNAL_SAP 0x0004
51
52
53/* Subsystem definitions - these are various pieces that can be 47/* Subsystem definitions - these are various pieces that can be
54 independently stopped / started. Usually you don't want to mess with 48 independently stopped / started. Usually you don't want to mess with
55 this directly (let the driver handle things itself), but it is useful 49 this directly (let the driver handle things itself), but it is useful
@@ -155,8 +149,11 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
155/* Return name for this driver instance */ 149/* Return name for this driver instance */
156const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *); 150const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);
157 151
158/* Return PVR2_SIGNAL_XXXX bit mask indicating signal status */ 152/* Mark tuner status stale so that it will be re-fetched */
159unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *); 153void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *);
154
155/* Return information about the tuner */
156int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *);
160 157
161/* Query device and see if it thinks it is on a high-speed USB link */ 158/* Query device and see if it thinks it is on a high-speed USB link */
162int pvr2_hdw_is_hsm(struct pvr2_hdw *); 159int pvr2_hdw_is_hsm(struct pvr2_hdw *);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index 05121666b9ba..16fa075a1eec 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -59,6 +59,7 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
59 (1 << OP_FREQ) | 59 (1 << OP_FREQ) |
60 (1 << OP_SIZE) | 60 (1 << OP_SIZE) |
61 (1 << OP_LOG)); 61 (1 << OP_LOG));
62 cp->status_poll = pvr2_v4l2_cmd_status_poll;
62 63
63 if (id == I2C_DRIVERID_MSP3400) { 64 if (id == I2C_DRIVERID_MSP3400) {
64 if (pvr2_i2c_msp3400_setup(hdw,cp)) { 65 if (pvr2_i2c_msp3400_setup(hdw,cp)) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
index 51da8945efe4..b1f6809625e8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -37,6 +37,7 @@ static void set_standard(struct pvr2_hdw *hdw)
37 vs = hdw->std_mask_cur; 37 vs = hdw->std_mask_cur;
38 pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); 38 pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
39 } 39 }
40 hdw->tuner_signal_stale = !0;
40} 41}
41 42
42 43
@@ -145,13 +146,21 @@ static void set_frequency(struct pvr2_hdw *hdw)
145 struct v4l2_frequency freq; 146 struct v4l2_frequency freq;
146 fv = pvr2_hdw_get_cur_freq(hdw); 147 fv = pvr2_hdw_get_cur_freq(hdw);
147 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv); 148 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv);
149 if (hdw->tuner_signal_stale) {
150 pvr2_i2c_core_status_poll(hdw);
151 }
148 memset(&freq,0,sizeof(freq)); 152 memset(&freq,0,sizeof(freq));
149 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { 153 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
150 // ((fv * 1000) / 62500) 154 // ((fv * 1000) / 62500)
151 freq.frequency = (fv * 2) / 125; 155 freq.frequency = (fv * 2) / 125;
152 freq.type = V4L2_TUNER_RADIO;
153 } else { 156 } else {
154 freq.frequency = fv / 62500; 157 freq.frequency = fv / 62500;
158 }
159 /* tuner-core currently doesn't seem to care about this, but
160 let's set it anyway for completeness. */
161 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
162 freq.type = V4L2_TUNER_RADIO;
163 } else {
155 freq.type = V4L2_TUNER_ANALOG_TV; 164 freq.type = V4L2_TUNER_ANALOG_TV;
156 } 165 }
157 freq.tuner = 0; 166 freq.tuner = 0;
@@ -230,6 +239,12 @@ void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
230} 239}
231 240
232 241
242void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp)
243{
244 pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&cp->hdw->tuner_signal_info);
245}
246
247
233/* 248/*
234 Stuff for Emacs to see, in order to encourage consistent editing style: 249 Stuff for Emacs to see, in order to encourage consistent editing style:
235 *** Local Variables: *** 250 *** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
index 894de610893b..6a9bb46d0654 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
@@ -34,6 +34,7 @@ extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
34extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; 34extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
35 35
36void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int); 36void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
37void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *);
37 38
38#endif /* __PVRUSB2_CMD_V4L2_H */ 39#endif /* __PVRUSB2_CMD_V4L2_H */
39 40
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 62a7cfca837d..35a06652a60c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -590,6 +590,27 @@ static int handler_check(struct pvr2_i2c_client *cp)
590 590
591#define BUFSIZE 500 591#define BUFSIZE 500
592 592
593
594void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw)
595{
596 struct list_head *item;
597 struct pvr2_i2c_client *cp;
598 mutex_lock(&hdw->i2c_list_lock); do {
599 struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
600 memset(vtp,0,sizeof(vtp));
601 list_for_each(item,&hdw->i2c_clients) {
602 cp = list_entry(item,struct pvr2_i2c_client,list);
603 if (!cp->detected_flag) continue;
604 if (!cp->status_poll) continue;
605 cp->status_poll(cp);
606 }
607 hdw->tuner_signal_stale = 0;
608 } while (0); mutex_unlock(&hdw->i2c_list_lock);
609}
610
611
612/* Issue various I2C operations to bring chip-level drivers into sync with
613 state stored in this driver. */
593void pvr2_i2c_core_sync(struct pvr2_hdw *hdw) 614void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
594{ 615{
595 unsigned long msk; 616 unsigned long msk;
@@ -876,6 +897,7 @@ static int pvr2_i2c_attach_inform(struct i2c_client *client)
876 client->addr,cp); 897 client->addr,cp);
877 if (!cp) return -ENOMEM; 898 if (!cp) return -ENOMEM;
878 memset(cp,0,sizeof(*cp)); 899 memset(cp,0,sizeof(*cp));
900 cp->hdw = hdw;
879 INIT_LIST_HEAD(&cp->list); 901 INIT_LIST_HEAD(&cp->list);
880 cp->client = client; 902 cp->client = client;
881 mutex_lock(&hdw->i2c_list_lock); do { 903 mutex_lock(&hdw->i2c_list_lock); do {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
index 6d7e25247576..bd0807b905bb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
@@ -35,10 +35,12 @@ struct pvr2_i2c_client {
35 struct i2c_client *client; 35 struct i2c_client *client;
36 struct pvr2_i2c_handler *handler; 36 struct pvr2_i2c_handler *handler;
37 struct list_head list; 37 struct list_head list;
38 struct pvr2_hdw *hdw;
38 int detected_flag; 39 int detected_flag;
39 int recv_enable; 40 int recv_enable;
40 unsigned long pend_mask; 41 unsigned long pend_mask;
41 unsigned long ctl_mask; 42 unsigned long ctl_mask;
43 void (*status_poll)(struct pvr2_i2c_client *);
42}; 44};
43 45
44struct pvr2_i2c_handler { 46struct pvr2_i2c_handler {
@@ -67,6 +69,7 @@ int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
67 69
68int pvr2_i2c_core_check_stale(struct pvr2_hdw *); 70int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
69void pvr2_i2c_core_sync(struct pvr2_hdw *); 71void pvr2_i2c_core_sync(struct pvr2_hdw *);
72void pvr2_i2c_core_status_poll(struct pvr2_hdw *);
70unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen); 73unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
71#define PVR2_I2C_DETAIL_DEBUG 0x0001 74#define PVR2_I2C_DETAIL_DEBUG 0x0001
72#define PVR2_I2C_DETAIL_HANDLER 0x0002 75#define PVR2_I2C_DETAIL_HANDLER 0x0002
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 655a722289ed..2a6763865266 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -95,25 +95,6 @@ static struct v4l2_capability pvr_capability ={
95 .reserved = {0,0,0,0} 95 .reserved = {0,0,0,0}
96}; 96};
97 97
98static struct v4l2_tuner pvr_v4l2_tuners[]= {
99 {
100 .index = 0,
101 .name = "TV Tuner",
102 .type = V4L2_TUNER_ANALOG_TV,
103 .capability = (V4L2_TUNER_CAP_NORM |
104 V4L2_TUNER_CAP_STEREO |
105 V4L2_TUNER_CAP_LANG1 |
106 V4L2_TUNER_CAP_LANG2),
107 .rangelow = 0,
108 .rangehigh = 0,
109 .rxsubchans = V4L2_TUNER_SUB_STEREO,
110 .audmode = V4L2_TUNER_MODE_STEREO,
111 .signal = 0,
112 .afc = 0,
113 .reserved = {0,0,0,0}
114 }
115};
116
117static struct v4l2_fmtdesc pvr_fmtdesc [] = { 98static struct v4l2_fmtdesc pvr_fmtdesc [] = {
118 { 99 {
119 .index = 0, 100 .index = 0,
@@ -358,34 +339,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
358 case VIDIOC_G_TUNER: 339 case VIDIOC_G_TUNER:
359 { 340 {
360 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 341 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
361 unsigned int status_mask; 342 pvr2_hdw_execute_tuner_poll(hdw);
362 int val; 343 ret = pvr2_hdw_get_tuner_status(hdw,vt);
363 if (vt->index !=0) break;
364
365 status_mask = pvr2_hdw_get_signal_status(hdw);
366
367 memcpy(vt, &pvr_v4l2_tuners[vt->index],
368 sizeof(struct v4l2_tuner));
369
370 vt->signal = 0;
371 if (status_mask & PVR2_SIGNAL_OK) {
372 if (status_mask & PVR2_SIGNAL_STEREO) {
373 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
374 } else {
375 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
376 }
377 if (status_mask & PVR2_SIGNAL_SAP) {
378 vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 |
379 V4L2_TUNER_SUB_LANG2);
380 }
381 vt->signal = 65535;
382 }
383
384 val = 0;
385 ret = pvr2_ctrl_get_value(
386 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
387 &val);
388 vt->audmode = val;
389 break; 344 break;
390 } 345 }
391 346
@@ -405,8 +360,27 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
405 { 360 {
406 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; 361 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
407 unsigned long fv; 362 unsigned long fv;
408 fv = vf->frequency; 363 struct v4l2_tuner vt;
364 int cur_input;
365 struct pvr2_ctrl *ctrlp;
366 ret = pvr2_hdw_get_tuner_status(hdw,&vt);
367 if (ret != 0) break;
368 ctrlp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
369 ret = pvr2_ctrl_get_value(ctrlp,&cur_input);
370 if (ret != 0) break;
409 if (vf->type == V4L2_TUNER_RADIO) { 371 if (vf->type == V4L2_TUNER_RADIO) {
372 if (cur_input != PVR2_CVAL_INPUT_RADIO) {
373 pvr2_ctrl_set_value(ctrlp,
374 PVR2_CVAL_INPUT_RADIO);
375 }
376 } else {
377 if (cur_input == PVR2_CVAL_INPUT_RADIO) {
378 pvr2_ctrl_set_value(ctrlp,
379 PVR2_CVAL_INPUT_TV);
380 }
381 }
382 fv = vf->frequency;
383 if (vt.capability & V4L2_TUNER_CAP_LOW) {
410 fv = (fv * 125) / 2; 384 fv = (fv * 125) / 2;
411 } else { 385 } else {
412 fv = fv * 62500; 386 fv = fv * 62500;
@@ -420,7 +394,10 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
420 { 394 {
421 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; 395 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
422 int val = 0; 396 int val = 0;
423 int cur_input = PVR2_CVAL_INPUT_TV; 397 int cur_input;
398 struct v4l2_tuner vt;
399 ret = pvr2_hdw_get_tuner_status(hdw,&vt);
400 if (ret != 0) break;
424 ret = pvr2_ctrl_get_value( 401 ret = pvr2_ctrl_get_value(
425 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), 402 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
426 &val); 403 &val);
@@ -429,14 +406,16 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
429 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), 406 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
430 &cur_input); 407 &cur_input);
431 if (cur_input == PVR2_CVAL_INPUT_RADIO) { 408 if (cur_input == PVR2_CVAL_INPUT_RADIO) {
432 val = (val * 2) / 125;
433 vf->frequency = val;
434 vf->type = V4L2_TUNER_RADIO; 409 vf->type = V4L2_TUNER_RADIO;
435 } else { 410 } else {
436 val /= 62500;
437 vf->frequency = val;
438 vf->type = V4L2_TUNER_ANALOG_TV; 411 vf->type = V4L2_TUNER_ANALOG_TV;
439 } 412 }
413 if (vt.capability & V4L2_TUNER_CAP_LOW) {
414 val = (val * 2) / 125;
415 } else {
416 val /= 62500;
417 }
418 vf->frequency = val;
440 break; 419 break;
441 } 420 }
442 421
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 2a826464911a..8b37748cfcba 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -183,18 +183,6 @@ static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
183} 183}
184 184
185 185
186static int decoder_is_tuned(struct pvr2_v4l_decoder *ctxt)
187{
188 struct v4l2_tuner vt;
189 int ret;
190
191 memset(&vt,0,sizeof(vt));
192 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
193 if (ret < 0) return -EINVAL;
194 return vt.signal ? 1 : 0;
195}
196
197
198static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt) 186static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
199{ 187{
200 return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l"); 188 return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
@@ -227,7 +215,6 @@ int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
227 ctxt->ctrl.ctxt = ctxt; 215 ctxt->ctrl.ctxt = ctxt;
228 ctxt->ctrl.detach = (void (*)(void *))decoder_detach; 216 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
229 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; 217 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
230 ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
231 ctxt->client = cp; 218 ctxt->client = cp;
232 ctxt->hdw = hdw; 219 ctxt->hdw = hdw;
233 ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ 220 ctxt->stale_mask = (1 << (sizeof(decoder_ops)/