5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 This source file is specifically designed to interface with the
26 cx2584x, in kernels 2.6.16 or newer.
30 #include "pvrusb2-cx2584x-v4l.h"
31 #include "pvrusb2-video-v4l.h"
32 #include "pvrusb2-i2c-cmd-v4l2.h"
35 #include "pvrusb2-hdw-internal.h"
36 #include "pvrusb2-debug.h"
37 #include <media/cx25840.h>
38 #include <linux/videodev2.h>
39 #include <media/v4l2-common.h>
40 #include <linux/errno.h>
41 #include <linux/slab.h>
43 struct pvr2_v4l_cx2584x
{
44 struct pvr2_i2c_handler handler
;
45 struct pvr2_decoder_ctrl ctrl
;
46 struct pvr2_i2c_client
*client
;
48 unsigned long stale_mask
;
52 struct routing_scheme_item
{
57 struct routing_scheme
{
58 const struct routing_scheme_item
*def
;
62 static const struct routing_scheme_item routing_scheme0
[] = {
63 [PVR2_CVAL_INPUT_TV
] = {
64 .vid
= CX25840_COMPOSITE7
,
65 .aud
= CX25840_AUDIO8
,
67 [PVR2_CVAL_INPUT_RADIO
] = { /* Treat the same as composite */
68 .vid
= CX25840_COMPOSITE3
,
69 .aud
= CX25840_AUDIO_SERIAL
,
71 [PVR2_CVAL_INPUT_COMPOSITE
] = {
72 .vid
= CX25840_COMPOSITE3
,
73 .aud
= CX25840_AUDIO_SERIAL
,
75 [PVR2_CVAL_INPUT_SVIDEO
] = {
76 .vid
= CX25840_SVIDEO1
,
77 .aud
= CX25840_AUDIO_SERIAL
,
81 /* Specific to gotview device */
82 static const struct routing_scheme_item routing_schemegv
[] = {
83 [PVR2_CVAL_INPUT_TV
] = {
84 .vid
= CX25840_COMPOSITE2
,
85 .aud
= CX25840_AUDIO5
,
87 [PVR2_CVAL_INPUT_RADIO
] = { /* Treat the same as composite */
88 .vid
= CX25840_COMPOSITE1
,
89 .aud
= CX25840_AUDIO_SERIAL
,
91 [PVR2_CVAL_INPUT_COMPOSITE
] = {
92 .vid
= CX25840_COMPOSITE1
,
93 .aud
= CX25840_AUDIO_SERIAL
,
95 [PVR2_CVAL_INPUT_SVIDEO
] = {
96 .vid
= (CX25840_SVIDEO_LUMA3
|CX25840_SVIDEO_CHROMA4
),
97 .aud
= CX25840_AUDIO_SERIAL
,
101 static const struct routing_scheme routing_schemes
[] = {
102 [PVR2_ROUTING_SCHEME_HAUPPAUGE
] = {
103 .def
= routing_scheme0
,
104 .cnt
= ARRAY_SIZE(routing_scheme0
),
106 [PVR2_ROUTING_SCHEME_GOTVIEW
] = {
107 .def
= routing_schemegv
,
108 .cnt
= ARRAY_SIZE(routing_schemegv
),
112 static void set_input(struct pvr2_v4l_cx2584x
*ctxt
)
114 struct pvr2_hdw
*hdw
= ctxt
->hdw
;
115 struct v4l2_routing route
;
116 enum cx25840_video_input vid_input
;
117 enum cx25840_audio_input aud_input
;
118 const struct routing_scheme
*sp
;
119 unsigned int sid
= hdw
->hdw_desc
->signal_routing_scheme
;
121 memset(&route
,0,sizeof(route
));
123 if ((sid
< ARRAY_SIZE(routing_schemes
)) &&
124 ((sp
= routing_schemes
+ sid
) != 0) &&
125 (hdw
->input_val
>= 0) &&
126 (hdw
->input_val
< sp
->cnt
)) {
127 vid_input
= sp
->def
[hdw
->input_val
].vid
;
128 aud_input
= sp
->def
[hdw
->input_val
].aud
;
130 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
131 "*** WARNING *** i2c cx2584x set_input:"
132 " Invalid routing scheme (%u) and/or input (%d)",
137 pvr2_trace(PVR2_TRACE_CHIPS
,"i2c cx2584x set_input vid=0x%x aud=0x%x",
138 vid_input
,aud_input
);
139 route
.input
= (u32
)vid_input
;
140 pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_INT_S_VIDEO_ROUTING
,&route
);
141 route
.input
= (u32
)aud_input
;
142 pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_INT_S_AUDIO_ROUTING
,&route
);
146 static int check_input(struct pvr2_v4l_cx2584x
*ctxt
)
148 struct pvr2_hdw
*hdw
= ctxt
->hdw
;
149 return hdw
->input_dirty
!= 0;
153 static void set_audio(struct pvr2_v4l_cx2584x
*ctxt
)
156 struct pvr2_hdw
*hdw
= ctxt
->hdw
;
158 pvr2_trace(PVR2_TRACE_CHIPS
,"i2c cx2584x set_audio %d",
160 switch (hdw
->srate_val
) {
162 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
:
165 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100
:
168 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000
:
172 pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_INT_AUDIO_CLOCK_FREQ
,&val
);
176 static int check_audio(struct pvr2_v4l_cx2584x
*ctxt
)
178 struct pvr2_hdw
*hdw
= ctxt
->hdw
;
179 return hdw
->srate_dirty
!= 0;
183 struct pvr2_v4l_cx2584x_ops
{
184 void (*update
)(struct pvr2_v4l_cx2584x
*);
185 int (*check
)(struct pvr2_v4l_cx2584x
*);
189 static const struct pvr2_v4l_cx2584x_ops decoder_ops
[] = {
190 { .update
= set_input
, .check
= check_input
},
191 { .update
= set_audio
, .check
= check_audio
},
195 static void decoder_detach(struct pvr2_v4l_cx2584x
*ctxt
)
197 ctxt
->client
->handler
= NULL
;
198 pvr2_hdw_set_decoder(ctxt
->hdw
,NULL
);
203 static int decoder_check(struct pvr2_v4l_cx2584x
*ctxt
)
208 for (idx
= 0; idx
< ARRAY_SIZE(decoder_ops
); idx
++) {
210 if (ctxt
->stale_mask
& msk
) continue;
211 if (decoder_ops
[idx
].check(ctxt
)) {
212 ctxt
->stale_mask
|= msk
;
215 return ctxt
->stale_mask
!= 0;
219 static void decoder_update(struct pvr2_v4l_cx2584x
*ctxt
)
224 for (idx
= 0; idx
< ARRAY_SIZE(decoder_ops
); idx
++) {
226 if (!(ctxt
->stale_mask
& msk
)) continue;
227 ctxt
->stale_mask
&= ~msk
;
228 decoder_ops
[idx
].update(ctxt
);
233 static void decoder_enable(struct pvr2_v4l_cx2584x
*ctxt
,int fl
)
235 pvr2_trace(PVR2_TRACE_CHIPS
,"i2c cx25840 decoder_enable(%d)",fl
);
236 pvr2_v4l2_cmd_stream(ctxt
->client
,fl
);
240 static int decoder_detect(struct pvr2_i2c_client
*cp
)
243 /* Attempt to query the decoder - let's see if it will answer */
244 struct v4l2_queryctrl qc
;
246 memset(&qc
,0,sizeof(qc
));
248 qc
.id
= V4L2_CID_BRIGHTNESS
;
250 ret
= pvr2_i2c_client_cmd(cp
,VIDIOC_QUERYCTRL
,&qc
);
251 return ret
== 0; /* Return true if it answered */
255 static unsigned int decoder_describe(struct pvr2_v4l_cx2584x
*ctxt
,
256 char *buf
,unsigned int cnt
)
258 return scnprintf(buf
,cnt
,"handler: pvrusb2-cx2584x-v4l");
262 static void decoder_reset(struct pvr2_v4l_cx2584x
*ctxt
)
265 ret
= pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_INT_RESET
,NULL
);
266 pvr2_trace(PVR2_TRACE_CHIPS
,"i2c cx25840 decoder_reset (ret=%d)",ret
);
270 static const struct pvr2_i2c_handler_functions hfuncs
= {
271 .detach
= (void (*)(void *))decoder_detach
,
272 .check
= (int (*)(void *))decoder_check
,
273 .update
= (void (*)(void *))decoder_update
,
274 .describe
= (unsigned int (*)(void *,char *,unsigned int))decoder_describe
,
278 int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw
*hdw
,
279 struct pvr2_i2c_client
*cp
)
281 struct pvr2_v4l_cx2584x
*ctxt
;
283 if (hdw
->decoder_ctrl
) return 0;
284 if (cp
->handler
) return 0;
285 if (!decoder_detect(cp
)) return 0;
287 ctxt
= kzalloc(sizeof(*ctxt
),GFP_KERNEL
);
290 ctxt
->handler
.func_data
= ctxt
;
291 ctxt
->handler
.func_table
= &hfuncs
;
292 ctxt
->ctrl
.ctxt
= ctxt
;
293 ctxt
->ctrl
.detach
= (void (*)(void *))decoder_detach
;
294 ctxt
->ctrl
.enable
= (void (*)(void *,int))decoder_enable
;
295 ctxt
->ctrl
.force_reset
= (void (*)(void*))decoder_reset
;
298 ctxt
->stale_mask
= (1 << ARRAY_SIZE(decoder_ops
)) - 1;
299 pvr2_hdw_set_decoder(hdw
,&ctxt
->ctrl
);
300 cp
->handler
= &ctxt
->handler
;
303 Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
304 of nuttiness for cx25840 causes that module to
305 correctly set up its video scaling. This is really
306 a problem in the cx25840 module itself, but we work
307 around it here. The problem has not been seen in
308 ivtv because there VBI is supported and set up. We
309 don't do VBI here (at least not yet) and thus we
310 never attempted to even set it up.
312 struct v4l2_format fmt
;
313 memset(&fmt
,0,sizeof(fmt
));
314 fmt
.type
= V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
;
315 pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_S_FMT
,&fmt
);
317 pvr2_trace(PVR2_TRACE_CHIPS
,"i2c 0x%x cx2584x V4L2 handler set up",
326 Stuff for Emacs to see, in order to encourage consistent editing style:
327 *** Local Variables: ***
329 *** fill-column: 70 ***
331 *** c-basic-offset: 8 ***