2 * cx18 ADEC audio functions
4 * Derived from cx25840-core.c
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "cx18-driver.h"
26 int cx18_av_write(struct cx18
*cx
, u16 addr
, u8 value
)
28 u32 x
= readl(cx
->reg_mem
+ 0xc40000 + (addr
& ~3));
30 int shift
= (addr
& 3) * 8;
32 x
= (x
& ~(mask
<< shift
)) | ((u32
)value
<< shift
);
33 writel(x
, cx
->reg_mem
+ 0xc40000 + (addr
& ~3));
37 int cx18_av_write4(struct cx18
*cx
, u16 addr
, u32 value
)
39 writel(value
, cx
->reg_mem
+ 0xc40000 + addr
);
43 u8
cx18_av_read(struct cx18
*cx
, u16 addr
)
45 u32 x
= readl(cx
->reg_mem
+ 0xc40000 + (addr
& ~3));
46 int shift
= (addr
& 3) * 8;
48 return (x
>> shift
) & 0xff;
51 u32
cx18_av_read4(struct cx18
*cx
, u16 addr
)
53 return readl(cx
->reg_mem
+ 0xc40000 + addr
);
56 int cx18_av_and_or(struct cx18
*cx
, u16 addr
, unsigned and_mask
,
59 return cx18_av_write(cx
, addr
,
60 (cx18_av_read(cx
, addr
) & and_mask
) |
64 int cx18_av_and_or4(struct cx18
*cx
, u16 addr
, u32 and_mask
,
67 return cx18_av_write4(cx
, addr
,
68 (cx18_av_read4(cx
, addr
) & and_mask
) |
72 /* ----------------------------------------------------------------------- */
74 static int set_input(struct cx18
*cx
, enum cx18_av_video_input vid_input
,
75 enum cx18_av_audio_input aud_input
);
76 static void log_audio_status(struct cx18
*cx
);
77 static void log_video_status(struct cx18
*cx
);
79 /* ----------------------------------------------------------------------- */
81 static void cx18_av_initialize(struct cx18
*cx
)
86 /* Stop 8051 code execution */
87 cx18_av_write4(cx
, CXADEC_DL_CTL
, 0x03000000);
89 /* initallize the PLL by toggling sleep bit */
90 v
= cx18_av_read4(cx
, CXADEC_HOST_REG1
);
91 /* enable sleep mode */
92 cx18_av_write4(cx
, CXADEC_HOST_REG1
, v
| 1);
93 /* disable sleep mode */
94 cx18_av_write4(cx
, CXADEC_HOST_REG1
, v
& 0xfffe);
97 v
= cx18_av_read4(cx
, CXADEC_DLL1_DIAG_CTRL
) & 0xE1FFFEFF;
99 cx18_av_write4(cx
, CXADEC_DLL1_DIAG_CTRL
, v
);
101 cx18_av_write4(cx
, CXADEC_DLL1_DIAG_CTRL
, v
| 0x10000100);
103 v
= cx18_av_read4(cx
, CXADEC_DLL2_DIAG_CTRL
) & 0xE1FFFEFF;
105 cx18_av_write4(cx
, CXADEC_DLL2_DIAG_CTRL
, v
);
107 cx18_av_write4(cx
, CXADEC_DLL2_DIAG_CTRL
, v
| 0x06000100);
109 /* set analog bias currents. Set Vreg to 1.20V. */
110 cx18_av_write4(cx
, CXADEC_AFE_DIAG_CTRL1
, 0x000A1802);
112 v
= cx18_av_read4(cx
, CXADEC_AFE_DIAG_CTRL3
) | 1;
113 /* enable TUNE_FIL_RST */
114 cx18_av_write4(cx
, CXADEC_AFE_DIAG_CTRL3
, v
);
115 /* disable TUNE_FIL_RST */
116 cx18_av_write4(cx
, CXADEC_AFE_DIAG_CTRL3
, v
& 0xFFFFFFFE);
118 /* enable 656 output */
119 cx18_av_and_or4(cx
, CXADEC_PIN_CTRL1
, ~0, 0x040C00);
121 /* video output drive strength */
122 cx18_av_and_or4(cx
, CXADEC_PIN_CTRL2
, ~0, 0x2);
125 cx18_av_write4(cx
, CXADEC_SOFT_RST_CTRL
, 0x8000);
126 cx18_av_write4(cx
, CXADEC_SOFT_RST_CTRL
, 0);
128 /* set video to auto-detect */
129 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
130 /* set the comb notch = 1 */
131 cx18_av_and_or4(cx
, CXADEC_MODE_CTRL
, 0xFFF7E7F0, 0x02040800);
133 /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
134 /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
135 cx18_av_and_or4(cx
, CXADEC_CRUSH_CTRL
, ~0, 0x00500000);
137 /* Set VGA_TRACK_RANGE to 0x20 */
138 cx18_av_and_or4(cx
, CXADEC_DFE_CTRL2
, 0xFFFF00FF, 0x00002000);
140 /* Enable VBI capture */
141 cx18_av_write4(cx
, CXADEC_OUT_CTRL1
, 0x4010253F);
142 /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
144 /* Set the video input.
145 The setting in MODE_CTRL gets lost when we do the above setup */
146 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
147 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
149 v
= cx18_av_read4(cx
, CXADEC_AFE_CTRL
);
150 v
&= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */
151 v
&= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */
152 v
&= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */
153 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */
154 cx18_av_write4(cx
, CXADEC_AFE_CTRL
, v
);
156 /* if(dwEnable && dw3DCombAvailable) { */
157 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
159 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
161 cx18_av_write4(cx
, CXADEC_SRC_COMB_CFG
, 0x6628021F);
164 /* ----------------------------------------------------------------------- */
166 static void input_change(struct cx18
*cx
)
168 struct cx18_av_state
*state
= &cx
->av_state
;
169 v4l2_std_id std
= state
->std
;
171 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
172 if (std
& V4L2_STD_SECAM
)
173 cx18_av_write(cx
, 0x402, 0);
175 cx18_av_write(cx
, 0x402, 0x04);
176 cx18_av_write(cx
, 0x49f, (std
& V4L2_STD_NTSC
) ? 0x14 : 0x11);
178 cx18_av_and_or(cx
, 0x401, ~0x60, 0);
179 cx18_av_and_or(cx
, 0x401, ~0x60, 0x60);
181 if (std
& V4L2_STD_525_60
) {
182 if (std
== V4L2_STD_NTSC_M_JP
) {
183 /* Japan uses EIAJ audio standard */
184 cx18_av_write(cx
, 0x808, 0xf7);
185 } else if (std
== V4L2_STD_NTSC_M_KR
) {
186 /* South Korea uses A2 audio standard */
187 cx18_av_write(cx
, 0x808, 0xf8);
189 /* Others use the BTSC audio standard */
190 cx18_av_write(cx
, 0x808, 0xf6);
192 cx18_av_write(cx
, 0x80b, 0x00);
193 } else if (std
& V4L2_STD_PAL
) {
194 /* Follow tuner change procedure for PAL */
195 cx18_av_write(cx
, 0x808, 0xff);
196 cx18_av_write(cx
, 0x80b, 0x03);
197 } else if (std
& V4L2_STD_SECAM
) {
198 /* Select autodetect for SECAM */
199 cx18_av_write(cx
, 0x808, 0xff);
200 cx18_av_write(cx
, 0x80b, 0x03);
203 if (cx18_av_read(cx
, 0x803) & 0x10) {
204 /* restart audio decoder microcontroller */
205 cx18_av_and_or(cx
, 0x803, ~0x10, 0x00);
206 cx18_av_and_or(cx
, 0x803, ~0x10, 0x10);
210 static int set_input(struct cx18
*cx
, enum cx18_av_video_input vid_input
,
211 enum cx18_av_audio_input aud_input
)
213 struct cx18_av_state
*state
= &cx
->av_state
;
214 u8 is_composite
= (vid_input
>= CX18_AV_COMPOSITE1
&&
215 vid_input
<= CX18_AV_COMPOSITE8
);
218 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
219 vid_input
, aud_input
);
222 reg
= 0xf0 + (vid_input
- CX18_AV_COMPOSITE1
);
224 int luma
= vid_input
& 0xf0;
225 int chroma
= vid_input
& 0xf00;
227 if ((vid_input
& ~0xff0) ||
228 luma
< CX18_AV_SVIDEO_LUMA1
||
229 luma
> CX18_AV_SVIDEO_LUMA4
||
230 chroma
< CX18_AV_SVIDEO_CHROMA4
||
231 chroma
> CX18_AV_SVIDEO_CHROMA8
) {
232 CX18_ERR("0x%04x is not a valid video input!\n",
236 reg
= 0xf0 + ((luma
- CX18_AV_SVIDEO_LUMA1
) >> 4);
237 if (chroma
>= CX18_AV_SVIDEO_CHROMA7
) {
239 reg
|= (chroma
- CX18_AV_SVIDEO_CHROMA7
) >> 2;
242 reg
|= (chroma
- CX18_AV_SVIDEO_CHROMA4
) >> 4;
247 case CX18_AV_AUDIO_SERIAL
:
248 /* do nothing, use serial audio input */
250 case CX18_AV_AUDIO4
: reg
&= ~0x30; break;
251 case CX18_AV_AUDIO5
: reg
&= ~0x30; reg
|= 0x10; break;
252 case CX18_AV_AUDIO6
: reg
&= ~0x30; reg
|= 0x20; break;
253 case CX18_AV_AUDIO7
: reg
&= ~0xc0; break;
254 case CX18_AV_AUDIO8
: reg
&= ~0xc0; reg
|= 0x40; break;
257 CX18_ERR("0x%04x is not a valid audio input!\n", aud_input
);
261 cx18_av_write(cx
, 0x103, reg
);
262 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
263 cx18_av_and_or(cx
, 0x401, ~0x6, is_composite
? 0 : 0x02);
264 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
265 cx18_av_and_or(cx
, 0x102, ~0x2, (reg
& 0x80) == 0 ? 2 : 0);
266 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
267 if ((reg
& 0xc0) != 0xc0 && (reg
& 0x30) != 0x30)
268 cx18_av_and_or(cx
, 0x102, ~0x4, 4);
270 cx18_av_and_or(cx
, 0x102, ~0x4, 0);
271 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
273 state
->vid_input
= vid_input
;
274 state
->aud_input
= aud_input
;
275 cx18_av_audio_set_path(cx
);
280 /* ----------------------------------------------------------------------- */
282 static int set_v4lstd(struct cx18
*cx
)
284 struct cx18_av_state
*state
= &cx
->av_state
;
285 u8 fmt
= 0; /* zero is autodetect */
288 /* First tests should be against specific std */
289 if (state
->std
== V4L2_STD_NTSC_M_JP
) {
291 } else if (state
->std
== V4L2_STD_NTSC_443
) {
293 } else if (state
->std
== V4L2_STD_PAL_M
) {
296 } else if (state
->std
== V4L2_STD_PAL_N
) {
298 } else if (state
->std
== V4L2_STD_PAL_Nc
) {
300 } else if (state
->std
== V4L2_STD_PAL_60
) {
303 /* Then, test against generic ones */
304 if (state
->std
& V4L2_STD_NTSC
)
306 else if (state
->std
& V4L2_STD_PAL
)
308 else if (state
->std
& V4L2_STD_SECAM
)
312 CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt
);
314 /* Follow step 9 of section 3.16 in the cx18_av datasheet.
315 Without this PAL may display a vertical ghosting effect.
316 This happens for example with the Yuan MPC622. */
317 if (fmt
>= 4 && fmt
< 8) {
318 /* Set format to NTSC-M */
319 cx18_av_and_or(cx
, 0x400, ~0xf, 1);
321 cx18_av_and_or(cx
, 0x47b, ~6, 0);
323 cx18_av_and_or(cx
, 0x400, ~0xf, fmt
);
324 cx18_av_and_or(cx
, 0x403, ~0x3, pal_m
);
325 cx18_av_vbi_setup(cx
);
330 /* ----------------------------------------------------------------------- */
332 static int set_v4lctrl(struct cx18
*cx
, struct v4l2_control
*ctrl
)
335 case V4L2_CID_BRIGHTNESS
:
336 if (ctrl
->value
< 0 || ctrl
->value
> 255) {
337 CX18_ERR("invalid brightness setting %d\n",
342 cx18_av_write(cx
, 0x414, ctrl
->value
- 128);
345 case V4L2_CID_CONTRAST
:
346 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
347 CX18_ERR("invalid contrast setting %d\n",
352 cx18_av_write(cx
, 0x415, ctrl
->value
<< 1);
355 case V4L2_CID_SATURATION
:
356 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
357 CX18_ERR("invalid saturation setting %d\n",
362 cx18_av_write(cx
, 0x420, ctrl
->value
<< 1);
363 cx18_av_write(cx
, 0x421, ctrl
->value
<< 1);
367 if (ctrl
->value
< -127 || ctrl
->value
> 127) {
368 CX18_ERR("invalid hue setting %d\n", ctrl
->value
);
372 cx18_av_write(cx
, 0x422, ctrl
->value
);
375 case V4L2_CID_AUDIO_VOLUME
:
376 case V4L2_CID_AUDIO_BASS
:
377 case V4L2_CID_AUDIO_TREBLE
:
378 case V4L2_CID_AUDIO_BALANCE
:
379 case V4L2_CID_AUDIO_MUTE
:
380 return cx18_av_audio(cx
, VIDIOC_S_CTRL
, ctrl
);
389 static int get_v4lctrl(struct cx18
*cx
, struct v4l2_control
*ctrl
)
392 case V4L2_CID_BRIGHTNESS
:
393 ctrl
->value
= (s8
)cx18_av_read(cx
, 0x414) + 128;
395 case V4L2_CID_CONTRAST
:
396 ctrl
->value
= cx18_av_read(cx
, 0x415) >> 1;
398 case V4L2_CID_SATURATION
:
399 ctrl
->value
= cx18_av_read(cx
, 0x420) >> 1;
402 ctrl
->value
= (s8
)cx18_av_read(cx
, 0x422);
404 case V4L2_CID_AUDIO_VOLUME
:
405 case V4L2_CID_AUDIO_BASS
:
406 case V4L2_CID_AUDIO_TREBLE
:
407 case V4L2_CID_AUDIO_BALANCE
:
408 case V4L2_CID_AUDIO_MUTE
:
409 return cx18_av_audio(cx
, VIDIOC_G_CTRL
, ctrl
);
417 /* ----------------------------------------------------------------------- */
419 static int get_v4lfmt(struct cx18
*cx
, struct v4l2_format
*fmt
)
422 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
:
423 return cx18_av_vbi(cx
, VIDIOC_G_FMT
, fmt
);
431 static int set_v4lfmt(struct cx18
*cx
, struct v4l2_format
*fmt
)
433 struct cx18_av_state
*state
= &cx
->av_state
;
434 struct v4l2_pix_format
*pix
;
435 int HSC
, VSC
, Vsrc
, Hsrc
, filter
, Vlines
;
436 int is_50Hz
= !(state
->std
& V4L2_STD_525_60
);
439 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
440 pix
= &(fmt
->fmt
.pix
);
442 Vsrc
= (cx18_av_read(cx
, 0x476) & 0x3f) << 4;
443 Vsrc
|= (cx18_av_read(cx
, 0x475) & 0xf0) >> 4;
445 Hsrc
= (cx18_av_read(cx
, 0x472) & 0x3f) << 4;
446 Hsrc
|= (cx18_av_read(cx
, 0x471) & 0xf0) >> 4;
448 Vlines
= pix
->height
+ (is_50Hz
? 4 : 7);
450 if ((pix
->width
* 16 < Hsrc
) || (Hsrc
< pix
->width
) ||
451 (Vlines
* 8 < Vsrc
) || (Vsrc
< Vlines
)) {
452 CX18_ERR("%dx%d is not a valid size!\n",
453 pix
->width
, pix
->height
);
457 HSC
= (Hsrc
* (1 << 20)) / pix
->width
- (1 << 20);
458 VSC
= (1 << 16) - (Vsrc
* (1 << 9) / Vlines
- (1 << 9));
461 if (pix
->width
>= 385)
463 else if (pix
->width
> 192)
465 else if (pix
->width
> 96)
470 CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n",
471 pix
->width
, pix
->height
, HSC
, VSC
);
474 cx18_av_write(cx
, 0x418, HSC
& 0xff);
475 cx18_av_write(cx
, 0x419, (HSC
>> 8) & 0xff);
476 cx18_av_write(cx
, 0x41a, HSC
>> 16);
478 cx18_av_write(cx
, 0x41c, VSC
& 0xff);
479 cx18_av_write(cx
, 0x41d, VSC
>> 8);
480 /* VS_INTRLACE=1 VFILT=filter */
481 cx18_av_write(cx
, 0x41e, 0x8 | filter
);
484 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
:
485 return cx18_av_vbi(cx
, VIDIOC_S_FMT
, fmt
);
487 case V4L2_BUF_TYPE_VBI_CAPTURE
:
488 return cx18_av_vbi(cx
, VIDIOC_S_FMT
, fmt
);
497 /* ----------------------------------------------------------------------- */
499 int cx18_av_cmd(struct cx18
*cx
, unsigned int cmd
, void *arg
)
501 struct cx18_av_state
*state
= &cx
->av_state
;
502 struct v4l2_tuner
*vt
= arg
;
503 struct v4l2_routing
*route
= arg
;
505 /* ignore these commands */
507 case TUNER_SET_TYPE_ADDR
:
511 if (!state
->is_initialized
) {
512 CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd
);
513 /* initialize on first use */
514 state
->is_initialized
= 1;
515 cx18_av_initialize(cx
);
519 case VIDIOC_INT_DECODE_VBI_LINE
:
520 return cx18_av_vbi(cx
, cmd
, arg
);
522 case VIDIOC_INT_AUDIO_CLOCK_FREQ
:
523 return cx18_av_audio(cx
, cmd
, arg
);
525 case VIDIOC_STREAMON
:
526 CX18_DEBUG_INFO("enable output\n");
527 cx18_av_write(cx
, 0x115, 0x8c);
528 cx18_av_write(cx
, 0x116, 0x07);
531 case VIDIOC_STREAMOFF
:
532 CX18_DEBUG_INFO("disable output\n");
533 cx18_av_write(cx
, 0x115, 0x00);
534 cx18_av_write(cx
, 0x116, 0x00);
537 case VIDIOC_LOG_STATUS
:
538 log_video_status(cx
);
539 log_audio_status(cx
);
543 return get_v4lctrl(cx
, (struct v4l2_control
*)arg
);
546 return set_v4lctrl(cx
, (struct v4l2_control
*)arg
);
548 case VIDIOC_QUERYCTRL
:
550 struct v4l2_queryctrl
*qc
= arg
;
553 case V4L2_CID_BRIGHTNESS
:
554 case V4L2_CID_CONTRAST
:
555 case V4L2_CID_SATURATION
:
557 return v4l2_ctrl_query_fill_std(qc
);
563 case V4L2_CID_AUDIO_VOLUME
:
564 case V4L2_CID_AUDIO_MUTE
:
565 case V4L2_CID_AUDIO_BALANCE
:
566 case V4L2_CID_AUDIO_BASS
:
567 case V4L2_CID_AUDIO_TREBLE
:
568 return v4l2_ctrl_query_fill_std(qc
);
576 *(v4l2_std_id
*)arg
= state
->std
;
580 if (state
->radio
== 0 && state
->std
== *(v4l2_std_id
*)arg
)
583 state
->std
= *(v4l2_std_id
*)arg
;
584 return set_v4lstd(cx
);
590 case VIDIOC_INT_G_VIDEO_ROUTING
:
591 route
->input
= state
->vid_input
;
595 case VIDIOC_INT_S_VIDEO_ROUTING
:
596 return set_input(cx
, route
->input
, state
->aud_input
);
598 case VIDIOC_INT_G_AUDIO_ROUTING
:
599 route
->input
= state
->aud_input
;
603 case VIDIOC_INT_S_AUDIO_ROUTING
:
604 return set_input(cx
, state
->vid_input
, route
->input
);
606 case VIDIOC_S_FREQUENCY
:
612 u8 vpres
= cx18_av_read(cx
, 0x40e) & 0x20;
619 vt
->signal
= vpres
? 0xffff : 0x0;
622 V4L2_TUNER_CAP_STEREO
| V4L2_TUNER_CAP_LANG1
|
623 V4L2_TUNER_CAP_LANG2
| V4L2_TUNER_CAP_SAP
;
625 mode
= cx18_av_read(cx
, 0x804);
627 /* get rxsubchans and audmode */
628 if ((mode
& 0xf) == 1)
629 val
|= V4L2_TUNER_SUB_STEREO
;
631 val
|= V4L2_TUNER_SUB_MONO
;
633 if (mode
== 2 || mode
== 4)
634 val
= V4L2_TUNER_SUB_LANG1
| V4L2_TUNER_SUB_LANG2
;
637 val
|= V4L2_TUNER_SUB_SAP
;
639 vt
->rxsubchans
= val
;
640 vt
->audmode
= state
->audmode
;
648 switch (vt
->audmode
) {
649 case V4L2_TUNER_MODE_MONO
:
652 bilingual -> lang1 */
653 cx18_av_and_or(cx
, 0x809, ~0xf, 0x00);
655 case V4L2_TUNER_MODE_STEREO
:
656 case V4L2_TUNER_MODE_LANG1
:
659 bilingual -> lang1 */
660 cx18_av_and_or(cx
, 0x809, ~0xf, 0x04);
662 case V4L2_TUNER_MODE_LANG1_LANG2
:
665 bilingual -> lang1/lang2 */
666 cx18_av_and_or(cx
, 0x809, ~0xf, 0x07);
668 case V4L2_TUNER_MODE_LANG2
:
671 bilingual -> lang2 */
672 cx18_av_and_or(cx
, 0x809, ~0xf, 0x01);
677 state
->audmode
= vt
->audmode
;
681 return get_v4lfmt(cx
, (struct v4l2_format
*)arg
);
684 return set_v4lfmt(cx
, (struct v4l2_format
*)arg
);
686 case VIDIOC_INT_RESET
:
687 cx18_av_initialize(cx
);
697 /* ----------------------------------------------------------------------- */
699 /* ----------------------------------------------------------------------- */
701 static void log_video_status(struct cx18
*cx
)
703 static const char *const fmt_strs
[] = {
705 "NTSC-M", "NTSC-J", "NTSC-4.43",
706 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
712 struct cx18_av_state
*state
= &cx
->av_state
;
713 u8 vidfmt_sel
= cx18_av_read(cx
, 0x400) & 0xf;
714 u8 gen_stat1
= cx18_av_read(cx
, 0x40d);
715 u8 gen_stat2
= cx18_av_read(cx
, 0x40e);
716 int vid_input
= state
->vid_input
;
718 CX18_INFO("Video signal: %spresent\n",
719 (gen_stat2
& 0x20) ? "" : "not ");
720 CX18_INFO("Detected format: %s\n",
721 fmt_strs
[gen_stat1
& 0xf]);
723 CX18_INFO("Specified standard: %s\n",
724 vidfmt_sel
? fmt_strs
[vidfmt_sel
] : "automatic detection");
726 if (vid_input
>= CX18_AV_COMPOSITE1
&&
727 vid_input
<= CX18_AV_COMPOSITE8
) {
728 CX18_INFO("Specified video input: Composite %d\n",
729 vid_input
- CX18_AV_COMPOSITE1
+ 1);
731 CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
732 (vid_input
& 0xf0) >> 4, (vid_input
& 0xf00) >> 8);
735 CX18_INFO("Specified audioclock freq: %d Hz\n", state
->audclk_freq
);
738 /* ----------------------------------------------------------------------- */
740 static void log_audio_status(struct cx18
*cx
)
742 struct cx18_av_state
*state
= &cx
->av_state
;
743 u8 download_ctl
= cx18_av_read(cx
, 0x803);
744 u8 mod_det_stat0
= cx18_av_read(cx
, 0x805);
745 u8 mod_det_stat1
= cx18_av_read(cx
, 0x804);
746 u8 audio_config
= cx18_av_read(cx
, 0x808);
747 u8 pref_mode
= cx18_av_read(cx
, 0x809);
748 u8 afc0
= cx18_av_read(cx
, 0x80b);
749 u8 mute_ctl
= cx18_av_read(cx
, 0x8d3);
750 int aud_input
= state
->aud_input
;
753 switch (mod_det_stat0
) {
754 case 0x00: p
= "mono"; break;
755 case 0x01: p
= "stereo"; break;
756 case 0x02: p
= "dual"; break;
757 case 0x04: p
= "tri"; break;
758 case 0x10: p
= "mono with SAP"; break;
759 case 0x11: p
= "stereo with SAP"; break;
760 case 0x12: p
= "dual with SAP"; break;
761 case 0x14: p
= "tri with SAP"; break;
762 case 0xfe: p
= "forced mode"; break;
763 default: p
= "not defined";
765 CX18_INFO("Detected audio mode: %s\n", p
);
767 switch (mod_det_stat1
) {
768 case 0x00: p
= "BTSC"; break;
769 case 0x01: p
= "EIAJ"; break;
770 case 0x02: p
= "A2-M"; break;
771 case 0x03: p
= "A2-BG"; break;
772 case 0x04: p
= "A2-DK1"; break;
773 case 0x05: p
= "A2-DK2"; break;
774 case 0x06: p
= "A2-DK3"; break;
775 case 0x07: p
= "A1 (6.0 MHz FM Mono)"; break;
776 case 0x08: p
= "AM-L"; break;
777 case 0x09: p
= "NICAM-BG"; break;
778 case 0x0a: p
= "NICAM-DK"; break;
779 case 0x0b: p
= "NICAM-I"; break;
780 case 0x0c: p
= "NICAM-L"; break;
781 case 0x0d: p
= "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
782 case 0xff: p
= "no detected audio standard"; break;
783 default: p
= "not defined";
785 CX18_INFO("Detected audio standard: %s\n", p
);
786 CX18_INFO("Audio muted: %s\n",
787 (mute_ctl
& 0x2) ? "yes" : "no");
788 CX18_INFO("Audio microcontroller: %s\n",
789 (download_ctl
& 0x10) ? "running" : "stopped");
791 switch (audio_config
>> 4) {
792 case 0x00: p
= "BTSC"; break;
793 case 0x01: p
= "EIAJ"; break;
794 case 0x02: p
= "A2-M"; break;
795 case 0x03: p
= "A2-BG"; break;
796 case 0x04: p
= "A2-DK1"; break;
797 case 0x05: p
= "A2-DK2"; break;
798 case 0x06: p
= "A2-DK3"; break;
799 case 0x07: p
= "A1 (6.0 MHz FM Mono)"; break;
800 case 0x08: p
= "AM-L"; break;
801 case 0x09: p
= "NICAM-BG"; break;
802 case 0x0a: p
= "NICAM-DK"; break;
803 case 0x0b: p
= "NICAM-I"; break;
804 case 0x0c: p
= "NICAM-L"; break;
805 case 0x0d: p
= "FM radio"; break;
806 case 0x0f: p
= "automatic detection"; break;
807 default: p
= "undefined";
809 CX18_INFO("Configured audio standard: %s\n", p
);
811 if ((audio_config
>> 4) < 0xF) {
812 switch (audio_config
& 0xF) {
813 case 0x00: p
= "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
814 case 0x01: p
= "MONO2 (LANGUAGE B)"; break;
815 case 0x02: p
= "MONO3 (STEREO forced MONO)"; break;
816 case 0x03: p
= "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
817 case 0x04: p
= "STEREO"; break;
818 case 0x05: p
= "DUAL1 (AB)"; break;
819 case 0x06: p
= "DUAL2 (AC) (FM)"; break;
820 case 0x07: p
= "DUAL3 (BC) (FM)"; break;
821 case 0x08: p
= "DUAL4 (AC) (AM)"; break;
822 case 0x09: p
= "DUAL5 (BC) (AM)"; break;
823 case 0x0a: p
= "SAP"; break;
824 default: p
= "undefined";
826 CX18_INFO("Configured audio mode: %s\n", p
);
828 switch (audio_config
& 0xF) {
829 case 0x00: p
= "BG"; break;
830 case 0x01: p
= "DK1"; break;
831 case 0x02: p
= "DK2"; break;
832 case 0x03: p
= "DK3"; break;
833 case 0x04: p
= "I"; break;
834 case 0x05: p
= "L"; break;
835 case 0x06: p
= "BTSC"; break;
836 case 0x07: p
= "EIAJ"; break;
837 case 0x08: p
= "A2-M"; break;
838 case 0x09: p
= "FM Radio"; break;
839 case 0x0f: p
= "automatic standard and mode detection"; break;
840 default: p
= "undefined";
842 CX18_INFO("Configured audio system: %s\n", p
);
846 CX18_INFO("Specified audio input: Tuner (In%d)\n",
849 CX18_INFO("Specified audio input: External\n");
851 switch (pref_mode
& 0xf) {
852 case 0: p
= "mono/language A"; break;
853 case 1: p
= "language B"; break;
854 case 2: p
= "language C"; break;
855 case 3: p
= "analog fallback"; break;
856 case 4: p
= "stereo"; break;
857 case 5: p
= "language AC"; break;
858 case 6: p
= "language BC"; break;
859 case 7: p
= "language AB"; break;
860 default: p
= "undefined";
862 CX18_INFO("Preferred audio mode: %s\n", p
);
864 if ((audio_config
& 0xf) == 0xf) {
865 switch ((afc0
>> 2) & 0x1) {
866 case 0: p
= "system DK"; break;
867 case 1: p
= "system L"; break;
869 CX18_INFO("Selected 65 MHz format: %s\n", p
);
871 switch (afc0
& 0x3) {
872 case 0: p
= "BTSC"; break;
873 case 1: p
= "EIAJ"; break;
874 case 2: p
= "A2-M"; break;
875 default: p
= "undefined";
877 CX18_INFO("Selected 45 MHz format: %s\n", p
);