2 * cx18 ADEC audio functions
4 * Derived from cx25840-core.c
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "cx18-driver.h"
28 int cx18_av_write(struct cx18
*cx
, u16 addr
, u8 value
)
30 u32 reg
= 0xc40000 + (addr
& ~3);
32 int shift
= (addr
& 3) * 8;
33 u32 x
= cx18_read_reg(cx
, reg
);
35 x
= (x
& ~(mask
<< shift
)) | ((u32
)value
<< shift
);
36 cx18_write_reg(cx
, x
, reg
);
40 int cx18_av_write_expect(struct cx18
*cx
, u16 addr
, u8 value
, u8 eval
, u8 mask
)
42 u32 reg
= 0xc40000 + (addr
& ~3);
43 int shift
= (addr
& 3) * 8;
44 u32 x
= cx18_read_reg(cx
, reg
);
46 x
= (x
& ~((u32
)0xff << shift
)) | ((u32
)value
<< shift
);
47 cx18_write_reg_expect(cx
, x
, reg
,
48 ((u32
)eval
<< shift
), ((u32
)mask
<< shift
));
52 int cx18_av_write4(struct cx18
*cx
, u16 addr
, u32 value
)
54 cx18_write_reg(cx
, value
, 0xc40000 + addr
);
59 cx18_av_write4_expect(struct cx18
*cx
, u16 addr
, u32 value
, u32 eval
, u32 mask
)
61 cx18_write_reg_expect(cx
, value
, 0xc40000 + addr
, eval
, mask
);
65 int cx18_av_write4_noretry(struct cx18
*cx
, u16 addr
, u32 value
)
67 cx18_write_reg_noretry(cx
, value
, 0xc40000 + addr
);
71 u8
cx18_av_read(struct cx18
*cx
, u16 addr
)
73 u32 x
= cx18_read_reg(cx
, 0xc40000 + (addr
& ~3));
74 int shift
= (addr
& 3) * 8;
76 return (x
>> shift
) & 0xff;
79 u32
cx18_av_read4(struct cx18
*cx
, u16 addr
)
81 return cx18_read_reg(cx
, 0xc40000 + addr
);
84 int cx18_av_and_or(struct cx18
*cx
, u16 addr
, unsigned and_mask
,
87 return cx18_av_write(cx
, addr
,
88 (cx18_av_read(cx
, addr
) & and_mask
) |
92 int cx18_av_and_or4(struct cx18
*cx
, u16 addr
, u32 and_mask
,
95 return cx18_av_write4(cx
, addr
,
96 (cx18_av_read4(cx
, addr
) & and_mask
) |
100 /* ----------------------------------------------------------------------- */
102 static int set_input(struct cx18
*cx
, enum cx18_av_video_input vid_input
,
103 enum cx18_av_audio_input aud_input
);
104 static void log_audio_status(struct cx18
*cx
);
105 static void log_video_status(struct cx18
*cx
);
107 /* ----------------------------------------------------------------------- */
109 static void cx18_av_initialize(struct cx18
*cx
)
111 struct cx18_av_state
*state
= &cx
->av_state
;
115 /* Stop 8051 code execution */
116 cx18_av_write4_expect(cx
, CXADEC_DL_CTL
, 0x03000000,
117 0x03000000, 0x13000000);
119 /* initallize the PLL by toggling sleep bit */
120 v
= cx18_av_read4(cx
, CXADEC_HOST_REG1
);
121 /* enable sleep mode - register appears to be read only... */
122 cx18_av_write4_expect(cx
, CXADEC_HOST_REG1
, v
| 1, v
, 0xfffe);
123 /* disable sleep mode */
124 cx18_av_write4_expect(cx
, CXADEC_HOST_REG1
, v
& 0xfffe,
127 /* initialize DLLs */
128 v
= cx18_av_read4(cx
, CXADEC_DLL1_DIAG_CTRL
) & 0xE1FFFEFF;
130 cx18_av_write4(cx
, CXADEC_DLL1_DIAG_CTRL
, v
);
132 cx18_av_write4(cx
, CXADEC_DLL1_DIAG_CTRL
, v
| 0x10000100);
134 v
= cx18_av_read4(cx
, CXADEC_DLL2_DIAG_CTRL
) & 0xE1FFFEFF;
136 cx18_av_write4(cx
, CXADEC_DLL2_DIAG_CTRL
, v
);
138 cx18_av_write4(cx
, CXADEC_DLL2_DIAG_CTRL
, v
| 0x06000100);
140 /* set analog bias currents. Set Vreg to 1.20V. */
141 cx18_av_write4(cx
, CXADEC_AFE_DIAG_CTRL1
, 0x000A1802);
143 v
= cx18_av_read4(cx
, CXADEC_AFE_DIAG_CTRL3
) | 1;
144 /* enable TUNE_FIL_RST */
145 cx18_av_write4_expect(cx
, CXADEC_AFE_DIAG_CTRL3
, v
, v
, 0x03009F0F);
146 /* disable TUNE_FIL_RST */
147 cx18_av_write4_expect(cx
, CXADEC_AFE_DIAG_CTRL3
,
148 v
& 0xFFFFFFFE, v
& 0xFFFFFFFE, 0x03009F0F);
150 /* enable 656 output */
151 cx18_av_and_or4(cx
, CXADEC_PIN_CTRL1
, ~0, 0x040C00);
153 /* video output drive strength */
154 cx18_av_and_or4(cx
, CXADEC_PIN_CTRL2
, ~0, 0x2);
157 cx18_av_write4(cx
, CXADEC_SOFT_RST_CTRL
, 0x8000);
158 cx18_av_write4(cx
, CXADEC_SOFT_RST_CTRL
, 0);
160 /* set video to auto-detect */
161 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
162 /* set the comb notch = 1 */
163 cx18_av_and_or4(cx
, CXADEC_MODE_CTRL
, 0xFFF7E7F0, 0x02040800);
165 /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
166 /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
167 cx18_av_and_or4(cx
, CXADEC_CRUSH_CTRL
, ~0, 0x00500000);
169 /* Set VGA_TRACK_RANGE to 0x20 */
170 cx18_av_and_or4(cx
, CXADEC_DFE_CTRL2
, 0xFFFF00FF, 0x00002000);
172 /* Enable VBI capture */
173 cx18_av_write4(cx
, CXADEC_OUT_CTRL1
, 0x4010253F);
174 /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
176 /* Set the video input.
177 The setting in MODE_CTRL gets lost when we do the above setup */
178 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
179 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
181 v
= cx18_av_read4(cx
, CXADEC_AFE_CTRL
);
182 v
&= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */
183 v
&= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */
184 v
&= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */
185 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */
186 cx18_av_write4(cx
, CXADEC_AFE_CTRL
, v
);
188 /* if(dwEnable && dw3DCombAvailable) { */
189 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
191 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
193 cx18_av_write4(cx
, CXADEC_SRC_COMB_CFG
, 0x6628021F);
194 state
->default_volume
= 228 - cx18_av_read(cx
, 0x8d4);
195 state
->default_volume
= ((state
->default_volume
/ 2) + 23) << 9;
198 /* ----------------------------------------------------------------------- */
200 void cx18_av_std_setup(struct cx18
*cx
)
202 struct cx18_av_state
*state
= &cx
->av_state
;
203 v4l2_std_id std
= state
->std
;
204 int hblank
, hactive
, burst
, vblank
, vactive
, sc
;
205 int vblank656
, src_decimation
;
206 int luma_lpf
, uv_lpf
, comb
;
207 u32 pll_int
, pll_frac
, pll_post
;
209 /* datasheet startup, step 8d */
210 if (std
& ~V4L2_STD_NTSC
)
211 cx18_av_write(cx
, 0x49f, 0x11);
213 cx18_av_write(cx
, 0x49f, 0x14);
215 if (std
& V4L2_STD_625_50
) {
222 src_decimation
= 0x21f;
225 if (std
& V4L2_STD_PAL
) {
229 } else if (std
== V4L2_STD_PAL_Nc
) {
247 src_decimation
= 0x21f;
248 if (std
== V4L2_STD_PAL_60
) {
253 } else if (std
== V4L2_STD_PAL_M
) {
264 /* DEBUG: Displays configured PLL frequency */
265 pll_int
= cx18_av_read(cx
, 0x108);
266 pll_frac
= cx18_av_read4(cx
, 0x10c) & 0x1ffffff;
267 pll_post
= cx18_av_read(cx
, 0x109);
268 CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
269 pll_int
, pll_frac
, pll_post
);
274 pll
= (28636360L * ((((u64
)pll_int
) << 25) + pll_frac
)) >> 25;
276 CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
277 pll
/ 1000000, pll
% 1000000);
278 CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
279 pll
/ 8000000, (pll
/ 8) % 1000000);
281 fin
= ((u64
)src_decimation
* pll
) >> 12;
282 CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
283 fin
/ 1000000, fin
% 1000000);
285 fsc
= (((u64
)sc
) * pll
) >> 24L;
286 CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
287 fsc
/ 1000000, fsc
% 1000000);
289 CX18_DEBUG_INFO("hblank %i, hactive %i, "
290 "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
291 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
293 hblank
, hactive
, vblank
, vactive
, vblank656
,
294 src_decimation
, burst
, luma_lpf
, uv_lpf
, comb
, sc
);
297 /* Sets horizontal blanking delay and active lines */
298 cx18_av_write(cx
, 0x470, hblank
);
299 cx18_av_write(cx
, 0x471, 0xff & (((hblank
>> 8) & 0x3) |
301 cx18_av_write(cx
, 0x472, hactive
>> 4);
303 /* Sets burst gate delay */
304 cx18_av_write(cx
, 0x473, burst
);
306 /* Sets vertical blanking delay and active duration */
307 cx18_av_write(cx
, 0x474, vblank
);
308 cx18_av_write(cx
, 0x475, 0xff & (((vblank
>> 8) & 0x3) |
310 cx18_av_write(cx
, 0x476, vactive
>> 4);
311 cx18_av_write(cx
, 0x477, vblank656
);
313 /* Sets src decimation rate */
314 cx18_av_write(cx
, 0x478, 0xff & src_decimation
);
315 cx18_av_write(cx
, 0x479, 0xff & (src_decimation
>> 8));
317 /* Sets Luma and UV Low pass filters */
318 cx18_av_write(cx
, 0x47a, luma_lpf
<< 6 | ((uv_lpf
<< 4) & 0x30));
320 /* Enables comb filters */
321 cx18_av_write(cx
, 0x47b, comb
);
324 cx18_av_write(cx
, 0x47c, sc
);
325 cx18_av_write(cx
, 0x47d, 0xff & sc
>> 8);
326 cx18_av_write(cx
, 0x47e, 0xff & sc
>> 16);
328 /* Sets VBI parameters */
329 if (std
& V4L2_STD_625_50
) {
330 cx18_av_write(cx
, 0x47f, 0x01);
331 state
->vbi_line_offset
= 5;
333 cx18_av_write(cx
, 0x47f, 0x00);
334 state
->vbi_line_offset
= 8;
338 /* ----------------------------------------------------------------------- */
340 static void input_change(struct cx18
*cx
)
342 struct cx18_av_state
*state
= &cx
->av_state
;
343 v4l2_std_id std
= state
->std
;
346 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
347 cx18_av_write(cx
, 0x49f, (std
& V4L2_STD_NTSC
) ? 0x14 : 0x11);
348 cx18_av_and_or(cx
, 0x401, ~0x60, 0);
349 cx18_av_and_or(cx
, 0x401, ~0x60, 0x60);
351 if (std
& V4L2_STD_525_60
) {
352 if (std
== V4L2_STD_NTSC_M_JP
) {
353 /* Japan uses EIAJ audio standard */
354 cx18_av_write_expect(cx
, 0x808, 0xf7, 0xf7, 0xff);
355 cx18_av_write_expect(cx
, 0x80b, 0x02, 0x02, 0x3f);
356 } else if (std
== V4L2_STD_NTSC_M_KR
) {
357 /* South Korea uses A2 audio standard */
358 cx18_av_write_expect(cx
, 0x808, 0xf8, 0xf8, 0xff);
359 cx18_av_write_expect(cx
, 0x80b, 0x03, 0x03, 0x3f);
361 /* Others use the BTSC audio standard */
362 cx18_av_write_expect(cx
, 0x808, 0xf6, 0xf6, 0xff);
363 cx18_av_write_expect(cx
, 0x80b, 0x01, 0x01, 0x3f);
365 } else if (std
& V4L2_STD_PAL
) {
366 /* Follow tuner change procedure for PAL */
367 cx18_av_write_expect(cx
, 0x808, 0xff, 0xff, 0xff);
368 cx18_av_write_expect(cx
, 0x80b, 0x03, 0x03, 0x3f);
369 } else if (std
& V4L2_STD_SECAM
) {
370 /* Select autodetect for SECAM */
371 cx18_av_write_expect(cx
, 0x808, 0xff, 0xff, 0xff);
372 cx18_av_write_expect(cx
, 0x80b, 0x03, 0x03, 0x3f);
375 v
= cx18_av_read(cx
, 0x803);
377 /* restart audio decoder microcontroller */
379 cx18_av_write_expect(cx
, 0x803, v
, v
, 0x1f);
381 cx18_av_write_expect(cx
, 0x803, v
, v
, 0x1f);
385 static int set_input(struct cx18
*cx
, enum cx18_av_video_input vid_input
,
386 enum cx18_av_audio_input aud_input
)
388 struct cx18_av_state
*state
= &cx
->av_state
;
389 u8 is_composite
= (vid_input
>= CX18_AV_COMPOSITE1
&&
390 vid_input
<= CX18_AV_COMPOSITE8
);
394 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
395 vid_input
, aud_input
);
398 reg
= 0xf0 + (vid_input
- CX18_AV_COMPOSITE1
);
400 int luma
= vid_input
& 0xf0;
401 int chroma
= vid_input
& 0xf00;
403 if ((vid_input
& ~0xff0) ||
404 luma
< CX18_AV_SVIDEO_LUMA1
||
405 luma
> CX18_AV_SVIDEO_LUMA8
||
406 chroma
< CX18_AV_SVIDEO_CHROMA4
||
407 chroma
> CX18_AV_SVIDEO_CHROMA8
) {
408 CX18_ERR("0x%04x is not a valid video input!\n",
412 reg
= 0xf0 + ((luma
- CX18_AV_SVIDEO_LUMA1
) >> 4);
413 if (chroma
>= CX18_AV_SVIDEO_CHROMA7
) {
415 reg
|= (chroma
- CX18_AV_SVIDEO_CHROMA7
) >> 2;
418 reg
|= (chroma
- CX18_AV_SVIDEO_CHROMA4
) >> 4;
423 case CX18_AV_AUDIO_SERIAL1
:
424 case CX18_AV_AUDIO_SERIAL2
:
425 /* do nothing, use serial audio input */
427 case CX18_AV_AUDIO4
: reg
&= ~0x30; break;
428 case CX18_AV_AUDIO5
: reg
&= ~0x30; reg
|= 0x10; break;
429 case CX18_AV_AUDIO6
: reg
&= ~0x30; reg
|= 0x20; break;
430 case CX18_AV_AUDIO7
: reg
&= ~0xc0; break;
431 case CX18_AV_AUDIO8
: reg
&= ~0xc0; reg
|= 0x40; break;
434 CX18_ERR("0x%04x is not a valid audio input!\n", aud_input
);
438 cx18_av_write_expect(cx
, 0x103, reg
, reg
, 0xf7);
439 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
440 cx18_av_and_or(cx
, 0x401, ~0x6, is_composite
? 0 : 0x02);
442 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
443 v
= cx18_av_read(cx
, 0x102);
448 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
449 if ((reg
& 0xc0) != 0xc0 && (reg
& 0x30) != 0x30)
453 cx18_av_write_expect(cx
, 0x102, v
, v
, 0x17);
455 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
457 state
->vid_input
= vid_input
;
458 state
->aud_input
= aud_input
;
459 cx18_av_audio_set_path(cx
);
464 /* ----------------------------------------------------------------------- */
466 static int set_v4lstd(struct cx18
*cx
)
468 struct cx18_av_state
*state
= &cx
->av_state
;
469 u8 fmt
= 0; /* zero is autodetect */
472 /* First tests should be against specific std */
473 if (state
->std
== V4L2_STD_NTSC_M_JP
) {
475 } else if (state
->std
== V4L2_STD_NTSC_443
) {
477 } else if (state
->std
== V4L2_STD_PAL_M
) {
480 } else if (state
->std
== V4L2_STD_PAL_N
) {
482 } else if (state
->std
== V4L2_STD_PAL_Nc
) {
484 } else if (state
->std
== V4L2_STD_PAL_60
) {
487 /* Then, test against generic ones */
488 if (state
->std
& V4L2_STD_NTSC
)
490 else if (state
->std
& V4L2_STD_PAL
)
492 else if (state
->std
& V4L2_STD_SECAM
)
496 CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt
);
498 /* Follow step 9 of section 3.16 in the cx18_av datasheet.
499 Without this PAL may display a vertical ghosting effect.
500 This happens for example with the Yuan MPC622. */
501 if (fmt
>= 4 && fmt
< 8) {
502 /* Set format to NTSC-M */
503 cx18_av_and_or(cx
, 0x400, ~0xf, 1);
505 cx18_av_and_or(cx
, 0x47b, ~6, 0);
507 cx18_av_and_or(cx
, 0x400, ~0x2f, fmt
| 0x20);
508 cx18_av_and_or(cx
, 0x403, ~0x3, pal_m
);
509 cx18_av_std_setup(cx
);
514 /* ----------------------------------------------------------------------- */
516 static int set_v4lctrl(struct cx18
*cx
, struct v4l2_control
*ctrl
)
519 case V4L2_CID_BRIGHTNESS
:
520 if (ctrl
->value
< 0 || ctrl
->value
> 255) {
521 CX18_ERR("invalid brightness setting %d\n",
526 cx18_av_write(cx
, 0x414, ctrl
->value
- 128);
529 case V4L2_CID_CONTRAST
:
530 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
531 CX18_ERR("invalid contrast setting %d\n",
536 cx18_av_write(cx
, 0x415, ctrl
->value
<< 1);
539 case V4L2_CID_SATURATION
:
540 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
541 CX18_ERR("invalid saturation setting %d\n",
546 cx18_av_write(cx
, 0x420, ctrl
->value
<< 1);
547 cx18_av_write(cx
, 0x421, ctrl
->value
<< 1);
551 if (ctrl
->value
< -127 || ctrl
->value
> 127) {
552 CX18_ERR("invalid hue setting %d\n", ctrl
->value
);
556 cx18_av_write(cx
, 0x422, ctrl
->value
);
559 case V4L2_CID_AUDIO_VOLUME
:
560 case V4L2_CID_AUDIO_BASS
:
561 case V4L2_CID_AUDIO_TREBLE
:
562 case V4L2_CID_AUDIO_BALANCE
:
563 case V4L2_CID_AUDIO_MUTE
:
564 return cx18_av_audio(cx
, VIDIOC_S_CTRL
, ctrl
);
573 static int get_v4lctrl(struct cx18
*cx
, struct v4l2_control
*ctrl
)
576 case V4L2_CID_BRIGHTNESS
:
577 ctrl
->value
= (s8
)cx18_av_read(cx
, 0x414) + 128;
579 case V4L2_CID_CONTRAST
:
580 ctrl
->value
= cx18_av_read(cx
, 0x415) >> 1;
582 case V4L2_CID_SATURATION
:
583 ctrl
->value
= cx18_av_read(cx
, 0x420) >> 1;
586 ctrl
->value
= (s8
)cx18_av_read(cx
, 0x422);
588 case V4L2_CID_AUDIO_VOLUME
:
589 case V4L2_CID_AUDIO_BASS
:
590 case V4L2_CID_AUDIO_TREBLE
:
591 case V4L2_CID_AUDIO_BALANCE
:
592 case V4L2_CID_AUDIO_MUTE
:
593 return cx18_av_audio(cx
, VIDIOC_G_CTRL
, ctrl
);
601 /* ----------------------------------------------------------------------- */
603 static int get_v4lfmt(struct cx18
*cx
, struct v4l2_format
*fmt
)
606 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
:
607 return cx18_av_vbi(cx
, VIDIOC_G_FMT
, fmt
);
615 static int set_v4lfmt(struct cx18
*cx
, struct v4l2_format
*fmt
)
617 struct cx18_av_state
*state
= &cx
->av_state
;
618 struct v4l2_pix_format
*pix
;
619 int HSC
, VSC
, Vsrc
, Hsrc
, filter
, Vlines
;
620 int is_50Hz
= !(state
->std
& V4L2_STD_525_60
);
623 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
624 pix
= &(fmt
->fmt
.pix
);
626 Vsrc
= (cx18_av_read(cx
, 0x476) & 0x3f) << 4;
627 Vsrc
|= (cx18_av_read(cx
, 0x475) & 0xf0) >> 4;
629 Hsrc
= (cx18_av_read(cx
, 0x472) & 0x3f) << 4;
630 Hsrc
|= (cx18_av_read(cx
, 0x471) & 0xf0) >> 4;
632 Vlines
= pix
->height
+ (is_50Hz
? 4 : 7);
634 if ((pix
->width
* 16 < Hsrc
) || (Hsrc
< pix
->width
) ||
635 (Vlines
* 8 < Vsrc
) || (Vsrc
< Vlines
)) {
636 CX18_ERR("%dx%d is not a valid size!\n",
637 pix
->width
, pix
->height
);
641 HSC
= (Hsrc
* (1 << 20)) / pix
->width
- (1 << 20);
642 VSC
= (1 << 16) - (Vsrc
* (1 << 9) / Vlines
- (1 << 9));
645 if (pix
->width
>= 385)
647 else if (pix
->width
> 192)
649 else if (pix
->width
> 96)
654 CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n",
655 pix
->width
, pix
->height
, HSC
, VSC
);
658 cx18_av_write(cx
, 0x418, HSC
& 0xff);
659 cx18_av_write(cx
, 0x419, (HSC
>> 8) & 0xff);
660 cx18_av_write(cx
, 0x41a, HSC
>> 16);
662 cx18_av_write(cx
, 0x41c, VSC
& 0xff);
663 cx18_av_write(cx
, 0x41d, VSC
>> 8);
664 /* VS_INTRLACE=1 VFILT=filter */
665 cx18_av_write(cx
, 0x41e, 0x8 | filter
);
668 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
:
669 return cx18_av_vbi(cx
, VIDIOC_S_FMT
, fmt
);
671 case V4L2_BUF_TYPE_VBI_CAPTURE
:
672 return cx18_av_vbi(cx
, VIDIOC_S_FMT
, fmt
);
681 /* ----------------------------------------------------------------------- */
683 int cx18_av_cmd(struct cx18
*cx
, unsigned int cmd
, void *arg
)
685 struct cx18_av_state
*state
= &cx
->av_state
;
686 struct v4l2_tuner
*vt
= arg
;
687 struct v4l2_routing
*route
= arg
;
689 /* ignore these commands */
691 case TUNER_SET_TYPE_ADDR
:
695 if (!state
->is_initialized
) {
696 CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd
);
697 /* initialize on first use */
698 state
->is_initialized
= 1;
699 cx18_av_initialize(cx
);
703 case VIDIOC_INT_DECODE_VBI_LINE
:
704 return cx18_av_vbi(cx
, cmd
, arg
);
706 case VIDIOC_INT_AUDIO_CLOCK_FREQ
:
707 return cx18_av_audio(cx
, cmd
, arg
);
709 case VIDIOC_STREAMON
:
710 CX18_DEBUG_INFO("enable output\n");
711 cx18_av_write(cx
, 0x115, 0x8c);
712 cx18_av_write(cx
, 0x116, 0x07);
715 case VIDIOC_STREAMOFF
:
716 CX18_DEBUG_INFO("disable output\n");
717 cx18_av_write(cx
, 0x115, 0x00);
718 cx18_av_write(cx
, 0x116, 0x00);
721 case VIDIOC_LOG_STATUS
:
722 log_video_status(cx
);
723 log_audio_status(cx
);
727 return get_v4lctrl(cx
, (struct v4l2_control
*)arg
);
730 return set_v4lctrl(cx
, (struct v4l2_control
*)arg
);
732 case VIDIOC_QUERYCTRL
:
734 struct v4l2_queryctrl
*qc
= arg
;
737 case V4L2_CID_BRIGHTNESS
:
738 case V4L2_CID_CONTRAST
:
739 case V4L2_CID_SATURATION
:
741 return v4l2_ctrl_query_fill_std(qc
);
747 case V4L2_CID_AUDIO_VOLUME
:
748 return v4l2_ctrl_query_fill(qc
, 0, 65535,
749 65535 / 100, state
->default_volume
);
750 case V4L2_CID_AUDIO_MUTE
:
751 case V4L2_CID_AUDIO_BALANCE
:
752 case V4L2_CID_AUDIO_BASS
:
753 case V4L2_CID_AUDIO_TREBLE
:
754 return v4l2_ctrl_query_fill_std(qc
);
762 *(v4l2_std_id
*)arg
= state
->std
;
766 if (state
->radio
== 0 && state
->std
== *(v4l2_std_id
*)arg
)
769 state
->std
= *(v4l2_std_id
*)arg
;
770 return set_v4lstd(cx
);
776 case VIDIOC_INT_G_VIDEO_ROUTING
:
777 route
->input
= state
->vid_input
;
781 case VIDIOC_INT_S_VIDEO_ROUTING
:
782 return set_input(cx
, route
->input
, state
->aud_input
);
784 case VIDIOC_INT_G_AUDIO_ROUTING
:
785 route
->input
= state
->aud_input
;
789 case VIDIOC_INT_S_AUDIO_ROUTING
:
790 return set_input(cx
, state
->vid_input
, route
->input
);
792 case VIDIOC_S_FREQUENCY
:
798 u8 vpres
= cx18_av_read(cx
, 0x40e) & 0x20;
805 vt
->signal
= vpres
? 0xffff : 0x0;
808 V4L2_TUNER_CAP_STEREO
| V4L2_TUNER_CAP_LANG1
|
809 V4L2_TUNER_CAP_LANG2
| V4L2_TUNER_CAP_SAP
;
811 mode
= cx18_av_read(cx
, 0x804);
813 /* get rxsubchans and audmode */
814 if ((mode
& 0xf) == 1)
815 val
|= V4L2_TUNER_SUB_STEREO
;
817 val
|= V4L2_TUNER_SUB_MONO
;
819 if (mode
== 2 || mode
== 4)
820 val
= V4L2_TUNER_SUB_LANG1
| V4L2_TUNER_SUB_LANG2
;
823 val
|= V4L2_TUNER_SUB_SAP
;
825 vt
->rxsubchans
= val
;
826 vt
->audmode
= state
->audmode
;
837 v
= cx18_av_read(cx
, 0x809);
840 switch (vt
->audmode
) {
841 case V4L2_TUNER_MODE_MONO
:
844 bilingual -> lang1 */
846 case V4L2_TUNER_MODE_STEREO
:
847 case V4L2_TUNER_MODE_LANG1
:
850 bilingual -> lang1 */
853 case V4L2_TUNER_MODE_LANG1_LANG2
:
856 bilingual -> lang1/lang2 */
859 case V4L2_TUNER_MODE_LANG2
:
862 bilingual -> lang2 */
868 cx18_av_write_expect(cx
, 0x809, v
, v
, 0xff);
869 state
->audmode
= vt
->audmode
;
874 return get_v4lfmt(cx
, (struct v4l2_format
*)arg
);
877 return set_v4lfmt(cx
, (struct v4l2_format
*)arg
);
879 case VIDIOC_INT_RESET
:
880 cx18_av_initialize(cx
);
890 /* ----------------------------------------------------------------------- */
892 /* ----------------------------------------------------------------------- */
894 static void log_video_status(struct cx18
*cx
)
896 static const char *const fmt_strs
[] = {
898 "NTSC-M", "NTSC-J", "NTSC-4.43",
899 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
905 struct cx18_av_state
*state
= &cx
->av_state
;
906 u8 vidfmt_sel
= cx18_av_read(cx
, 0x400) & 0xf;
907 u8 gen_stat1
= cx18_av_read(cx
, 0x40d);
908 u8 gen_stat2
= cx18_av_read(cx
, 0x40e);
909 int vid_input
= state
->vid_input
;
911 CX18_INFO("Video signal: %spresent\n",
912 (gen_stat2
& 0x20) ? "" : "not ");
913 CX18_INFO("Detected format: %s\n",
914 fmt_strs
[gen_stat1
& 0xf]);
916 CX18_INFO("Specified standard: %s\n",
917 vidfmt_sel
? fmt_strs
[vidfmt_sel
] : "automatic detection");
919 if (vid_input
>= CX18_AV_COMPOSITE1
&&
920 vid_input
<= CX18_AV_COMPOSITE8
) {
921 CX18_INFO("Specified video input: Composite %d\n",
922 vid_input
- CX18_AV_COMPOSITE1
+ 1);
924 CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
925 (vid_input
& 0xf0) >> 4, (vid_input
& 0xf00) >> 8);
928 CX18_INFO("Specified audioclock freq: %d Hz\n", state
->audclk_freq
);
931 /* ----------------------------------------------------------------------- */
933 static void log_audio_status(struct cx18
*cx
)
935 struct cx18_av_state
*state
= &cx
->av_state
;
936 u8 download_ctl
= cx18_av_read(cx
, 0x803);
937 u8 mod_det_stat0
= cx18_av_read(cx
, 0x804);
938 u8 mod_det_stat1
= cx18_av_read(cx
, 0x805);
939 u8 audio_config
= cx18_av_read(cx
, 0x808);
940 u8 pref_mode
= cx18_av_read(cx
, 0x809);
941 u8 afc0
= cx18_av_read(cx
, 0x80b);
942 u8 mute_ctl
= cx18_av_read(cx
, 0x8d3);
943 int aud_input
= state
->aud_input
;
946 switch (mod_det_stat0
) {
947 case 0x00: p
= "mono"; break;
948 case 0x01: p
= "stereo"; break;
949 case 0x02: p
= "dual"; break;
950 case 0x04: p
= "tri"; break;
951 case 0x10: p
= "mono with SAP"; break;
952 case 0x11: p
= "stereo with SAP"; break;
953 case 0x12: p
= "dual with SAP"; break;
954 case 0x14: p
= "tri with SAP"; break;
955 case 0xfe: p
= "forced mode"; break;
956 default: p
= "not defined"; break;
958 CX18_INFO("Detected audio mode: %s\n", p
);
960 switch (mod_det_stat1
) {
961 case 0x00: p
= "not defined"; break;
962 case 0x01: p
= "EIAJ"; break;
963 case 0x02: p
= "A2-M"; break;
964 case 0x03: p
= "A2-BG"; break;
965 case 0x04: p
= "A2-DK1"; break;
966 case 0x05: p
= "A2-DK2"; break;
967 case 0x06: p
= "A2-DK3"; break;
968 case 0x07: p
= "A1 (6.0 MHz FM Mono)"; break;
969 case 0x08: p
= "AM-L"; break;
970 case 0x09: p
= "NICAM-BG"; break;
971 case 0x0a: p
= "NICAM-DK"; break;
972 case 0x0b: p
= "NICAM-I"; break;
973 case 0x0c: p
= "NICAM-L"; break;
974 case 0x0d: p
= "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
975 case 0x0e: p
= "IF FM Radio"; break;
976 case 0x0f: p
= "BTSC"; break;
977 case 0x10: p
= "detected chrominance"; break;
978 case 0xfd: p
= "unknown audio standard"; break;
979 case 0xfe: p
= "forced audio standard"; break;
980 case 0xff: p
= "no detected audio standard"; break;
981 default: p
= "not defined"; break;
983 CX18_INFO("Detected audio standard: %s\n", p
);
984 CX18_INFO("Audio muted: %s\n",
985 (mute_ctl
& 0x2) ? "yes" : "no");
986 CX18_INFO("Audio microcontroller: %s\n",
987 (download_ctl
& 0x10) ? "running" : "stopped");
989 switch (audio_config
>> 4) {
990 case 0x00: p
= "undefined"; break;
991 case 0x01: p
= "BTSC"; break;
992 case 0x02: p
= "EIAJ"; break;
993 case 0x03: p
= "A2-M"; break;
994 case 0x04: p
= "A2-BG"; break;
995 case 0x05: p
= "A2-DK1"; break;
996 case 0x06: p
= "A2-DK2"; break;
997 case 0x07: p
= "A2-DK3"; break;
998 case 0x08: p
= "A1 (6.0 MHz FM Mono)"; break;
999 case 0x09: p
= "AM-L"; break;
1000 case 0x0a: p
= "NICAM-BG"; break;
1001 case 0x0b: p
= "NICAM-DK"; break;
1002 case 0x0c: p
= "NICAM-I"; break;
1003 case 0x0d: p
= "NICAM-L"; break;
1004 case 0x0e: p
= "FM radio"; break;
1005 case 0x0f: p
= "automatic detection"; break;
1006 default: p
= "undefined"; break;
1008 CX18_INFO("Configured audio standard: %s\n", p
);
1010 if ((audio_config
>> 4) < 0xF) {
1011 switch (audio_config
& 0xF) {
1012 case 0x00: p
= "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
1013 case 0x01: p
= "MONO2 (LANGUAGE B)"; break;
1014 case 0x02: p
= "MONO3 (STEREO forced MONO)"; break;
1015 case 0x03: p
= "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
1016 case 0x04: p
= "STEREO"; break;
1017 case 0x05: p
= "DUAL1 (AC)"; break;
1018 case 0x06: p
= "DUAL2 (BC)"; break;
1019 case 0x07: p
= "DUAL3 (AB)"; break;
1020 default: p
= "undefined";
1022 CX18_INFO("Configured audio mode: %s\n", p
);
1024 switch (audio_config
& 0xF) {
1025 case 0x00: p
= "BG"; break;
1026 case 0x01: p
= "DK1"; break;
1027 case 0x02: p
= "DK2"; break;
1028 case 0x03: p
= "DK3"; break;
1029 case 0x04: p
= "I"; break;
1030 case 0x05: p
= "L"; break;
1031 case 0x06: p
= "BTSC"; break;
1032 case 0x07: p
= "EIAJ"; break;
1033 case 0x08: p
= "A2-M"; break;
1034 case 0x09: p
= "FM Radio (4.5 MHz)"; break;
1035 case 0x0a: p
= "FM Radio (5.5 MHz)"; break;
1036 case 0x0b: p
= "S-Video"; break;
1037 case 0x0f: p
= "automatic standard and mode detection"; break;
1038 default: p
= "undefined"; break;
1040 CX18_INFO("Configured audio system: %s\n", p
);
1044 CX18_INFO("Specified audio input: Tuner (In%d)\n",
1047 CX18_INFO("Specified audio input: External\n");
1049 switch (pref_mode
& 0xf) {
1050 case 0: p
= "mono/language A"; break;
1051 case 1: p
= "language B"; break;
1052 case 2: p
= "language C"; break;
1053 case 3: p
= "analog fallback"; break;
1054 case 4: p
= "stereo"; break;
1055 case 5: p
= "language AC"; break;
1056 case 6: p
= "language BC"; break;
1057 case 7: p
= "language AB"; break;
1058 default: p
= "undefined"; break;
1060 CX18_INFO("Preferred audio mode: %s\n", p
);
1062 if ((audio_config
& 0xf) == 0xf) {
1063 switch ((afc0
>> 3) & 0x1) {
1064 case 0: p
= "system DK"; break;
1065 case 1: p
= "system L"; break;
1067 CX18_INFO("Selected 65 MHz format: %s\n", p
);
1069 switch (afc0
& 0x7) {
1070 case 0: p
= "Chroma"; break;
1071 case 1: p
= "BTSC"; break;
1072 case 2: p
= "EIAJ"; break;
1073 case 3: p
= "A2-M"; break;
1074 case 4: p
= "autodetect"; break;
1075 default: p
= "undefined"; break;
1077 CX18_INFO("Selected 45 MHz format: %s\n", p
);