blob: 895859ec495a7737b85ebd2ca47fd4924ed7e5da [file] [log] [blame]
Mike Iselyd8554972006-06-26 20:58:46 -03001/*
2 *
Mike Iselyd8554972006-06-26 20:58:46 -03003 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22/*
23
24 This source file is specifically designed to interface with the
25 cx2584x, in kernels 2.6.16 or newer.
26
27*/
28
29#include "pvrusb2-cx2584x-v4l.h"
30#include "pvrusb2-video-v4l.h"
31#include "pvrusb2-i2c-cmd-v4l2.h"
32
33
34#include "pvrusb2-hdw-internal.h"
35#include "pvrusb2-debug.h"
36#include <media/cx25840.h>
37#include <linux/videodev2.h>
38#include <media/v4l2-common.h>
39#include <linux/errno.h>
40#include <linux/slab.h>
41
42struct pvr2_v4l_cx2584x {
43 struct pvr2_i2c_handler handler;
44 struct pvr2_decoder_ctrl ctrl;
45 struct pvr2_i2c_client *client;
46 struct pvr2_hdw *hdw;
47 unsigned long stale_mask;
48};
49
50
Mike Iselyf5174af2007-11-26 02:07:26 -030051struct routing_scheme_item {
52 int vid;
53 int aud;
54};
55
56struct routing_scheme {
57 const struct routing_scheme_item *def;
58 unsigned int cnt;
59};
60
61static const struct routing_scheme_item routing_scheme0[] = {
62 [PVR2_CVAL_INPUT_TV] = {
63 .vid = CX25840_COMPOSITE7,
64 .aud = CX25840_AUDIO8,
65 },
66 [PVR2_CVAL_INPUT_RADIO] = { /* Treat the same as composite */
67 .vid = CX25840_COMPOSITE3,
68 .aud = CX25840_AUDIO_SERIAL,
69 },
70 [PVR2_CVAL_INPUT_COMPOSITE] = {
71 .vid = CX25840_COMPOSITE3,
72 .aud = CX25840_AUDIO_SERIAL,
73 },
74 [PVR2_CVAL_INPUT_SVIDEO] = {
75 .vid = CX25840_SVIDEO1,
76 .aud = CX25840_AUDIO_SERIAL,
77 },
78};
79
Mike Isely9e2e3ae2007-11-26 02:14:23 -030080/* Specific to gotview device */
81static const struct routing_scheme_item routing_schemegv[] = {
82 [PVR2_CVAL_INPUT_TV] = {
83 .vid = CX25840_COMPOSITE2,
84 .aud = CX25840_AUDIO5,
85 },
Mike Isely1df59f02008-04-21 03:50:39 -030086 [PVR2_CVAL_INPUT_RADIO] = {
87 /* line-in is used for radio and composite. A GPIO is
88 used to switch between the two choices. */
Mike Isely9e2e3ae2007-11-26 02:14:23 -030089 .vid = CX25840_COMPOSITE1,
90 .aud = CX25840_AUDIO_SERIAL,
91 },
92 [PVR2_CVAL_INPUT_COMPOSITE] = {
93 .vid = CX25840_COMPOSITE1,
94 .aud = CX25840_AUDIO_SERIAL,
95 },
96 [PVR2_CVAL_INPUT_SVIDEO] = {
97 .vid = (CX25840_SVIDEO_LUMA3|CX25840_SVIDEO_CHROMA4),
98 .aud = CX25840_AUDIO_SERIAL,
99 },
100};
101
Mike Iselyf5174af2007-11-26 02:07:26 -0300102static const struct routing_scheme routing_schemes[] = {
103 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
104 .def = routing_scheme0,
105 .cnt = ARRAY_SIZE(routing_scheme0),
106 },
Mike Isely9e2e3ae2007-11-26 02:14:23 -0300107 [PVR2_ROUTING_SCHEME_GOTVIEW] = {
108 .def = routing_schemegv,
109 .cnt = ARRAY_SIZE(routing_schemegv),
110 },
Mike Iselyf5174af2007-11-26 02:07:26 -0300111};
112
Mike Iselyd8554972006-06-26 20:58:46 -0300113static void set_input(struct pvr2_v4l_cx2584x *ctxt)
114{
115 struct pvr2_hdw *hdw = ctxt->hdw;
116 struct v4l2_routing route;
117 enum cx25840_video_input vid_input;
118 enum cx25840_audio_input aud_input;
Mike Iselyf5174af2007-11-26 02:07:26 -0300119 const struct routing_scheme *sp;
120 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
Mike Iselyd8554972006-06-26 20:58:46 -0300121
122 memset(&route,0,sizeof(route));
123
Mike Iselyf5174af2007-11-26 02:07:26 -0300124 if ((sid < ARRAY_SIZE(routing_schemes)) &&
Harvey Harrisona6a3a172008-04-28 16:50:03 -0700125 ((sp = routing_schemes + sid) != NULL) &&
Mike Iselyf5174af2007-11-26 02:07:26 -0300126 (hdw->input_val >= 0) &&
127 (hdw->input_val < sp->cnt)) {
128 vid_input = sp->def[hdw->input_val].vid;
129 aud_input = sp->def[hdw->input_val].aud;
130 } else {
131 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
132 "*** WARNING *** i2c cx2584x set_input:"
133 " Invalid routing scheme (%u) and/or input (%d)",
134 sid,hdw->input_val);
135 return;
Mike Iselyd8554972006-06-26 20:58:46 -0300136 }
137
138 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
139 vid_input,aud_input);
140 route.input = (u32)vid_input;
141 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
142 route.input = (u32)aud_input;
143 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
144}
145
146
147static int check_input(struct pvr2_v4l_cx2584x *ctxt)
148{
149 struct pvr2_hdw *hdw = ctxt->hdw;
150 return hdw->input_dirty != 0;
151}
152
153
154static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
155{
156 u32 val;
157 struct pvr2_hdw *hdw = ctxt->hdw;
158
159 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
160 hdw->srate_val);
161 switch (hdw->srate_val) {
162 default:
Mike Iselyb30d2442006-06-25 20:05:01 -0300163 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
Mike Iselyd8554972006-06-26 20:58:46 -0300164 val = 48000;
165 break;
Mike Iselyb30d2442006-06-25 20:05:01 -0300166 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
Mike Iselyd8554972006-06-26 20:58:46 -0300167 val = 44100;
168 break;
Mike Iselyb30d2442006-06-25 20:05:01 -0300169 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
170 val = 32000;
171 break;
Mike Iselyd8554972006-06-26 20:58:46 -0300172 }
173 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
174}
175
176
177static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
178{
179 struct pvr2_hdw *hdw = ctxt->hdw;
180 return hdw->srate_dirty != 0;
181}
182
183
184struct pvr2_v4l_cx2584x_ops {
185 void (*update)(struct pvr2_v4l_cx2584x *);
186 int (*check)(struct pvr2_v4l_cx2584x *);
187};
188
189
190static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
191 { .update = set_input, .check = check_input},
192 { .update = set_audio, .check = check_audio},
193};
194
195
196static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
197{
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300198 ctxt->client->handler = NULL;
Mike Isely681c7392007-11-26 01:48:52 -0300199 pvr2_hdw_set_decoder(ctxt->hdw,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -0300200 kfree(ctxt);
201}
202
203
204static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
205{
206 unsigned long msk;
207 unsigned int idx;
208
Mike Isely27c7b712007-01-20 00:39:17 -0300209 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -0300210 msk = 1 << idx;
211 if (ctxt->stale_mask & msk) continue;
212 if (decoder_ops[idx].check(ctxt)) {
213 ctxt->stale_mask |= msk;
214 }
215 }
216 return ctxt->stale_mask != 0;
217}
218
219
220static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
221{
222 unsigned long msk;
223 unsigned int idx;
224
Mike Isely27c7b712007-01-20 00:39:17 -0300225 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -0300226 msk = 1 << idx;
227 if (!(ctxt->stale_mask & msk)) continue;
228 ctxt->stale_mask &= ~msk;
229 decoder_ops[idx].update(ctxt);
230 }
231}
232
233
234static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
235{
236 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
237 pvr2_v4l2_cmd_stream(ctxt->client,fl);
238}
239
240
241static int decoder_detect(struct pvr2_i2c_client *cp)
242{
243 int ret;
244 /* Attempt to query the decoder - let's see if it will answer */
245 struct v4l2_queryctrl qc;
246
247 memset(&qc,0,sizeof(qc));
248
249 qc.id = V4L2_CID_BRIGHTNESS;
250
251 ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
252 return ret == 0; /* Return true if it answered */
253}
254
255
Mike Iselyd8554972006-06-26 20:58:46 -0300256static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
257 char *buf,unsigned int cnt)
258{
259 return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
260}
261
262
263static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
264{
265 int ret;
Randy Dunlapc2625bf2006-10-29 11:12:27 -0300266 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -0300267 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
268}
269
270
Tobias Klauserc5a69d52007-02-17 20:11:19 +0100271static const struct pvr2_i2c_handler_functions hfuncs = {
Mike Iselyd8554972006-06-26 20:58:46 -0300272 .detach = (void (*)(void *))decoder_detach,
273 .check = (int (*)(void *))decoder_check,
274 .update = (void (*)(void *))decoder_update,
275 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
276};
277
278
279int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
280 struct pvr2_i2c_client *cp)
281{
282 struct pvr2_v4l_cx2584x *ctxt;
283
284 if (hdw->decoder_ctrl) return 0;
285 if (cp->handler) return 0;
286 if (!decoder_detect(cp)) return 0;
287
Mike Iselyca545f72007-01-20 00:37:11 -0300288 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -0300289 if (!ctxt) return 0;
Mike Iselyd8554972006-06-26 20:58:46 -0300290
291 ctxt->handler.func_data = ctxt;
292 ctxt->handler.func_table = &hfuncs;
293 ctxt->ctrl.ctxt = ctxt;
294 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
295 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
Mike Iselyd8554972006-06-26 20:58:46 -0300296 ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
297 ctxt->client = cp;
298 ctxt->hdw = hdw;
Mike Isely27c7b712007-01-20 00:39:17 -0300299 ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
Mike Isely681c7392007-11-26 01:48:52 -0300300 pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
Mike Iselyd8554972006-06-26 20:58:46 -0300301 cp->handler = &ctxt->handler;
Mike Iselyff67c612006-11-19 20:50:31 -0300302 {
303 /*
304 Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
305 of nuttiness for cx25840 causes that module to
306 correctly set up its video scaling. This is really
307 a problem in the cx25840 module itself, but we work
308 around it here. The problem has not been seen in
309 ivtv because there VBI is supported and set up. We
310 don't do VBI here (at least not yet) and thus we
311 never attempted to even set it up.
312 */
313 struct v4l2_format fmt;
314 memset(&fmt,0,sizeof(fmt));
315 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
316 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
317 }
Mike Iselyd8554972006-06-26 20:58:46 -0300318 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
319 cp->client->addr);
320 return !0;
321}
322
323
324
325
326/*
327 Stuff for Emacs to see, in order to encourage consistent editing style:
328 *** Local Variables: ***
329 *** mode: c ***
330 *** fill-column: 70 ***
331 *** tab-width: 8 ***
332 *** c-basic-offset: 8 ***
333 *** End: ***
334 */