aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/cx18-audio.c44
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c374
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c82
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c4
-rw-r--r--drivers/media/video/cx18/cx18-cards.c63
-rw-r--r--drivers/media/video/cx18/cx18-controls.c6
-rw-r--r--drivers/media/video/cx18/cx18-driver.c100
-rw-r--r--drivers/media/video/cx18/cx18-driver.h22
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c54
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c7
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c114
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h2
-rw-r--r--drivers/media/video/cx18/cx18-queue.c85
-rw-r--r--drivers/media/video/cx18/cx18-streams.c44
-rw-r--r--drivers/media/video/cx18/cx18-streams.h20
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
16 files changed, 773 insertions, 250 deletions
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 7a8ad5963de8..35268923911c 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -26,14 +26,18 @@
26#include "cx18-cards.h" 26#include "cx18-cards.h"
27#include "cx18-audio.h" 27#include "cx18-audio.h"
28 28
29#define CX18_AUDIO_ENABLE 0xc72014 29#define CX18_AUDIO_ENABLE 0xc72014
30#define CX18_AI1_MUX_MASK 0x30
31#define CX18_AI1_MUX_I2S1 0x00
32#define CX18_AI1_MUX_I2S2 0x10
33#define CX18_AI1_MUX_843_I2S 0x20
30 34
31/* Selects the audio input and output according to the current 35/* Selects the audio input and output according to the current
32 settings. */ 36 settings. */
33int cx18_audio_set_io(struct cx18 *cx) 37int cx18_audio_set_io(struct cx18 *cx)
34{ 38{
35 const struct cx18_card_audio_input *in; 39 const struct cx18_card_audio_input *in;
36 u32 val; 40 u32 u, v;
37 int err; 41 int err;
38 42
39 /* Determine which input to use */ 43 /* Determine which input to use */
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx)
52 return err; 56 return err;
53 57
54 /* FIXME - this internal mux should be abstracted to a subdev */ 58 /* FIXME - this internal mux should be abstracted to a subdev */
55 val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; 59 u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
56 val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : 60 v = u & ~CX18_AI1_MUX_MASK;
57 (in->audio_input << 4); 61 switch (in->audio_input) {
58 cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); 62 case CX18_AV_AUDIO_SERIAL1:
63 v |= CX18_AI1_MUX_I2S1;
64 break;
65 case CX18_AV_AUDIO_SERIAL2:
66 v |= CX18_AI1_MUX_I2S2;
67 break;
68 default:
69 v |= CX18_AI1_MUX_843_I2S;
70 break;
71 }
72 if (v == u) {
73 /* force a toggle of some AI1 MUX control bits */
74 u &= ~CX18_AI1_MUX_MASK;
75 switch (in->audio_input) {
76 case CX18_AV_AUDIO_SERIAL1:
77 u |= CX18_AI1_MUX_843_I2S;
78 break;
79 case CX18_AV_AUDIO_SERIAL2:
80 u |= CX18_AI1_MUX_843_I2S;
81 break;
82 default:
83 u |= CX18_AI1_MUX_I2S1;
84 break;
85 }
86 cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
87 u, CX18_AI1_MUX_MASK);
88 }
89 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
90 v, CX18_AI1_MUX_MASK);
59 return 0; 91 return 0;
60} 92}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index cf2bd888a429..536dedb23ba3 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -99,9 +99,39 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
99 or_value); 99 or_value);
100} 100}
101 101
102static void cx18_av_initialize(struct cx18 *cx) 102static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
103{ 103{
104 struct cx18_av_state *state = &cx->av_state; 104 struct cx18 *cx = v4l2_get_subdevdata(sd);
105
106 /*
107 * The crystal freq used in calculations in this driver will be
108 * 28.636360 MHz.
109 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
110 */
111
112 /*
113 * VDCLK Integer = 0x0f, Post Divider = 0x04
114 * AIMCLK Integer = 0x0e, Post Divider = 0x16
115 */
116 cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
117
118 /* VDCLK Fraction = 0x2be2fe */
119 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
120 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
121
122 /* AIMCLK Fraction = 0x05227ad */
123 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
124 cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
125
126 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
127 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
128 return 0;
129}
130
131static void cx18_av_initialize(struct v4l2_subdev *sd)
132{
133 struct cx18_av_state *state = to_cx18_av_state(sd);
134 struct cx18 *cx = v4l2_get_subdevdata(sd);
105 u32 v; 135 u32 v;
106 136
107 cx18_av_loadfw(cx); 137 cx18_av_loadfw(cx);
@@ -150,6 +180,26 @@ static void cx18_av_initialize(struct cx18 *cx)
150 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); 180 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
151 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); 181 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
152 182
183 /*
184 * Disable Video Auto-config of the Analog Front End and Video PLL.
185 *
186 * Since we only use BT.656 pixel mode, which works for both 525 and 625
187 * line systems, it's just easier for us to set registers
188 * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL),
189 * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC)
190 * ourselves, than to run around cleaning up after the auto-config.
191 *
192 * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit
193 * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL
194 * autoconfig either.)
195 *
196 * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3.
197 */
198 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
199
200 /* Setup the Video and and Aux/Audio PLLs */
201 cx18_av_init(sd, 0);
202
153 /* set video to auto-detect */ 203 /* set video to auto-detect */
154 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ 204 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
155 /* set the comb notch = 1 */ 205 /* set the comb notch = 1 */
@@ -176,12 +226,23 @@ static void cx18_av_initialize(struct cx18 *cx)
176 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ 226 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
177 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ 227 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
178 228
179 v = cx18_av_read4(cx, CXADEC_AFE_CTRL); 229 /*
180 v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */ 230 * Analog Front End (AFE)
181 v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */ 231 * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2
182 v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */ 232 * bypass_ch[1-3] use filter
183 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */ 233 * droop_comp_ch[1-3] disable
184 cx18_av_write4(cx, CXADEC_AFE_CTRL, v); 234 * clamp_en_ch[1-3] disable
235 * aud_in_sel ADC2
236 * luma_in_sel ADC1
237 * chroma_in_sel ADC2
238 * clamp_sel_ch[2-3] midcode
239 * clamp_sel_ch1 video decoder
240 * vga_sel_ch3 audio decoder
241 * vga_sel_ch[1-2] video decoder
242 * half_bw_ch[1-3] disable
243 * +12db_ch[1-3] disable
244 */
245 cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
185 246
186/* if(dwEnable && dw3DCombAvailable) { */ 247/* if(dwEnable && dw3DCombAvailable) { */
187/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ 248/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
@@ -195,50 +256,18 @@ static void cx18_av_initialize(struct cx18 *cx)
195 256
196static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) 257static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
197{ 258{
198 struct cx18 *cx = v4l2_get_subdevdata(sd); 259 cx18_av_initialize(sd);
199
200 cx18_av_initialize(cx);
201 return 0;
202}
203
204static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
205{
206 struct cx18 *cx = v4l2_get_subdevdata(sd);
207
208 /*
209 * The crystal freq used in calculations in this driver will be
210 * 28.636360 MHz.
211 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
212 */
213
214 /*
215 * VDCLK Integer = 0x0f, Post Divider = 0x04
216 * AIMCLK Integer = 0x0e, Post Divider = 0x16
217 */
218 cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
219
220 /* VDCLK Fraction = 0x2be2fe */
221 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
222 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
223
224 /* AIMCLK Fraction = 0x05227ad */
225 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
226 cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
227
228 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
229 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
230 return 0; 260 return 0;
231} 261}
232 262
233static int cx18_av_load_fw(struct v4l2_subdev *sd) 263static int cx18_av_load_fw(struct v4l2_subdev *sd)
234{ 264{
235 struct cx18_av_state *state = to_cx18_av_state(sd); 265 struct cx18_av_state *state = to_cx18_av_state(sd);
236 struct cx18 *cx = v4l2_get_subdevdata(sd);
237 266
238 if (!state->is_initialized) { 267 if (!state->is_initialized) {
239 /* initialize on first use */ 268 /* initialize on first use */
240 state->is_initialized = 1; 269 state->is_initialized = 1;
241 cx18_av_initialize(cx); 270 cx18_av_initialize(sd);
242 } 271 }
243 return 0; 272 return 0;
244} 273}
@@ -248,8 +277,15 @@ void cx18_av_std_setup(struct cx18 *cx)
248 struct cx18_av_state *state = &cx->av_state; 277 struct cx18_av_state *state = &cx->av_state;
249 struct v4l2_subdev *sd = &state->sd; 278 struct v4l2_subdev *sd = &state->sd;
250 v4l2_std_id std = state->std; 279 v4l2_std_id std = state->std;
280
281 /*
282 * Video ADC crystal clock to pixel clock SRC decimation ratio
283 * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b
284 */
285 const int src_decimation = 0x21f;
286
251 int hblank, hactive, burst, vblank, vactive, sc; 287 int hblank, hactive, burst, vblank, vactive, sc;
252 int vblank656, src_decimation; 288 int vblank656;
253 int luma_lpf, uv_lpf, comb; 289 int luma_lpf, uv_lpf, comb;
254 u32 pll_int, pll_frac, pll_post; 290 u32 pll_int, pll_frac, pll_post;
255 291
@@ -259,40 +295,96 @@ void cx18_av_std_setup(struct cx18 *cx)
259 else 295 else
260 cx18_av_write(cx, 0x49f, 0x14); 296 cx18_av_write(cx, 0x49f, 0x14);
261 297
298 /*
299 * Note: At the end of a field, there are 3 sets of half line duration
300 * (double horizontal rate) pulses:
301 *
302 * 5 (625) or 6 (525) half-lines to blank for the vertical retrace
303 * 5 (625) or 6 (525) vertical sync pulses of half line duration
304 * 5 (625) or 6 (525) half-lines of equalization pulses
305 */
262 if (std & V4L2_STD_625_50) { 306 if (std & V4L2_STD_625_50) {
263 /* FIXME - revisit these for Sliced VBI */ 307 /*
308 * The following relationships of half line counts should hold:
309 * 625 = vblank656 + vactive
310 * 10 = vblank656 - vblank = vsync pulses + equalization pulses
311 *
312 * vblank656: half lines after line 625/mid-313 of blanked video
313 * vblank: half lines, after line 5/317, of blanked video
314 * vactive: half lines of active video +
315 * 5 half lines after the end of active video
316 *
317 * As far as I can tell:
318 * vblank656 starts counting from the falling edge of the first
319 * vsync pulse (start of line 1 or mid-313)
320 * vblank starts counting from the after the 5 vsync pulses and
321 * 5 or 4 equalization pulses (start of line 6 or 318)
322 *
323 * For 625 line systems the driver will extract VBI information
324 * from lines 6-23 and lines 318-335 (but the slicer can only
325 * handle 17 lines, not the 18 in the vblank region).
326 * In addition, we need vblank656 and vblank to be one whole
327 * line longer, to cover line 24 and 336, so the SAV/EAV RP
328 * codes get generated such that the encoder can actually
329 * extract line 23 & 335 (WSS). We'll lose 1 line in each field
330 * at the top of the screen.
331 *
332 * It appears the 5 half lines that happen after active
333 * video must be included in vactive (579 instead of 574),
334 * otherwise the colors get badly displayed in various regions
335 * of the screen. I guess the chroma comb filter gets confused
336 * without them (at least when a PVR-350 is the PAL source).
337 */
338 vblank656 = 48; /* lines 1 - 24 & 313 - 336 */
339 vblank = 38; /* lines 6 - 24 & 318 - 336 */
340 vactive = 579; /* lines 24 - 313 & 337 - 626 */
341
342 /*
343 * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
344 * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601
345 * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after
346 * the end of active video to start a horizontal line, so that
347 * leaves 132 pixels of hblank to ignore.
348 */
264 hblank = 132; 349 hblank = 132;
265 hactive = 720; 350 hactive = 720;
266 burst = 93;
267 vblank = 36;
268 vactive = 580;
269 vblank656 = 40;
270 src_decimation = 0x21f;
271 351
352 /*
353 * Burst gate delay (for 625 line systems)
354 * Hsync leading edge to color burst rise = 5.6 us
355 * Color burst width = 2.25 us
356 * Gate width = 4 pixel clocks
357 * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks
358 */
359 burst = 93;
272 luma_lpf = 2; 360 luma_lpf = 2;
273 if (std & V4L2_STD_PAL) { 361 if (std & V4L2_STD_PAL) {
274 uv_lpf = 1; 362 uv_lpf = 1;
275 comb = 0x20; 363 comb = 0x20;
276 sc = 688739; 364 /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
365 sc = 688700;
277 } else if (std == V4L2_STD_PAL_Nc) { 366 } else if (std == V4L2_STD_PAL_Nc) {
278 uv_lpf = 1; 367 uv_lpf = 1;
279 comb = 0x20; 368 comb = 0x20;
280 sc = 556453; 369 /* sc = 3582056.25 * src_decimation/28636360 * 2^13 */
370 sc = 556422;
281 } else { /* SECAM */ 371 } else { /* SECAM */
282 uv_lpf = 0; 372 uv_lpf = 0;
283 comb = 0; 373 comb = 0;
284 sc = 672351; 374 /* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */
375 /* sc = 4328130 * src_decimation/28636360 * 2^13 */
376 sc = 672314;
285 } 377 }
286 } else { 378 } else {
287 /* 379 /*
288 * The following relationships of half line counts should hold: 380 * The following relationships of half line counts should hold:
289 * 525 = vsync + vactive + vblank656 381 * 525 = prevsync + vblank656 + vactive
290 * 12 = vblank656 - vblank 382 * 12 = vblank656 - vblank = vsync pulses + equalization pulses
291 * 383 *
292 * vsync: always 6 half-lines of vsync pulses 384 * prevsync: 6 half-lines before the vsync pulses
293 * vactive: half lines of active video
294 * vblank656: half lines, after line 3/mid-266, of blanked video 385 * vblank656: half lines, after line 3/mid-266, of blanked video
295 * vblank: half lines, after line 9/272, of blanked video 386 * vblank: half lines, after line 9/272, of blanked video
387 * vactive: half lines of active video
296 * 388 *
297 * As far as I can tell: 389 * As far as I can tell:
298 * vblank656 starts counting from the falling edge of the first 390 * vblank656 starts counting from the falling edge of the first
@@ -319,20 +411,30 @@ void cx18_av_std_setup(struct cx18 *cx)
319 luma_lpf = 1; 411 luma_lpf = 1;
320 uv_lpf = 1; 412 uv_lpf = 1;
321 413
322 src_decimation = 0x21f; 414 /*
415 * Burst gate delay (for 525 line systems)
416 * Hsync leading edge to color burst rise = 5.3 us
417 * Color burst width = 2.5 us
418 * Gate width = 4 pixel clocks
419 * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks
420 */
323 if (std == V4L2_STD_PAL_60) { 421 if (std == V4L2_STD_PAL_60) {
324 burst = 0x5b; 422 burst = 90;
325 luma_lpf = 2; 423 luma_lpf = 2;
326 comb = 0x20; 424 comb = 0x20;
327 sc = 688739; 425 /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
426 sc = 688700;
328 } else if (std == V4L2_STD_PAL_M) { 427 } else if (std == V4L2_STD_PAL_M) {
329 burst = 0x61; 428 /* The 97 needs to be verified against PAL-M timings */
429 burst = 97;
330 comb = 0x20; 430 comb = 0x20;
331 sc = 555452; 431 /* sc = 3575611.49 * src_decimation/28636360 * 2^13 */
432 sc = 555421;
332 } else { 433 } else {
333 burst = 0x5b; 434 burst = 90;
334 comb = 0x66; 435 comb = 0x66;
335 sc = 556063; 436 /* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */
437 sc = 556032;
336 } 438 }
337 } 439 }
338 440
@@ -344,23 +446,26 @@ void cx18_av_std_setup(struct cx18 *cx)
344 pll_int, pll_frac, pll_post); 446 pll_int, pll_frac, pll_post);
345 447
346 if (pll_post) { 448 if (pll_post) {
347 int fin, fsc, pll; 449 int fsc, pll;
450 u64 tmp;
348 451
349 pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; 452 pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
350 pll /= pll_post; 453 pll /= pll_post;
351 CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n", 454 CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n",
352 pll / 1000000, pll % 1000000); 455 pll / 1000000, pll % 1000000);
353 CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n", 456 CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n",
354 pll / 8000000, (pll / 8) % 1000000); 457 pll / 8000000, (pll / 8) % 1000000);
355 458
356 fin = ((u64)src_decimation * pll) >> 12; 459 CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio "
357 CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n", 460 "= %d.%03d\n", src_decimation / 256,
358 fin / 1000000, fin % 1000000); 461 ((src_decimation % 256) * 1000) / 256);
359 462
360 fsc = (((u64)sc) * pll) >> 24L; 463 tmp = 28636360 * (u64) sc;
464 do_div(tmp, src_decimation);
465 fsc = tmp >> 13;
361 CX18_DEBUG_INFO_DEV(sd, 466 CX18_DEBUG_INFO_DEV(sd,
362 "Chroma sub-carrier freq = %d.%06d MHz\n", 467 "Chroma sub-carrier initial freq = %d.%06d "
363 fsc / 1000000, fsc % 1000000); 468 "MHz\n", fsc / 1000000, fsc % 1000000);
364 469
365 CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " 470 CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
366 "vactive %i, vblank656 %i, src_dec %i, " 471 "vactive %i, vblank656 %i, src_dec %i, "
@@ -470,16 +575,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
470{ 575{
471 struct cx18_av_state *state = &cx->av_state; 576 struct cx18_av_state *state = &cx->av_state;
472 struct v4l2_subdev *sd = &state->sd; 577 struct v4l2_subdev *sd = &state->sd;
473 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && 578
474 vid_input <= CX18_AV_COMPOSITE8); 579 enum analog_signal_type {
475 u8 reg; 580 NONE, CVBS, Y, C, SIF, Pb, Pr
476 u8 v; 581 } ch[3] = {NONE, NONE, NONE};
582
583 u8 afe_mux_cfg;
584 u8 adc2_cfg;
585 u32 afe_cfg;
586 int i;
477 587
478 CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n", 588 CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
479 vid_input, aud_input); 589 vid_input, aud_input);
480 590
481 if (is_composite) { 591 if (vid_input >= CX18_AV_COMPOSITE1 &&
482 reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); 592 vid_input <= CX18_AV_COMPOSITE8) {
593 afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
594 ch[0] = CVBS;
483 } else { 595 } else {
484 int luma = vid_input & 0xf0; 596 int luma = vid_input & 0xf0;
485 int chroma = vid_input & 0xf00; 597 int chroma = vid_input & 0xf00;
@@ -493,26 +605,45 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
493 vid_input); 605 vid_input);
494 return -EINVAL; 606 return -EINVAL;
495 } 607 }
496 reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); 608 afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
609 ch[0] = Y;
497 if (chroma >= CX18_AV_SVIDEO_CHROMA7) { 610 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
498 reg &= 0x3f; 611 afe_mux_cfg &= 0x3f;
499 reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; 612 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
613 ch[2] = C;
500 } else { 614 } else {
501 reg &= 0xcf; 615 afe_mux_cfg &= 0xcf;
502 reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; 616 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
617 ch[1] = C;
503 } 618 }
504 } 619 }
620 /* TODO: LeadTek WinFast DVR3100 H & WinFast PVR2100 can do Y/Pb/Pr */
505 621
506 switch (aud_input) { 622 switch (aud_input) {
507 case CX18_AV_AUDIO_SERIAL1: 623 case CX18_AV_AUDIO_SERIAL1:
508 case CX18_AV_AUDIO_SERIAL2: 624 case CX18_AV_AUDIO_SERIAL2:
509 /* do nothing, use serial audio input */ 625 /* do nothing, use serial audio input */
510 break; 626 break;
511 case CX18_AV_AUDIO4: reg &= ~0x30; break; 627 case CX18_AV_AUDIO4:
512 case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break; 628 afe_mux_cfg &= ~0x30;
513 case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break; 629 ch[1] = SIF;
514 case CX18_AV_AUDIO7: reg &= ~0xc0; break; 630 break;
515 case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; 631 case CX18_AV_AUDIO5:
632 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
633 ch[1] = SIF;
634 break;
635 case CX18_AV_AUDIO6:
636 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
637 ch[1] = SIF;
638 break;
639 case CX18_AV_AUDIO7:
640 afe_mux_cfg &= ~0xc0;
641 ch[2] = SIF;
642 break;
643 case CX18_AV_AUDIO8:
644 afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
645 ch[2] = SIF;
646 break;
516 647
517 default: 648 default:
518 CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n", 649 CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
@@ -520,24 +651,65 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
520 return -EINVAL; 651 return -EINVAL;
521 } 652 }
522 653
523 cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7); 654 /* Set up analog front end multiplexers */
655 cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
524 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 656 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
525 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); 657 cx18_av_and_or(cx, 0x401, ~0x6, ch[0] == CVBS ? 0 : 0x02);
526 658
527 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 659 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
528 v = cx18_av_read(cx, 0x102); 660 adc2_cfg = cx18_av_read(cx, 0x102);
529 if (reg & 0x80) 661 if (ch[2] == NONE)
530 v &= ~0x2; 662 adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */
531 else 663 else
532 v |= 0x2; 664 adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */
665
533 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ 666 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
534 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) 667 if (ch[1] != NONE && ch[2] != NONE)
535 v |= 0x4; 668 adc2_cfg |= 0x4; /* Set dual mode */
536 else 669 else
537 v &= ~0x4; 670 adc2_cfg &= ~0x4; /* Clear dual mode */
538 cx18_av_write_expect(cx, 0x102, v, v, 0x17); 671 cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
672
673 /* Configure the analog front end */
674 afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
675 afe_cfg &= 0xff000000;
676 afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */
677 if (ch[1] != NONE && ch[2] != NONE)
678 afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */
679
680 for (i = 0; i < 3; i++) {
681 switch (ch[i]) {
682 default:
683 case NONE:
684 /* CLAMP_SEL = Fixed to midcode clamp level */
685 afe_cfg |= (0x00000200 << i);
686 break;
687 case CVBS:
688 case Y:
689 if (i > 0)
690 afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */
691 break;
692 case C:
693 case Pb:
694 case Pr:
695 /* CLAMP_SEL = Fixed to midcode clamp level */
696 afe_cfg |= (0x00000200 << i);
697 if (i == 0 && ch[i] == C)
698 afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */
699 break;
700 case SIF:
701 /*
702 * VGA_GAIN_SEL = Audio Decoder
703 * CLAMP_SEL = Fixed to midcode clamp level
704 */
705 afe_cfg |= (0x00000240 << i);
706 if (i == 0)
707 afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */
708 break;
709 }
710 }
539 711
540 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/ 712 cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
541 713
542 state->vid_input = vid_input; 714 state->vid_input = vid_input;
543 state->aud_input = aud_input; 715 state->aud_input = aud_input;
@@ -858,9 +1030,9 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
858 * cx18_av_std_setup(), above standard values: 1030 * cx18_av_std_setup(), above standard values:
859 * 1031 *
860 * 480 + 1 for 60 Hz systems 1032 * 480 + 1 for 60 Hz systems
861 * 576 + 4 for 50 Hz systems 1033 * 576 + 3 for 50 Hz systems
862 */ 1034 */
863 Vlines = pix->height + (is_50Hz ? 4 : 1); 1035 Vlines = pix->height + (is_50Hz ? 3 : 1);
864 1036
865 /* 1037 /*
866 * Invalid height and width scaling requests are: 1038 * Invalid height and width scaling requests are:
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 49a55cc8d839..b9e8cc5d264a 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -24,15 +24,63 @@
24#include "cx18-io.h" 24#include "cx18-io.h"
25#include <linux/firmware.h> 25#include <linux/firmware.h>
26 26
27#define CX18_AUDIO_ENABLE 0xc72014 27#define CX18_AUDIO_ENABLE 0xc72014
28#define CX18_AI1_MUX_MASK 0x30
29#define CX18_AI1_MUX_I2S1 0x00
30#define CX18_AI1_MUX_I2S2 0x10
31#define CX18_AI1_MUX_843_I2S 0x20
32#define CX18_AI1_MUX_INVALID 0x30
33
28#define FWFILE "v4l-cx23418-dig.fw" 34#define FWFILE "v4l-cx23418-dig.fw"
29 35
36static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
37{
38 struct v4l2_subdev *sd = &cx->av_state.sd;
39 int ret = 0;
40 const u8 *data;
41 u32 size;
42 int addr;
43 u32 expected, dl_control;
44
45 /* Ensure we put the 8051 in reset and enable firmware upload mode */
46 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
47 do {
48 dl_control &= 0x00ffffff;
49 dl_control |= 0x0f000000;
50 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
51 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
52 } while ((dl_control & 0xff000000) != 0x0f000000);
53
54 /* Read and auto increment until at address 0x0000 */
55 while (dl_control & 0x3fff)
56 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
57
58 data = fw->data;
59 size = fw->size;
60 for (addr = 0; addr < size; addr++) {
61 dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
62 expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
63 if (expected != dl_control) {
64 CX18_ERR_DEV(sd, "verification of %s firmware load "
65 "failed: expected %#010x got %#010x\n",
66 FWFILE, expected, dl_control);
67 ret = -EIO;
68 break;
69 }
70 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
71 }
72 if (ret == 0)
73 CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
74 FWFILE, size);
75 return ret;
76}
77
30int cx18_av_loadfw(struct cx18 *cx) 78int cx18_av_loadfw(struct cx18 *cx)
31{ 79{
32 struct v4l2_subdev *sd = &cx->av_state.sd; 80 struct v4l2_subdev *sd = &cx->av_state.sd;
33 const struct firmware *fw = NULL; 81 const struct firmware *fw = NULL;
34 u32 size; 82 u32 size;
35 u32 v; 83 u32 u, v;
36 const u8 *ptr; 84 const u8 *ptr;
37 int i; 85 int i;
38 int retries1 = 0; 86 int retries1 = 0;
@@ -95,6 +143,12 @@ int cx18_av_loadfw(struct cx18 *cx)
95 } 143 }
96 144
97 cx18_av_write4_expect(cx, CXADEC_DL_CTL, 145 cx18_av_write4_expect(cx, CXADEC_DL_CTL,
146 0x03000000 | fw->size, 0x03000000, 0x13000000);
147
148 CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
149
150 if (cx18_av_verifyfw(cx, fw) == 0)
151 cx18_av_write4_expect(cx, CXADEC_DL_CTL,
98 0x13000000 | fw->size, 0x13000000, 0x13000000); 152 0x13000000 | fw->size, 0x13000000, 0x13000000);
99 153
100 /* Output to the 416 */ 154 /* Output to the 416 */
@@ -135,6 +189,28 @@ int cx18_av_loadfw(struct cx18 *cx)
135 cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, 189 cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
136 0, 0x400); 190 0, 0x400);
137 191
192 /* Toggle the AI1 MUX */
193 v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
194 u = v & CX18_AI1_MUX_MASK;
195 v &= ~CX18_AI1_MUX_MASK;
196 if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
197 /* Switch to I2S1 */
198 v |= CX18_AI1_MUX_I2S1;
199 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
200 v, CX18_AI1_MUX_MASK);
201 /* Switch back to the A/V decoder core I2S output */
202 v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
203 } else {
204 /* Switch to the A/V decoder core I2S output */
205 v |= CX18_AI1_MUX_843_I2S;
206 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
207 v, CX18_AI1_MUX_MASK);
208 /* Switch back to I2S1 or I2S2 */
209 v = (v & ~CX18_AI1_MUX_MASK) | u;
210 }
211 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
212 v, CX18_AI1_MUX_MASK);
213
138 /* Enable WW auto audio standard detection */ 214 /* Enable WW auto audio standard detection */
139 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); 215 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
140 v |= 0xFF; /* Auto by default */ 216 v |= 0xFF; /* Auto by default */
@@ -143,7 +219,5 @@ int cx18_av_loadfw(struct cx18 *cx)
143 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF); 219 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
144 220
145 release_firmware(fw); 221 release_firmware(fw);
146
147 CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
148 return 0; 222 return 0;
149} 223}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 23b31670bf1d..a51732bcca4b 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -255,8 +255,8 @@ int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
255 } 255 }
256 256
257 cx18_av_write(cx, 0x43c, 0x16); 257 cx18_av_write(cx, 0x43c, 0x16);
258 /* FIXME - should match vblank set in cx18_av_std_setup() */ 258 /* Should match vblank set in cx18_av_std_setup() */
259 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); 259 cx18_av_write(cx, 0x474, is_pal ? 38 : 26);
260 return 0; 260 return 0;
261} 261}
262 262
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 9bc221837847..c92a25036f0e 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -340,13 +340,12 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
340 340
341static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { 341static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
342 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ 342 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
343 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
344 { 0, 0, 0 } 343 { 0, 0, 0 }
345}; 344};
346 345
347static const struct cx18_card cx18_card_leadtek_pvr2100 = { 346static const struct cx18_card cx18_card_leadtek_pvr2100 = {
348 .type = CX18_CARD_LEADTEK_PVR2100, 347 .type = CX18_CARD_LEADTEK_PVR2100,
349 .name = "Leadtek WinFast PVR2100/DVR3100 H", 348 .name = "Leadtek WinFast PVR2100",
350 .comment = "Experimenters and photos needed for device to work well.\n" 349 .comment = "Experimenters and photos needed for device to work well.\n"
351 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", 350 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
352 .v4l2_capabilities = CX18_CAP_ENCODER, 351 .v4l2_capabilities = CX18_CAP_ENCODER,
@@ -365,15 +364,12 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
365 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, 364 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
366 }, 365 },
367 .tuners = { 366 .tuners = {
368 /* XC3028 tuner */ 367 /* XC2028 tuner */
369 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, 368 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
370 }, 369 },
371 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, 370 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
372 .ddr = { 371 .ddr = {
373 /* 372 /* Pointer to proper DDR config values provided by Terry Wu */
374 * Pointer to proper DDR config values provided by
375 * Terry Wu <terrywu at leadtek.com.tw>
376 */
377 .chip_config = 0x303, 373 .chip_config = 0x303,
378 .refresh = 0x3bb, 374 .refresh = 0x3bb,
379 .timing1 = 0x24220e83, 375 .timing1 = 0x24220e83,
@@ -392,6 +388,58 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
392 388
393/* ------------------------------------------------------------------------- */ 389/* ------------------------------------------------------------------------- */
394 390
391/* Leadtek WinFast DVR3100 H */
392
393static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
394 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
395 { 0, 0, 0 }
396};
397
398static const struct cx18_card cx18_card_leadtek_dvr3100h = {
399 .type = CX18_CARD_LEADTEK_DVR3100H,
400 .name = "Leadtek WinFast DVR3100 H",
401 .comment = "Simultaneous DVB-T and Analog capture supported,\n"
402 "\texcept when capturing Analog from the antenna input.\n",
403 .v4l2_capabilities = CX18_CAP_ENCODER,
404 .hw_audio_ctrl = CX18_HW_418_AV,
405 .hw_muxer = CX18_HW_GPIO_MUX,
406 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
407 CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
408 .video_inputs = {
409 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
410 { CX18_CARD_INPUT_SVIDEO1, 1,
411 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
412 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
413 },
414 .audio_inputs = {
415 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
416 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
417 },
418 .tuners = {
419 /* XC3028 tuner */
420 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
421 },
422 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
423 .ddr = {
424 /* Pointer to proper DDR config values provided by Terry Wu */
425 .chip_config = 0x303,
426 .refresh = 0x3bb,
427 .timing1 = 0x24220e83,
428 .timing2 = 0x1f,
429 .tune_lane = 0,
430 .initial_emrs = 0x2,
431 },
432 .gpio_init.initial_value = 0x6,
433 .gpio_init.direction = 0x7,
434 .gpio_audio_input = { .mask = 0x7,
435 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
436 .xceive_pin = 1,
437 .pci_list = cx18_pci_leadtek_dvr3100h,
438 .i2c = &cx18_i2c_std,
439};
440
441/* ------------------------------------------------------------------------- */
442
395static const struct cx18_card *cx18_card_list[] = { 443static const struct cx18_card *cx18_card_list[] = {
396 &cx18_card_hvr1600_esmt, 444 &cx18_card_hvr1600_esmt,
397 &cx18_card_hvr1600_samsung, 445 &cx18_card_hvr1600_samsung,
@@ -400,6 +448,7 @@ static const struct cx18_card *cx18_card_list[] = {
400 &cx18_card_cnxt_raptor_pal, 448 &cx18_card_cnxt_raptor_pal,
401 &cx18_card_toshiba_qosmio_dvbt, 449 &cx18_card_toshiba_qosmio_dvbt,
402 &cx18_card_leadtek_pvr2100, 450 &cx18_card_leadtek_pvr2100,
451 &cx18_card_leadtek_dvr3100h,
403}; 452};
404 453
405const struct cx18_card *cx18_get_card(u16 index) 454const struct cx18_card *cx18_get_card(u16 index)
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 82fc2f9d4021..8e35c3aed544 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -176,8 +176,10 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx,
176 return -EBUSY; 176 return -EBUSY;
177 177
178 if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || 178 if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
179 type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { 179 !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
180 /* We don't do VBI insertion aside from IVTV format in a PS */ 180 type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
181 type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
182 /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
181 cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; 183 cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
182 CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " 184 CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
183 "the MPEG stream\n"); 185 "the MPEG stream\n");
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 49b1c3d7b1a8..92026e82e10e 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -30,6 +30,7 @@
30#include "cx18-irq.h" 30#include "cx18-irq.h"
31#include "cx18-gpio.h" 31#include "cx18-gpio.h"
32#include "cx18-firmware.h" 32#include "cx18-firmware.h"
33#include "cx18-queue.h"
33#include "cx18-streams.h" 34#include "cx18-streams.h"
34#include "cx18-av-core.h" 35#include "cx18-av-core.h"
35#include "cx18-scb.h" 36#include "cx18-scb.h"
@@ -151,7 +152,8 @@ MODULE_PARM_DESC(cardtype,
151 "\t\t\t 4 = Yuan MPC718\n" 152 "\t\t\t 4 = Yuan MPC718\n"
152 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" 153 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
153 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" 154 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
154 "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n" 155 "\t\t\t 7 = Leadtek WinFast PVR2100\n"
156 "\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
155 "\t\t\t 0 = Autodetect (default)\n" 157 "\t\t\t 0 = Autodetect (default)\n"
156 "\t\t\t-1 = Ignore this card\n\t\t"); 158 "\t\t\t-1 = Ignore this card\n\t\t");
157MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); 159MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -312,7 +314,7 @@ static void cx18_process_eeprom(struct cx18 *cx)
312 CX18_INFO("Autodetected %s\n", cx->card_name); 314 CX18_INFO("Autodetected %s\n", cx->card_name);
313 315
314 if (tv.tuner_type == TUNER_ABSENT) 316 if (tv.tuner_type == TUNER_ABSENT)
315 CX18_ERR("tveeprom cannot autodetect tuner!"); 317 CX18_ERR("tveeprom cannot autodetect tuner!\n");
316 318
317 if (cx->options.tuner == -1) 319 if (cx->options.tuner == -1)
318 cx->options.tuner = tv.tuner_type; 320 cx->options.tuner = tv.tuner_type;
@@ -546,6 +548,40 @@ done:
546 cx->card_i2c = cx->card->i2c; 548 cx->card_i2c = cx->card->i2c;
547} 549}
548 550
551static int __devinit cx18_create_in_workq(struct cx18 *cx)
552{
553 snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
554 cx->v4l2_dev.name);
555 cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
556 if (cx->in_work_queue == NULL) {
557 CX18_ERR("Unable to create incoming mailbox handler thread\n");
558 return -ENOMEM;
559 }
560 return 0;
561}
562
563static int __devinit cx18_create_out_workq(struct cx18 *cx)
564{
565 snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out",
566 cx->v4l2_dev.name);
567 cx->out_work_queue = create_workqueue(cx->out_workq_name);
568 if (cx->out_work_queue == NULL) {
569 CX18_ERR("Unable to create outgoing mailbox handler threads\n");
570 return -ENOMEM;
571 }
572 return 0;
573}
574
575static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
576{
577 int i;
578 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
579 cx->in_work_order[i].cx = cx;
580 cx->in_work_order[i].str = cx->epu_debug_str;
581 INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
582 }
583}
584
549/* Precondition: the cx18 structure has been memset to 0. Only 585/* Precondition: the cx18 structure has been memset to 0. Only
550 the dev and instance fields have been filled in. 586 the dev and instance fields have been filled in.
551 No assumptions on the card type may be made here (see cx18_init_struct2 587 No assumptions on the card type may be made here (see cx18_init_struct2
@@ -553,7 +589,7 @@ done:
553 */ 589 */
554static int __devinit cx18_init_struct1(struct cx18 *cx) 590static int __devinit cx18_init_struct1(struct cx18 *cx)
555{ 591{
556 int i; 592 int ret;
557 593
558 cx->base_addr = pci_resource_start(cx->pci_dev, 0); 594 cx->base_addr = pci_resource_start(cx->pci_dev, 0);
559 595
@@ -562,18 +598,18 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
562 mutex_init(&cx->epu2apu_mb_lock); 598 mutex_init(&cx->epu2apu_mb_lock);
563 mutex_init(&cx->epu2cpu_mb_lock); 599 mutex_init(&cx->epu2cpu_mb_lock);
564 600
565 cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name); 601 ret = cx18_create_out_workq(cx);
566 if (cx->work_queue == NULL) { 602 if (ret)
567 CX18_ERR("Unable to create work hander thread\n"); 603 return ret;
568 return -ENOMEM;
569 }
570 604
571 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { 605 ret = cx18_create_in_workq(cx);
572 cx->epu_work_order[i].cx = cx; 606 if (ret) {
573 cx->epu_work_order[i].str = cx->epu_debug_str; 607 destroy_workqueue(cx->out_work_queue);
574 INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler); 608 return ret;
575 } 609 }
576 610
611 cx18_init_in_work_orders(cx);
612
577 /* start counting open_id at 1 */ 613 /* start counting open_id at 1 */
578 cx->open_id = 1; 614 cx->open_id = 1;
579 615
@@ -759,17 +795,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
759 retval = -ENODEV; 795 retval = -ENODEV;
760 goto err; 796 goto err;
761 } 797 }
762 if (cx18_init_struct1(cx)) { 798
763 retval = -ENOMEM; 799 retval = cx18_init_struct1(cx);
800 if (retval)
764 goto err; 801 goto err;
765 }
766 802
767 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); 803 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
768 804
769 /* PCI Device Setup */ 805 /* PCI Device Setup */
770 retval = cx18_setup_pci(cx, pci_dev, pci_id); 806 retval = cx18_setup_pci(cx, pci_dev, pci_id);
771 if (retval != 0) 807 if (retval != 0)
772 goto free_workqueue; 808 goto free_workqueues;
773 809
774 /* map io memory */ 810 /* map io memory */
775 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", 811 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -943,8 +979,9 @@ free_map:
943 cx18_iounmap(cx); 979 cx18_iounmap(cx);
944free_mem: 980free_mem:
945 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 981 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
946free_workqueue: 982free_workqueues:
947 destroy_workqueue(cx->work_queue); 983 destroy_workqueue(cx->in_work_queue);
984 destroy_workqueue(cx->out_work_queue);
948err: 985err:
949 if (retval == 0) 986 if (retval == 0)
950 retval = -ENODEV; 987 retval = -ENODEV;
@@ -1053,11 +1090,19 @@ int cx18_init_on_first_open(struct cx18 *cx)
1053 return 0; 1090 return 0;
1054} 1091}
1055 1092
1056static void cx18_cancel_epu_work_orders(struct cx18 *cx) 1093static void cx18_cancel_in_work_orders(struct cx18 *cx)
1057{ 1094{
1058 int i; 1095 int i;
1059 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) 1096 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
1060 cancel_work_sync(&cx->epu_work_order[i].work); 1097 cancel_work_sync(&cx->in_work_order[i].work);
1098}
1099
1100static void cx18_cancel_out_work_orders(struct cx18 *cx)
1101{
1102 int i;
1103 for (i = 0; i < CX18_MAX_STREAMS; i++)
1104 if (&cx->streams[i].video_dev != NULL)
1105 cancel_work_sync(&cx->streams[i].out_work_order);
1061} 1106}
1062 1107
1063static void cx18_remove(struct pci_dev *pci_dev) 1108static void cx18_remove(struct pci_dev *pci_dev)
@@ -1073,15 +1118,20 @@ static void cx18_remove(struct pci_dev *pci_dev)
1073 if (atomic_read(&cx->tot_capturing) > 0) 1118 if (atomic_read(&cx->tot_capturing) > 0)
1074 cx18_stop_all_captures(cx); 1119 cx18_stop_all_captures(cx);
1075 1120
1076 /* Interrupts */ 1121 /* Stop interrupts that cause incoming work to be queued */
1077 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 1122 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
1123
1124 /* Incoming work can cause outgoing work, so clean up incoming first */
1125 cx18_cancel_in_work_orders(cx);
1126 cx18_cancel_out_work_orders(cx);
1127
1128 /* Stop ack interrupts that may have been needed for work to finish */
1078 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 1129 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
1079 1130
1080 cx18_halt_firmware(cx); 1131 cx18_halt_firmware(cx);
1081 1132
1082 cx18_cancel_epu_work_orders(cx); 1133 destroy_workqueue(cx->in_work_queue);
1083 1134 destroy_workqueue(cx->out_work_queue);
1084 destroy_workqueue(cx->work_queue);
1085 1135
1086 cx18_streams_cleanup(cx, 1); 1136 cx18_streams_cleanup(cx, 1);
1087 1137
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index ece4f281ef42..c6a1e907f63a 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -80,8 +80,9 @@
80#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ 80#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
81#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ 81#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
82#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ 82#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
83#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */ 83#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
84#define CX18_CARD_LAST 6 84#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
85#define CX18_CARD_LAST 7
85 86
86#define CX18_ENC_STREAM_TYPE_MPG 0 87#define CX18_ENC_STREAM_TYPE_MPG 0
87#define CX18_ENC_STREAM_TYPE_TS 1 88#define CX18_ENC_STREAM_TYPE_TS 1
@@ -254,6 +255,7 @@ struct cx18_options {
254#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ 255#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
255#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ 256#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
256#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ 257#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
258#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
257 259
258/* per-cx18, i_flags */ 260/* per-cx18, i_flags */
259#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ 261#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
@@ -285,6 +287,7 @@ struct cx18_queue {
285 struct list_head list; 287 struct list_head list;
286 atomic_t buffers; 288 atomic_t buffers;
287 u32 bytesused; 289 u32 bytesused;
290 spinlock_t lock;
288}; 291};
289 292
290struct cx18_dvb { 293struct cx18_dvb {
@@ -305,7 +308,7 @@ struct cx18_scb; /* forward reference */
305 308
306 309
307#define CX18_MAX_MDL_ACKS 2 310#define CX18_MAX_MDL_ACKS 2
308#define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7) 311#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
309/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */ 312/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
310 313
311#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1 314#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
@@ -313,7 +316,7 @@ struct cx18_scb; /* forward reference */
313#define CX18_F_EWO_MB_STALE \ 316#define CX18_F_EWO_MB_STALE \
314 (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC) 317 (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
315 318
316struct cx18_epu_work_order { 319struct cx18_in_work_order {
317 struct work_struct work; 320 struct work_struct work;
318 atomic_t pending; 321 atomic_t pending;
319 struct cx18 *cx; 322 struct cx18 *cx;
@@ -337,7 +340,6 @@ struct cx18_stream {
337 unsigned mdl_offset; 340 unsigned mdl_offset;
338 341
339 u32 id; 342 u32 id;
340 struct mutex qlock; /* locks access to the queues */
341 unsigned long s_flags; /* status flags, see above */ 343 unsigned long s_flags; /* status flags, see above */
342 int dma; /* can be PCI_DMA_TODEVICE, 344 int dma; /* can be PCI_DMA_TODEVICE,
343 PCI_DMA_FROMDEVICE or 345 PCI_DMA_FROMDEVICE or
@@ -353,6 +355,8 @@ struct cx18_stream {
353 struct cx18_queue q_busy; /* busy buffers - in use by firmware */ 355 struct cx18_queue q_busy; /* busy buffers - in use by firmware */
354 struct cx18_queue q_full; /* full buffers - data for user apps */ 356 struct cx18_queue q_full; /* full buffers - data for user apps */
355 357
358 struct work_struct out_work_order;
359
356 /* DVB / Digital Transport */ 360 /* DVB / Digital Transport */
357 struct cx18_dvb dvb; 361 struct cx18_dvb dvb;
358}; 362};
@@ -568,10 +572,14 @@ struct cx18 {
568 u32 sw2_irq_mask; 572 u32 sw2_irq_mask;
569 u32 hw2_irq_mask; 573 u32 hw2_irq_mask;
570 574
571 struct workqueue_struct *work_queue; 575 struct workqueue_struct *in_work_queue;
572 struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS]; 576 char in_workq_name[11]; /* "cx18-NN-in" */
577 struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
573 char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ 578 char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
574 579
580 struct workqueue_struct *out_work_queue;
581 char out_workq_name[12]; /* "cx18-NN-out" */
582
575 /* i2c */ 583 /* i2c */
576 struct i2c_adapter i2c_adap[2]; 584 struct i2c_adapter i2c_adap[2];
577 struct i2c_algo_bit_data i2c_algo[2]; 585 struct i2c_algo_bit_data i2c_algo[2];
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 3b86f57cd15a..6ea3fe623ef4 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -23,14 +23,20 @@
23#include "cx18-version.h" 23#include "cx18-version.h"
24#include "cx18-dvb.h" 24#include "cx18-dvb.h"
25#include "cx18-io.h" 25#include "cx18-io.h"
26#include "cx18-queue.h"
26#include "cx18-streams.h" 27#include "cx18-streams.h"
27#include "cx18-cards.h" 28#include "cx18-cards.h"
29#include "cx18-gpio.h"
28#include "s5h1409.h" 30#include "s5h1409.h"
29#include "mxl5005s.h" 31#include "mxl5005s.h"
32#include "zl10353.h"
33#include "tuner-xc2028.h"
30 34
31DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 35DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
32 36
33#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 37#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
38#define CX18_CLOCK_ENABLE2 0xc71024
39#define CX18_DMUX_CLK_MASK 0x0080
34 40
35static struct mxl5005s_config hauppauge_hvr1600_tuner = { 41static struct mxl5005s_config hauppauge_hvr1600_tuner = {
36 .i2c_address = 0xC6 >> 1, 42 .i2c_address = 0xC6 >> 1,
@@ -57,7 +63,15 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
57 .inversion = S5H1409_INVERSION_OFF, 63 .inversion = S5H1409_INVERSION_OFF,
58 .status_mode = S5H1409_DEMODLOCKING, 64 .status_mode = S5H1409_DEMODLOCKING,
59 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 65 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
66};
60 67
68/* Information/confirmation of proper config values provided by Terry Wu */
69static struct zl10353_config leadtek_dvr3100h_demod = {
70 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
71 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
72 .parallel_ts = 1, /* Not a serial TS */
73 .no_tuner = 1, /* XC3028 is not behind the gate */
74 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
61}; 75};
62 76
63static int dvb_register(struct cx18_stream *stream); 77static int dvb_register(struct cx18_stream *stream);
@@ -98,6 +112,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
98 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); 112 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
99 break; 113 break;
100 114
115 case CX18_CARD_LEADTEK_DVR3100H:
101 default: 116 default:
102 /* Assumption - Parallel transport - Signalling 117 /* Assumption - Parallel transport - Signalling
103 * undefined or default. 118 * undefined or default.
@@ -267,8 +282,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream)
267} 282}
268 283
269/* All the DVB attach calls go here, this function get's modified 284/* All the DVB attach calls go here, this function get's modified
270 * for each new card. No other function in this file needs 285 * for each new card. cx18_dvb_start_feed() will also need changes.
271 * to change.
272 */ 286 */
273static int dvb_register(struct cx18_stream *stream) 287static int dvb_register(struct cx18_stream *stream)
274{ 288{
@@ -289,6 +303,29 @@ static int dvb_register(struct cx18_stream *stream)
289 ret = 0; 303 ret = 0;
290 } 304 }
291 break; 305 break;
306 case CX18_CARD_LEADTEK_DVR3100H:
307 dvb->fe = dvb_attach(zl10353_attach,
308 &leadtek_dvr3100h_demod,
309 &cx->i2c_adap[1]);
310 if (dvb->fe != NULL) {
311 struct dvb_frontend *fe;
312 struct xc2028_config cfg = {
313 .i2c_adap = &cx->i2c_adap[1],
314 .i2c_addr = 0xc2 >> 1,
315 .ctrl = NULL,
316 };
317 static struct xc2028_ctrl ctrl = {
318 .fname = XC2028_DEFAULT_FIRMWARE,
319 .max_len = 64,
320 .demod = XC3028_FE_ZARLINK456,
321 .type = XC2028_AUTO,
322 };
323
324 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
325 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
326 fe->ops.tuner_ops.set_config(fe, &ctrl);
327 }
328 break;
292 default: 329 default:
293 /* No Digital Tv Support */ 330 /* No Digital Tv Support */
294 break; 331 break;
@@ -299,6 +336,8 @@ static int dvb_register(struct cx18_stream *stream)
299 return -1; 336 return -1;
300 } 337 }
301 338
339 dvb->fe->callback = cx18_reset_tuner_gpio;
340
302 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); 341 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
303 if (ret < 0) { 342 if (ret < 0) {
304 if (dvb->fe->ops.release) 343 if (dvb->fe->ops.release)
@@ -306,5 +345,16 @@ static int dvb_register(struct cx18_stream *stream)
306 return ret; 345 return ret;
307 } 346 }
308 347
348 /*
349 * The firmware seems to enable the TS DMUX clock
350 * under various circumstances. However, since we know we
351 * might use it, let's just turn it on ourselves here.
352 */
353 cx18_write_reg_expect(cx,
354 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK,
355 CX18_CLOCK_ENABLE2,
356 CX18_DMUX_CLK_MASK,
357 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK);
358
309 return ret; 359 return ret;
310} 360}
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index b3889c0b2697..29969c18949c 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -265,8 +265,13 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
265 * an MPEG-2 Program Pack start code, and provide only 265 * an MPEG-2 Program Pack start code, and provide only
266 * up to that point to the user, so it's easy to insert VBI data 266 * up to that point to the user, so it's easy to insert VBI data
267 * the next time around. 267 * the next time around.
268 *
269 * This will not work for an MPEG-2 TS and has only been
270 * verified by analysis to work for an MPEG-2 PS. Helen Buus
271 * pointed out this works for the CX23416 MPEG-2 DVD compatible
272 * stream, and research indicates both the MPEG 2 SVCD and DVD
273 * stream types use an MPEG-2 PS container.
268 */ 274 */
269 /* FIXME - This only works for an MPEG-2 PS, not a TS */
270 /* 275 /*
271 * An MPEG-2 Program Stream (PS) is a series of 276 * An MPEG-2 Program Stream (PS) is a series of
272 * MPEG-2 Program Packs terminated by an 277 * MPEG-2 Program Packs terminated by an
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 2226e5791e99..afe46c3d4057 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,7 +131,7 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
131 * Functions that run in a work_queue work handling context 131 * Functions that run in a work_queue work handling context
132 */ 132 */
133 133
134static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) 134static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
135{ 135{
136 u32 handle, mdl_ack_count, id; 136 u32 handle, mdl_ack_count, id;
137 struct cx18_mailbox *mb; 137 struct cx18_mailbox *mb;
@@ -191,29 +191,30 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
191 if (buf == NULL) { 191 if (buf == NULL) {
192 CX18_WARN("Could not find buf %d for stream %s\n", 192 CX18_WARN("Could not find buf %d for stream %s\n",
193 id, s->name); 193 id, s->name);
194 /* Put as many buffers as possible back into fw use */
195 cx18_stream_load_fw_queue(s);
196 continue; 194 continue;
197 } 195 }
198 196
199 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { 197 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
200 CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", 198 s->name, buf->bytesused);
201 buf->bytesused); 199
202 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 200 if (s->type != CX18_ENC_STREAM_TYPE_TS)
203 buf->bytesused); 201 cx18_enqueue(s, buf, &s->q_full);
202 else {
203 if (s->dvb.enabled)
204 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
205 buf->bytesused);
206 cx18_enqueue(s, buf, &s->q_free);
204 } 207 }
205 /* Put as many buffers as possible back into fw use */
206 cx18_stream_load_fw_queue(s);
207 /* Put back TS buffer, since it was removed from all queues */
208 if (s->type == CX18_ENC_STREAM_TYPE_TS)
209 cx18_stream_put_buf_fw(s, buf);
210 } 208 }
209 /* Put as many buffers as possible back into fw use */
210 cx18_stream_load_fw_queue(s);
211
211 wake_up(&cx->dma_waitq); 212 wake_up(&cx->dma_waitq);
212 if (s->id != -1) 213 if (s->id != -1)
213 wake_up(&s->waitq); 214 wake_up(&s->waitq);
214} 215}
215 216
216static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order) 217static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order)
217{ 218{
218 char *p; 219 char *p;
219 char *str = order->str; 220 char *str = order->str;
@@ -224,7 +225,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order)
224 CX18_INFO("FW version: %s\n", p - 1); 225 CX18_INFO("FW version: %s\n", p - 1);
225} 226}
226 227
227static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order) 228static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order)
228{ 229{
229 switch (order->rpu) { 230 switch (order->rpu) {
230 case CPU: 231 case CPU:
@@ -253,18 +254,18 @@ static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order)
253} 254}
254 255
255static 256static
256void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order) 257void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order)
257{ 258{
258 atomic_set(&order->pending, 0); 259 atomic_set(&order->pending, 0);
259} 260}
260 261
261void cx18_epu_work_handler(struct work_struct *work) 262void cx18_in_work_handler(struct work_struct *work)
262{ 263{
263 struct cx18_epu_work_order *order = 264 struct cx18_in_work_order *order =
264 container_of(work, struct cx18_epu_work_order, work); 265 container_of(work, struct cx18_in_work_order, work);
265 struct cx18 *cx = order->cx; 266 struct cx18 *cx = order->cx;
266 epu_cmd(cx, order); 267 epu_cmd(cx, order);
267 free_epu_work_order(cx, order); 268 free_in_work_order(cx, order);
268} 269}
269 270
270 271
@@ -272,7 +273,7 @@ void cx18_epu_work_handler(struct work_struct *work)
272 * Functions that run in an interrupt handling context 273 * Functions that run in an interrupt handling context
273 */ 274 */
274 275
275static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 276static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order)
276{ 277{
277 struct cx18_mailbox __iomem *ack_mb; 278 struct cx18_mailbox __iomem *ack_mb;
278 u32 ack_irq, req; 279 u32 ack_irq, req;
@@ -308,7 +309,7 @@ static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
308 return; 309 return;
309} 310}
310 311
311static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 312static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order)
312{ 313{
313 u32 handle, mdl_ack_offset, mdl_ack_count; 314 u32 handle, mdl_ack_offset, mdl_ack_count;
314 struct cx18_mailbox *mb; 315 struct cx18_mailbox *mb;
@@ -334,7 +335,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
334} 335}
335 336
336static 337static
337int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 338int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
338{ 339{
339 u32 str_offset; 340 u32 str_offset;
340 char *str = order->str; 341 char *str = order->str;
@@ -355,7 +356,7 @@ int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
355} 356}
356 357
357static inline 358static inline
358int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 359int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
359{ 360{
360 int ret = -1; 361 int ret = -1;
361 362
@@ -387,12 +388,12 @@ int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
387} 388}
388 389
389static inline 390static inline
390struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx) 391struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
391{ 392{
392 int i; 393 int i;
393 struct cx18_epu_work_order *order = NULL; 394 struct cx18_in_work_order *order = NULL;
394 395
395 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { 396 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
396 /* 397 /*
397 * We only need "pending" atomic to inspect its contents, 398 * We only need "pending" atomic to inspect its contents,
398 * and need not do a check and set because: 399 * and need not do a check and set because:
@@ -401,8 +402,8 @@ struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx)
401 * 2. "pending" is only set here, and we're serialized because 402 * 2. "pending" is only set here, and we're serialized because
402 * we're called in an IRQ handler context. 403 * we're called in an IRQ handler context.
403 */ 404 */
404 if (atomic_read(&cx->epu_work_order[i].pending) == 0) { 405 if (atomic_read(&cx->in_work_order[i].pending) == 0) {
405 order = &cx->epu_work_order[i]; 406 order = &cx->in_work_order[i];
406 atomic_set(&order->pending, 1); 407 atomic_set(&order->pending, 1);
407 break; 408 break;
408 } 409 }
@@ -414,7 +415,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
414{ 415{
415 struct cx18_mailbox __iomem *mb; 416 struct cx18_mailbox __iomem *mb;
416 struct cx18_mailbox *order_mb; 417 struct cx18_mailbox *order_mb;
417 struct cx18_epu_work_order *order; 418 struct cx18_in_work_order *order;
418 int submit; 419 int submit;
419 420
420 switch (rpu) { 421 switch (rpu) {
@@ -428,7 +429,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
428 return; 429 return;
429 } 430 }
430 431
431 order = alloc_epu_work_order_irq(cx); 432 order = alloc_in_work_order_irq(cx);
432 if (order == NULL) { 433 if (order == NULL) {
433 CX18_WARN("Unable to find blank work order form to schedule " 434 CX18_WARN("Unable to find blank work order form to schedule "
434 "incoming mailbox command processing\n"); 435 "incoming mailbox command processing\n");
@@ -461,7 +462,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
461 */ 462 */
462 submit = epu_cmd_irq(cx, order); 463 submit = epu_cmd_irq(cx, order);
463 if (submit > 0) { 464 if (submit > 0) {
464 queue_work(cx->work_queue, &order->work); 465 queue_work(cx->in_work_queue, &order->work);
465 } 466 }
466} 467}
467 468
@@ -478,9 +479,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
478 u32 __iomem *xpu_state; 479 u32 __iomem *xpu_state;
479 wait_queue_head_t *waitq; 480 wait_queue_head_t *waitq;
480 struct mutex *mb_lock; 481 struct mutex *mb_lock;
481 long int timeout, ret; 482 unsigned long int t0, timeout, ret;
482 int i; 483 int i;
483 char argstr[MAX_MB_ARGUMENTS*11+1]; 484 char argstr[MAX_MB_ARGUMENTS*11+1];
485 DEFINE_WAIT(w);
484 486
485 if (info == NULL) { 487 if (info == NULL) {
486 CX18_WARN("unknown cmd %x\n", cmd); 488 CX18_WARN("unknown cmd %x\n", cmd);
@@ -562,25 +564,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
562 564
563 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", 565 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
564 irq, info->name); 566 irq, info->name);
567
568 /* So we don't miss the wakeup, prepare to wait before notifying fw */
569 prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
565 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); 570 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
566 571
567 ret = wait_event_timeout( 572 t0 = jiffies;
568 *waitq, 573 ack = cx18_readl(cx, &mb->ack);
569 cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), 574 if (ack != req) {
570 timeout); 575 schedule_timeout(timeout);
576 ret = jiffies - t0;
577 ack = cx18_readl(cx, &mb->ack);
578 } else {
579 ret = jiffies - t0;
580 }
571 581
572 if (ret == 0) { 582 finish_wait(waitq, &w);
573 /* Timed out */ 583
584 if (req != ack) {
574 mutex_unlock(mb_lock); 585 mutex_unlock(mb_lock);
575 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU " 586 if (ret >= timeout) {
576 "acknowledgement\n", 587 /* Timed out */
577 info->name, jiffies_to_msecs(timeout)); 588 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
589 "for RPU acknowledgement\n",
590 info->name, jiffies_to_msecs(ret));
591 } else {
592 CX18_DEBUG_WARN("woken up before mailbox ack was ready "
593 "after submitting %s to RPU. only "
594 "waited %d msecs on req %u but awakened"
595 " with unmatched ack %u\n",
596 info->name,
597 jiffies_to_msecs(ret),
598 req, ack);
599 }
578 return -EINVAL; 600 return -EINVAL;
579 } 601 }
580 602
581 if (ret != timeout) 603 if (ret >= timeout)
604 CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
605 "sending %s; timed out waiting %d msecs\n",
606 info->name, jiffies_to_msecs(ret));
607 else
582 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", 608 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
583 jiffies_to_msecs(timeout-ret), info->name); 609 jiffies_to_msecs(ret), info->name);
584 610
585 /* Collect data returned by the XPU */ 611 /* Collect data returned by the XPU */
586 for (i = 0; i < MAX_MB_ARGUMENTS; i++) 612 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index ce2b6686aa00..e23aaac5b280 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -95,6 +95,6 @@ int cx18_api_func(void *priv, u32 cmd, int in, int out,
95 95
96void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu); 96void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
97 97
98void cx18_epu_work_handler(struct work_struct *work); 98void cx18_in_work_handler(struct work_struct *work);
99 99
100#endif 100#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 3046b8e74345..fa1ed7897d97 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -23,8 +23,8 @@
23 */ 23 */
24 24
25#include "cx18-driver.h" 25#include "cx18-driver.h"
26#include "cx18-streams.h"
27#include "cx18-queue.h" 26#include "cx18-queue.h"
27#include "cx18-streams.h"
28#include "cx18-scb.h" 28#include "cx18-scb.h"
29 29
30void cx18_buf_swap(struct cx18_buffer *buf) 30void cx18_buf_swap(struct cx18_buffer *buf)
@@ -53,13 +53,13 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
53 buf->skipped = 0; 53 buf->skipped = 0;
54 } 54 }
55 55
56 mutex_lock(&s->qlock);
57
58 /* q_busy is restricted to a max buffer count imposed by firmware */ 56 /* q_busy is restricted to a max buffer count imposed by firmware */
59 if (q == &s->q_busy && 57 if (q == &s->q_busy &&
60 atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) 58 atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
61 q = &s->q_free; 59 q = &s->q_free;
62 60
61 spin_lock(&q->lock);
62
63 if (to_front) 63 if (to_front)
64 list_add(&buf->list, &q->list); /* LIFO */ 64 list_add(&buf->list, &q->list); /* LIFO */
65 else 65 else
@@ -67,7 +67,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
67 q->bytesused += buf->bytesused - buf->readpos; 67 q->bytesused += buf->bytesused - buf->readpos;
68 atomic_inc(&q->buffers); 68 atomic_inc(&q->buffers);
69 69
70 mutex_unlock(&s->qlock); 70 spin_unlock(&q->lock);
71 return q; 71 return q;
72} 72}
73 73
@@ -75,7 +75,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
75{ 75{
76 struct cx18_buffer *buf = NULL; 76 struct cx18_buffer *buf = NULL;
77 77
78 mutex_lock(&s->qlock); 78 spin_lock(&q->lock);
79 if (!list_empty(&q->list)) { 79 if (!list_empty(&q->list)) {
80 buf = list_first_entry(&q->list, struct cx18_buffer, list); 80 buf = list_first_entry(&q->list, struct cx18_buffer, list);
81 list_del_init(&buf->list); 81 list_del_init(&buf->list);
@@ -83,7 +83,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
83 buf->skipped = 0; 83 buf->skipped = 0;
84 atomic_dec(&q->buffers); 84 atomic_dec(&q->buffers);
85 } 85 }
86 mutex_unlock(&s->qlock); 86 spin_unlock(&q->lock);
87 return buf; 87 return buf;
88} 88}
89 89
@@ -94,9 +94,23 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
94 struct cx18_buffer *buf; 94 struct cx18_buffer *buf;
95 struct cx18_buffer *tmp; 95 struct cx18_buffer *tmp;
96 struct cx18_buffer *ret = NULL; 96 struct cx18_buffer *ret = NULL;
97 97 LIST_HEAD(sweep_up);
98 mutex_lock(&s->qlock); 98
99 /*
100 * We don't have to acquire multiple q locks here, because we are
101 * serialized by the single threaded work handler.
102 * Buffers from the firmware will thus remain in order as
103 * they are moved from q_busy to q_full or to the dvb ring buffer.
104 */
105 spin_lock(&s->q_busy.lock);
99 list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { 106 list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) {
107 /*
108 * We should find what the firmware told us is done,
109 * right at the front of the queue. If we don't, we likely have
110 * missed a buffer done message from the firmware.
111 * Once we skip a buffer repeatedly, relative to the size of
112 * q_busy, we have high confidence we've missed it.
113 */
100 if (buf->id != id) { 114 if (buf->id != id) {
101 buf->skipped++; 115 buf->skipped++;
102 if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { 116 if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) {
@@ -105,38 +119,41 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
105 "times - it must have dropped out of " 119 "times - it must have dropped out of "
106 "rotation\n", s->name, buf->id, 120 "rotation\n", s->name, buf->id,
107 buf->skipped); 121 buf->skipped);
108 /* move it to q_free */ 122 /* Sweep it up to put it back into rotation */
109 list_move_tail(&buf->list, &s->q_free.list); 123 list_move_tail(&buf->list, &sweep_up);
110 buf->bytesused = buf->readpos = buf->b_flags =
111 buf->skipped = 0;
112 atomic_dec(&s->q_busy.buffers); 124 atomic_dec(&s->q_busy.buffers);
113 atomic_inc(&s->q_free.buffers);
114 } 125 }
115 continue; 126 continue;
116 } 127 }
117 128 /*
118 buf->bytesused = bytesused; 129 * We pull the desired buffer off of the queue here. Something
119 /* Sync the buffer before we release the qlock */ 130 * will have to put it back on a queue later.
120 cx18_buf_sync_for_cpu(s, buf); 131 */
121 if (s->type == CX18_ENC_STREAM_TYPE_TS) { 132 list_del_init(&buf->list);
122 /*
123 * TS doesn't use q_full. As we pull the buffer off of
124 * the queue here, the caller will have to put it back.
125 */
126 list_del_init(&buf->list);
127 } else {
128 /* Move buffer from q_busy to q_full */
129 list_move_tail(&buf->list, &s->q_full.list);
130 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
131 s->q_full.bytesused += buf->bytesused;
132 atomic_inc(&s->q_full.buffers);
133 }
134 atomic_dec(&s->q_busy.buffers); 133 atomic_dec(&s->q_busy.buffers);
135
136 ret = buf; 134 ret = buf;
137 break; 135 break;
138 } 136 }
139 mutex_unlock(&s->qlock); 137 spin_unlock(&s->q_busy.lock);
138
139 /*
140 * We found the buffer for which we were looking. Get it ready for
141 * the caller to put on q_full or in the dvb ring buffer.
142 */
143 if (ret != NULL) {
144 ret->bytesused = bytesused;
145 ret->skipped = 0;
146 /* readpos and b_flags were 0'ed when the buf went on q_busy */
147 cx18_buf_sync_for_cpu(s, ret);
148 if (s->type != CX18_ENC_STREAM_TYPE_TS)
149 set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags);
150 }
151
152 /* Put any buffers the firmware is ignoring back into normal rotation */
153 list_for_each_entry_safe(buf, tmp, &sweep_up, list) {
154 list_del_init(&buf->list);
155 cx18_enqueue(s, buf, &s->q_free);
156 }
140 return ret; 157 return ret;
141} 158}
142 159
@@ -148,7 +165,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
148 if (q == &s->q_free) 165 if (q == &s->q_free)
149 return; 166 return;
150 167
151 mutex_lock(&s->qlock); 168 spin_lock(&q->lock);
152 while (!list_empty(&q->list)) { 169 while (!list_empty(&q->list)) {
153 buf = list_first_entry(&q->list, struct cx18_buffer, list); 170 buf = list_first_entry(&q->list, struct cx18_buffer, list);
154 list_move_tail(&buf->list, &s->q_free.list); 171 list_move_tail(&buf->list, &s->q_free.list);
@@ -156,7 +173,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
156 atomic_inc(&s->q_free.buffers); 173 atomic_inc(&s->q_free.buffers);
157 } 174 }
158 cx18_queue_init(q); 175 cx18_queue_init(q);
159 mutex_unlock(&s->qlock); 176 spin_unlock(&q->lock);
160} 177}
161 178
162void cx18_flush_queues(struct cx18_stream *s) 179void cx18_flush_queues(struct cx18_stream *s)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 0932b76b2373..54d248e16d85 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -116,12 +116,16 @@ static void cx18_stream_init(struct cx18 *cx, int type)
116 s->buffers = cx->stream_buffers[type]; 116 s->buffers = cx->stream_buffers[type];
117 s->buf_size = cx->stream_buf_size[type]; 117 s->buf_size = cx->stream_buf_size[type];
118 118
119 mutex_init(&s->qlock);
120 init_waitqueue_head(&s->waitq); 119 init_waitqueue_head(&s->waitq);
121 s->id = -1; 120 s->id = -1;
121 spin_lock_init(&s->q_free.lock);
122 cx18_queue_init(&s->q_free); 122 cx18_queue_init(&s->q_free);
123 spin_lock_init(&s->q_busy.lock);
123 cx18_queue_init(&s->q_busy); 124 cx18_queue_init(&s->q_busy);
125 spin_lock_init(&s->q_full.lock);
124 cx18_queue_init(&s->q_full); 126 cx18_queue_init(&s->q_full);
127
128 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
125} 129}
126 130
127static int cx18_prep_dev(struct cx18 *cx, int type) 131static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -367,9 +371,14 @@ static void cx18_vbi_setup(struct cx18_stream *s)
367 * Tell the encoder to capture 21-4+1=18 lines per field, 371 * Tell the encoder to capture 21-4+1=18 lines per field,
368 * since we want lines 10 through 21. 372 * since we want lines 10 through 21.
369 * 373 *
370 * FIXME - revisit for 625/50 systems 374 * For 625/50 systems, according to the VIP 2 & BT.656 std:
375 * The EAV RP code's Field bit toggles on line 1, a few lines
376 * after the Vertcal Blank bit has already toggled.
377 * (We've actually set the digitizer so that the Field bit
378 * toggles on line 2.) Tell the encoder to capture 23-2+1=22
379 * lines per field, since we want lines 6 through 23.
371 */ 380 */
372 lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38; 381 lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2;
373 } 382 }
374 383
375 data[0] = s->handle; 384 data[0] = s->handle;
@@ -431,14 +440,16 @@ static void cx18_vbi_setup(struct cx18_stream *s)
431 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 440 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
432} 441}
433 442
434struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, 443static
435 struct cx18_buffer *buf) 444struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
445 struct cx18_buffer *buf)
436{ 446{
437 struct cx18 *cx = s->cx; 447 struct cx18 *cx = s->cx;
438 struct cx18_queue *q; 448 struct cx18_queue *q;
439 449
440 /* Don't give it to the firmware, if we're not running a capture */ 450 /* Don't give it to the firmware, if we're not running a capture */
441 if (s->handle == CX18_INVALID_TASK_HANDLE || 451 if (s->handle == CX18_INVALID_TASK_HANDLE ||
452 test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
442 !test_bit(CX18_F_S_STREAMING, &s->s_flags)) 453 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
443 return cx18_enqueue(s, buf, &s->q_free); 454 return cx18_enqueue(s, buf, &s->q_free);
444 455
@@ -453,7 +464,8 @@ struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
453 return q; 464 return q;
454} 465}
455 466
456void cx18_stream_load_fw_queue(struct cx18_stream *s) 467static
468void _cx18_stream_load_fw_queue(struct cx18_stream *s)
457{ 469{
458 struct cx18_queue *q; 470 struct cx18_queue *q;
459 struct cx18_buffer *buf; 471 struct cx18_buffer *buf;
@@ -467,11 +479,19 @@ void cx18_stream_load_fw_queue(struct cx18_stream *s)
467 buf = cx18_dequeue(s, &s->q_free); 479 buf = cx18_dequeue(s, &s->q_free);
468 if (buf == NULL) 480 if (buf == NULL)
469 break; 481 break;
470 q = cx18_stream_put_buf_fw(s, buf); 482 q = _cx18_stream_put_buf_fw(s, buf);
471 } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM 483 } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM
472 && q == &s->q_busy); 484 && q == &s->q_busy);
473} 485}
474 486
487void cx18_out_work_handler(struct work_struct *work)
488{
489 struct cx18_stream *s =
490 container_of(work, struct cx18_stream, out_work_order);
491
492 _cx18_stream_load_fw_queue(s);
493}
494
475int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 495int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
476{ 496{
477 u32 data[MAX_MB_ARGUMENTS]; 497 u32 data[MAX_MB_ARGUMENTS];
@@ -600,19 +620,20 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
600 620
601 /* Init all the cpu_mdls for this stream */ 621 /* Init all the cpu_mdls for this stream */
602 cx18_flush_queues(s); 622 cx18_flush_queues(s);
603 mutex_lock(&s->qlock); 623 spin_lock(&s->q_free.lock);
604 list_for_each_entry(buf, &s->q_free.list, list) { 624 list_for_each_entry(buf, &s->q_free.list, list) {
605 cx18_writel(cx, buf->dma_handle, 625 cx18_writel(cx, buf->dma_handle,
606 &cx->scb->cpu_mdl[buf->id].paddr); 626 &cx->scb->cpu_mdl[buf->id].paddr);
607 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); 627 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
608 } 628 }
609 mutex_unlock(&s->qlock); 629 spin_unlock(&s->q_free.lock);
610 cx18_stream_load_fw_queue(s); 630 _cx18_stream_load_fw_queue(s);
611 631
612 /* begin_capture */ 632 /* begin_capture */
613 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { 633 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
614 CX18_DEBUG_WARN("Error starting capture!\n"); 634 CX18_DEBUG_WARN("Error starting capture!\n");
615 /* Ensure we're really not capturing before releasing MDLs */ 635 /* Ensure we're really not capturing before releasing MDLs */
636 set_bit(CX18_F_S_STOPPING, &s->s_flags);
616 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 637 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
617 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); 638 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
618 else 639 else
@@ -622,6 +643,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
622 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); 643 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
623 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 644 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
624 s->handle = CX18_INVALID_TASK_HANDLE; 645 s->handle = CX18_INVALID_TASK_HANDLE;
646 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
625 if (atomic_read(&cx->tot_capturing) == 0) { 647 if (atomic_read(&cx->tot_capturing) == 0) {
626 set_bit(CX18_F_I_EOS, &cx->i_flags); 648 set_bit(CX18_F_I_EOS, &cx->i_flags);
627 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); 649 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
@@ -666,6 +688,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
666 if (atomic_read(&cx->tot_capturing) == 0) 688 if (atomic_read(&cx->tot_capturing) == 0)
667 return 0; 689 return 0;
668 690
691 set_bit(CX18_F_S_STOPPING, &s->s_flags);
669 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 692 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
670 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); 693 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
671 else 694 else
@@ -689,6 +712,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
689 712
690 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 713 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
691 s->handle = CX18_INVALID_TASK_HANDLE; 714 s->handle = CX18_INVALID_TASK_HANDLE;
715 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
692 716
693 if (atomic_read(&cx->tot_capturing) > 0) 717 if (atomic_read(&cx->tot_capturing) > 0)
694 return 0; 718 return 0;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 420e0a172945..1afc3fd9d822 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,10 +28,24 @@ int cx18_streams_setup(struct cx18 *cx);
28int cx18_streams_register(struct cx18 *cx); 28int cx18_streams_register(struct cx18 *cx);
29void cx18_streams_cleanup(struct cx18 *cx, int unregister); 29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
30 30
31/* Related to submission of buffers to firmware */
32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
33{
34 struct cx18 *cx = s->cx;
35 queue_work(cx->out_work_queue, &s->out_work_order);
36}
37
38static inline void cx18_stream_put_buf_fw(struct cx18_stream *s,
39 struct cx18_buffer *buf)
40{
41 /* Put buf on q_free; the out work handler will move buf(s) to q_busy */
42 cx18_enqueue(s, buf, &s->q_free);
43 cx18_stream_load_fw_queue(s);
44}
45
46void cx18_out_work_handler(struct work_struct *work);
47
31/* Capture related */ 48/* Capture related */
32void cx18_stream_load_fw_queue(struct cx18_stream *s);
33struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
34 struct cx18_buffer *buf);
35int cx18_start_v4l2_encode_stream(struct cx18_stream *s); 49int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
36int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); 50int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
37 51
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index bd9bd44da791..45494b094e7f 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
24 24
25#define CX18_DRIVER_NAME "cx18" 25#define CX18_DRIVER_NAME "cx18"
26#define CX18_DRIVER_VERSION_MAJOR 1 26#define CX18_DRIVER_VERSION_MAJOR 1
27#define CX18_DRIVER_VERSION_MINOR 1 27#define CX18_DRIVER_VERSION_MINOR 2
28#define CX18_DRIVER_VERSION_PATCHLEVEL 0 28#define CX18_DRIVER_VERSION_PATCHLEVEL 0
29 29
30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) 30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)