blob: e8a9252c7df6a2250cb301f7c8f792fd50527c5f [file] [log] [blame]
Mike Iselyd8554972006-06-26 20:58:46 -03001/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
7 *
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
11 *
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.
16 *
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
20 *
21 */
22
23/*
24
25 This source file is specifically designed to interface with the
26 cx2584x, in kernels 2.6.16 or newer.
27
28*/
29
30#include "pvrusb2-cx2584x-v4l.h"
31#include "pvrusb2-video-v4l.h"
32#include "pvrusb2-i2c-cmd-v4l2.h"
33
34
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>
42
43struct pvr2_v4l_cx2584x {
44 struct pvr2_i2c_handler handler;
45 struct pvr2_decoder_ctrl ctrl;
46 struct pvr2_i2c_client *client;
47 struct pvr2_hdw *hdw;
48 unsigned long stale_mask;
49};
50
51
52static void set_input(struct pvr2_v4l_cx2584x *ctxt)
53{
54 struct pvr2_hdw *hdw = ctxt->hdw;
55 struct v4l2_routing route;
56 enum cx25840_video_input vid_input;
57 enum cx25840_audio_input aud_input;
58
59 memset(&route,0,sizeof(route));
60
61 switch(hdw->input_val) {
62 case PVR2_CVAL_INPUT_TV:
63 vid_input = CX25840_COMPOSITE7;
64 aud_input = CX25840_AUDIO8;
65 break;
Mike Isely20832302006-12-27 23:26:55 -030066 case PVR2_CVAL_INPUT_RADIO: // Treat same as composite
Mike Iselyd8554972006-06-26 20:58:46 -030067 case PVR2_CVAL_INPUT_COMPOSITE:
68 vid_input = CX25840_COMPOSITE3;
69 aud_input = CX25840_AUDIO_SERIAL;
70 break;
71 case PVR2_CVAL_INPUT_SVIDEO:
72 vid_input = CX25840_SVIDEO1;
73 aud_input = CX25840_AUDIO_SERIAL;
74 break;
Mike Iselyd8554972006-06-26 20:58:46 -030075 default:
76 // Just set it to be composite input for now...
77 vid_input = CX25840_COMPOSITE3;
78 aud_input = CX25840_AUDIO_SERIAL;
79 break;
80 }
81
82 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
83 vid_input,aud_input);
84 route.input = (u32)vid_input;
85 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
86 route.input = (u32)aud_input;
87 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
88}
89
90
91static int check_input(struct pvr2_v4l_cx2584x *ctxt)
92{
93 struct pvr2_hdw *hdw = ctxt->hdw;
94 return hdw->input_dirty != 0;
95}
96
97
98static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
99{
100 u32 val;
101 struct pvr2_hdw *hdw = ctxt->hdw;
102
103 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
104 hdw->srate_val);
105 switch (hdw->srate_val) {
106 default:
Mike Iselyb30d2442006-06-25 20:05:01 -0300107 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
Mike Iselyd8554972006-06-26 20:58:46 -0300108 val = 48000;
109 break;
Mike Iselyb30d2442006-06-25 20:05:01 -0300110 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
Mike Iselyd8554972006-06-26 20:58:46 -0300111 val = 44100;
112 break;
Mike Iselyb30d2442006-06-25 20:05:01 -0300113 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
114 val = 32000;
115 break;
Mike Iselyd8554972006-06-26 20:58:46 -0300116 }
117 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
118}
119
120
121static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
122{
123 struct pvr2_hdw *hdw = ctxt->hdw;
124 return hdw->srate_dirty != 0;
125}
126
127
128struct pvr2_v4l_cx2584x_ops {
129 void (*update)(struct pvr2_v4l_cx2584x *);
130 int (*check)(struct pvr2_v4l_cx2584x *);
131};
132
133
134static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
135 { .update = set_input, .check = check_input},
136 { .update = set_audio, .check = check_audio},
137};
138
139
140static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
141{
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300142 ctxt->client->handler = NULL;
143 ctxt->hdw->decoder_ctrl = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -0300144 kfree(ctxt);
145}
146
147
148static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
149{
150 unsigned long msk;
151 unsigned int idx;
152
Mike Isely27c7b712007-01-20 00:39:17 -0300153 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -0300154 msk = 1 << idx;
155 if (ctxt->stale_mask & msk) continue;
156 if (decoder_ops[idx].check(ctxt)) {
157 ctxt->stale_mask |= msk;
158 }
159 }
160 return ctxt->stale_mask != 0;
161}
162
163
164static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
165{
166 unsigned long msk;
167 unsigned int idx;
168
Mike Isely27c7b712007-01-20 00:39:17 -0300169 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -0300170 msk = 1 << idx;
171 if (!(ctxt->stale_mask & msk)) continue;
172 ctxt->stale_mask &= ~msk;
173 decoder_ops[idx].update(ctxt);
174 }
175}
176
177
178static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
179{
180 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
181 pvr2_v4l2_cmd_stream(ctxt->client,fl);
182}
183
184
185static int decoder_detect(struct pvr2_i2c_client *cp)
186{
187 int ret;
188 /* Attempt to query the decoder - let's see if it will answer */
189 struct v4l2_queryctrl qc;
190
191 memset(&qc,0,sizeof(qc));
192
193 qc.id = V4L2_CID_BRIGHTNESS;
194
195 ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
196 return ret == 0; /* Return true if it answered */
197}
198
199
Mike Iselyd8554972006-06-26 20:58:46 -0300200static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
201 char *buf,unsigned int cnt)
202{
203 return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
204}
205
206
207static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
208{
209 int ret;
Randy Dunlapc2625bf2006-10-29 11:12:27 -0300210 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -0300211 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
212}
213
214
Tobias Klauserc5a69d52007-02-17 20:11:19 +0100215static const struct pvr2_i2c_handler_functions hfuncs = {
Mike Iselyd8554972006-06-26 20:58:46 -0300216 .detach = (void (*)(void *))decoder_detach,
217 .check = (int (*)(void *))decoder_check,
218 .update = (void (*)(void *))decoder_update,
219 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
220};
221
222
223int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
224 struct pvr2_i2c_client *cp)
225{
226 struct pvr2_v4l_cx2584x *ctxt;
227
228 if (hdw->decoder_ctrl) return 0;
229 if (cp->handler) return 0;
230 if (!decoder_detect(cp)) return 0;
231
Mike Iselyca545f72007-01-20 00:37:11 -0300232 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -0300233 if (!ctxt) return 0;
Mike Iselyd8554972006-06-26 20:58:46 -0300234
235 ctxt->handler.func_data = ctxt;
236 ctxt->handler.func_table = &hfuncs;
237 ctxt->ctrl.ctxt = ctxt;
238 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
239 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
Mike Iselyd8554972006-06-26 20:58:46 -0300240 ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
241 ctxt->client = cp;
242 ctxt->hdw = hdw;
Mike Isely27c7b712007-01-20 00:39:17 -0300243 ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
Mike Iselyd8554972006-06-26 20:58:46 -0300244 hdw->decoder_ctrl = &ctxt->ctrl;
245 cp->handler = &ctxt->handler;
Mike Iselyff67c612006-11-19 20:50:31 -0300246 {
247 /*
248 Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
249 of nuttiness for cx25840 causes that module to
250 correctly set up its video scaling. This is really
251 a problem in the cx25840 module itself, but we work
252 around it here. The problem has not been seen in
253 ivtv because there VBI is supported and set up. We
254 don't do VBI here (at least not yet) and thus we
255 never attempted to even set it up.
256 */
257 struct v4l2_format fmt;
258 memset(&fmt,0,sizeof(fmt));
259 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
260 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
261 }
Mike Iselyd8554972006-06-26 20:58:46 -0300262 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
263 cp->client->addr);
264 return !0;
265}
266
267
268
269
270/*
271 Stuff for Emacs to see, in order to encourage consistent editing style:
272 *** Local Variables: ***
273 *** mode: c ***
274 *** fill-column: 70 ***
275 *** tab-width: 8 ***
276 *** c-basic-offset: 8 ***
277 *** End: ***
278 */