1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "cx18-driver.h"
21#include "cx18-io.h"
22#include "cx18-cards.h"
23
24int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
25{
26 u32 reg = 0xc40000 + (addr & ~3);
27 u32 mask = 0xff;
28 int shift = (addr & 3) * 8;
29 u32 x = cx18_read_reg(cx, reg);
30
31 x = (x & ~(mask << shift)) | ((u32)value << shift);
32 cx18_write_reg(cx, x, reg);
33 return 0;
34}
35
36int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask)
37{
38 u32 reg = 0xc40000 + (addr & ~3);
39 int shift = (addr & 3) * 8;
40 u32 x = cx18_read_reg(cx, reg);
41
42 x = (x & ~((u32)0xff << shift)) | ((u32)value << shift);
43 cx18_write_reg_expect(cx, x, reg,
44 ((u32)eval << shift), ((u32)mask << shift));
45 return 0;
46}
47
48int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
49{
50 cx18_write_reg(cx, value, 0xc40000 + addr);
51 return 0;
52}
53
54int
55cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, u32 mask)
56{
57 cx18_write_reg_expect(cx, value, 0xc40000 + addr, eval, mask);
58 return 0;
59}
60
61int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value)
62{
63 cx18_write_reg_noretry(cx, value, 0xc40000 + addr);
64 return 0;
65}
66
67u8 cx18_av_read(struct cx18 *cx, u16 addr)
68{
69 u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3));
70 int shift = (addr & 3) * 8;
71
72 return (x >> shift) & 0xff;
73}
74
75u32 cx18_av_read4(struct cx18 *cx, u16 addr)
76{
77 return cx18_read_reg(cx, 0xc40000 + addr);
78}
79
80int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
81 u8 or_value)
82{
83 return cx18_av_write(cx, addr,
84 (cx18_av_read(cx, addr) & and_mask) |
85 or_value);
86}
87
88int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
89 u32 or_value)
90{
91 return cx18_av_write4(cx, addr,
92 (cx18_av_read4(cx, addr) & and_mask) |
93 or_value);
94}
95
96static void cx18_av_init(struct cx18 *cx)
97{
98
99
100
101
102
103
104
105
106
107
108 cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
109
110
111
112 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
113
114
115
116 cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
117
118
119 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
120}
121
122static void cx18_av_initialize(struct v4l2_subdev *sd)
123{
124 struct cx18_av_state *state = to_cx18_av_state(sd);
125 struct cx18 *cx = v4l2_get_subdevdata(sd);
126 int default_volume;
127 u32 v;
128
129 cx18_av_loadfw(cx);
130
131 cx18_av_write4_expect(cx, CXADEC_DL_CTL, 0x03000000,
132 0x03000000, 0x13000000);
133
134
135 v = cx18_av_read4(cx, CXADEC_HOST_REG1);
136
137 cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v | 1, v, 0xfffe);
138
139 cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v & 0xfffe,
140 v & 0xfffe, 0xffff);
141
142
143 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
144
145 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
146
147 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
148
149 v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
150
151 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
152
153 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
154
155
156 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
157
158 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
159
160 cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, v, v, 0x03009F0F);
161
162 cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3,
163 v & 0xFFFFFFFE, v & 0xFFFFFFFE, 0x03009F0F);
164
165
166 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
167
168
169 cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
170
171
172 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
173 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
191
192
193 cx18_av_init(cx);
194
195
196
197
198 cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
199
200
201
202 cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
203
204
205 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
206
207
208
209
210
211
212
213
214 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
238
239
240
241
242
243
244 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
245 default_volume = cx18_av_read(cx, 0x8d4);
246
247
248
249
250 if (default_volume > 228) {
251
252 default_volume = 228;
253 cx18_av_write(cx, 0x8d4, 228);
254 } else if (default_volume < 20) {
255
256 default_volume = 20;
257 cx18_av_write(cx, 0x8d4, 20);
258 }
259 default_volume = (((228 - default_volume) >> 1) + 23) << 9;
260 state->volume->cur.val = state->volume->default_value = default_volume;
261 v4l2_ctrl_handler_setup(&state->hdl);
262}
263
264static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
265{
266 cx18_av_initialize(sd);
267 return 0;
268}
269
270static int cx18_av_load_fw(struct v4l2_subdev *sd)
271{
272 struct cx18_av_state *state = to_cx18_av_state(sd);
273
274 if (!state->is_initialized) {
275
276 state->is_initialized = 1;
277 cx18_av_initialize(sd);
278 }
279 return 0;
280}
281
282void cx18_av_std_setup(struct cx18 *cx)
283{
284 struct cx18_av_state *state = &cx->av_state;
285 struct v4l2_subdev *sd = &state->sd;
286 v4l2_std_id std = state->std;
287
288
289
290
291
292 const int src_decimation = 0x21f;
293
294 int hblank, hactive, burst, vblank, vactive, sc;
295 int vblank656;
296 int luma_lpf, uv_lpf, comb;
297 u32 pll_int, pll_frac, pll_post;
298
299
300 if (std & ~V4L2_STD_NTSC)
301 cx18_av_write(cx, 0x49f, 0x11);
302 else
303 cx18_av_write(cx, 0x49f, 0x14);
304
305
306
307
308
309
310
311
312
313 if (std & V4L2_STD_625_50) {
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345 vblank656 = 48;
346 vblank = 38;
347 vactive = 579;
348
349
350
351
352
353
354
355
356 hblank = 132;
357 hactive = 720;
358
359
360
361
362
363
364
365
366 burst = 93;
367 luma_lpf = 2;
368 if (std & V4L2_STD_PAL) {
369 uv_lpf = 1;
370 comb = 0x20;
371
372 sc = 688700;
373 } else if (std == V4L2_STD_PAL_Nc) {
374 uv_lpf = 1;
375 comb = 0x20;
376
377 sc = 556422;
378 } else {
379 uv_lpf = 0;
380 comb = 0;
381
382
383 sc = 672314;
384 }
385 } else {
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405 vblank656 = 38;
406 vblank = 26;
407 vactive = 481;
408
409
410
411
412
413
414
415
416 hactive = 720;
417 hblank = 122;
418 luma_lpf = 1;
419 uv_lpf = 1;
420
421
422
423
424
425
426
427
428 if (std == V4L2_STD_PAL_60) {
429 burst = 90;
430 luma_lpf = 2;
431 comb = 0x20;
432
433 sc = 688700;
434 } else if (std == V4L2_STD_PAL_M) {
435
436 burst = 97;
437 comb = 0x20;
438
439 sc = 555421;
440 } else {
441 burst = 90;
442 comb = 0x66;
443
444 sc = 556032;
445 }
446 }
447
448
449 pll_int = cx18_av_read(cx, 0x108);
450 pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
451 pll_post = cx18_av_read(cx, 0x109);
452 CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n",
453 pll_int, pll_frac, pll_post);
454
455 if (pll_post) {
456 int fsc, pll;
457 u64 tmp;
458
459 pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
460 pll /= pll_post;
461 CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n",
462 pll / 1000000, pll % 1000000);
463 CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n",
464 pll / 8000000, (pll / 8) % 1000000);
465
466 CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio = %d.%03d\n",
467 src_decimation / 256,
468 ((src_decimation % 256) * 1000) / 256);
469
470 tmp = 28636360 * (u64) sc;
471 do_div(tmp, src_decimation);
472 fsc = tmp >> 13;
473 CX18_DEBUG_INFO_DEV(sd,
474 "Chroma sub-carrier initial freq = %d.%06d MHz\n",
475 fsc / 1000000, fsc % 1000000);
476
477 CX18_DEBUG_INFO_DEV(sd,
478 "hblank %i, hactive %i, vblank %i, vactive %i, vblank656 %i, src_dec %i, burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, sc 0x%06x\n",
479 hblank, hactive, vblank, vactive, vblank656,
480 src_decimation, burst, luma_lpf, uv_lpf,
481 comb, sc);
482 }
483
484
485 cx18_av_write(cx, 0x470, hblank);
486 cx18_av_write(cx, 0x471,
487 (((hblank >> 8) & 0x3) | (hactive << 4)) & 0xff);
488 cx18_av_write(cx, 0x472, hactive >> 4);
489
490
491 cx18_av_write(cx, 0x473, burst);
492
493
494 cx18_av_write(cx, 0x474, vblank);
495 cx18_av_write(cx, 0x475,
496 (((vblank >> 8) & 0x3) | (vactive << 4)) & 0xff);
497 cx18_av_write(cx, 0x476, vactive >> 4);
498 cx18_av_write(cx, 0x477, vblank656);
499
500
501 cx18_av_write(cx, 0x478, src_decimation & 0xff);
502 cx18_av_write(cx, 0x479, (src_decimation >> 8) & 0xff);
503
504
505 cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
506
507
508 cx18_av_write(cx, 0x47b, comb);
509
510
511 cx18_av_write(cx, 0x47c, sc);
512 cx18_av_write(cx, 0x47d, (sc >> 8) & 0xff);
513 cx18_av_write(cx, 0x47e, (sc >> 16) & 0xff);
514
515 if (std & V4L2_STD_625_50) {
516 state->slicer_line_delay = 1;
517 state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
518 } else {
519 state->slicer_line_delay = 0;
520 state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
521 }
522 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
523}
524
525static void input_change(struct cx18 *cx)
526{
527 struct cx18_av_state *state = &cx->av_state;
528 v4l2_std_id std = state->std;
529 u8 v;
530
531
532 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
533 cx18_av_and_or(cx, 0x401, ~0x60, 0);
534 cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
535
536 if (std & V4L2_STD_525_60) {
537 if (std == V4L2_STD_NTSC_M_JP) {
538
539 cx18_av_write_expect(cx, 0x808, 0xf7, 0xf7, 0xff);
540 cx18_av_write_expect(cx, 0x80b, 0x02, 0x02, 0x3f);
541 } else if (std == V4L2_STD_NTSC_M_KR) {
542
543 cx18_av_write_expect(cx, 0x808, 0xf8, 0xf8, 0xff);
544 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
545 } else {
546
547 cx18_av_write_expect(cx, 0x808, 0xf6, 0xf6, 0xff);
548 cx18_av_write_expect(cx, 0x80b, 0x01, 0x01, 0x3f);
549 }
550 } else if (std & V4L2_STD_PAL) {
551
552 cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
553 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
554 } else if (std & V4L2_STD_SECAM) {
555
556 cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
557 cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
558 }
559
560 v = cx18_av_read(cx, 0x803);
561 if (v & 0x10) {
562
563 v &= ~0x10;
564 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
565 v |= 0x10;
566 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
567 }
568}
569
570static int cx18_av_s_frequency(struct v4l2_subdev *sd,
571 const struct v4l2_frequency *freq)
572{
573 struct cx18 *cx = v4l2_get_subdevdata(sd);
574 input_change(cx);
575 return 0;
576}
577
578static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
579 enum cx18_av_audio_input aud_input)
580{
581 struct cx18_av_state *state = &cx->av_state;
582 struct v4l2_subdev *sd = &state->sd;
583
584 enum analog_signal_type {
585 NONE, CVBS, Y, C, SIF, Pb, Pr
586 } ch[3] = {NONE, NONE, NONE};
587
588 u8 afe_mux_cfg;
589 u8 adc2_cfg;
590 u8 input_mode;
591 u32 afe_cfg;
592 int i;
593
594 CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
595 vid_input, aud_input);
596
597 if (vid_input >= CX18_AV_COMPOSITE1 &&
598 vid_input <= CX18_AV_COMPOSITE8) {
599 afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
600 ch[0] = CVBS;
601 input_mode = 0x0;
602 } else if (vid_input >= CX18_AV_COMPONENT_LUMA1) {
603 int luma = vid_input & 0xf000;
604 int r_chroma = vid_input & 0xf0000;
605 int b_chroma = vid_input & 0xf00000;
606
607 if ((vid_input & ~0xfff000) ||
608 luma < CX18_AV_COMPONENT_LUMA1 ||
609 luma > CX18_AV_COMPONENT_LUMA8 ||
610 r_chroma < CX18_AV_COMPONENT_R_CHROMA4 ||
611 r_chroma > CX18_AV_COMPONENT_R_CHROMA6 ||
612 b_chroma < CX18_AV_COMPONENT_B_CHROMA7 ||
613 b_chroma > CX18_AV_COMPONENT_B_CHROMA8) {
614 CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
615 vid_input);
616 return -EINVAL;
617 }
618 afe_mux_cfg = (luma - CX18_AV_COMPONENT_LUMA1) >> 12;
619 ch[0] = Y;
620 afe_mux_cfg |= (r_chroma - CX18_AV_COMPONENT_R_CHROMA4) >> 12;
621 ch[1] = Pr;
622 afe_mux_cfg |= (b_chroma - CX18_AV_COMPONENT_B_CHROMA7) >> 14;
623 ch[2] = Pb;
624 input_mode = 0x6;
625 } else {
626 int luma = vid_input & 0xf0;
627 int chroma = vid_input & 0xf00;
628
629 if ((vid_input & ~0xff0) ||
630 luma < CX18_AV_SVIDEO_LUMA1 ||
631 luma > CX18_AV_SVIDEO_LUMA8 ||
632 chroma < CX18_AV_SVIDEO_CHROMA4 ||
633 chroma > CX18_AV_SVIDEO_CHROMA8) {
634 CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
635 vid_input);
636 return -EINVAL;
637 }
638 afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
639 ch[0] = Y;
640 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
641 afe_mux_cfg &= 0x3f;
642 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
643 ch[2] = C;
644 } else {
645 afe_mux_cfg &= 0xcf;
646 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
647 ch[1] = C;
648 }
649 input_mode = 0x2;
650 }
651
652 switch (aud_input) {
653 case CX18_AV_AUDIO_SERIAL1:
654 case CX18_AV_AUDIO_SERIAL2:
655
656 break;
657 case CX18_AV_AUDIO4:
658 afe_mux_cfg &= ~0x30;
659 ch[1] = SIF;
660 break;
661 case CX18_AV_AUDIO5:
662 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
663 ch[1] = SIF;
664 break;
665 case CX18_AV_AUDIO6:
666 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
667 ch[1] = SIF;
668 break;
669 case CX18_AV_AUDIO7:
670 afe_mux_cfg &= ~0xc0;
671 ch[2] = SIF;
672 break;
673 case CX18_AV_AUDIO8:
674 afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
675 ch[2] = SIF;
676 break;
677
678 default:
679 CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
680 aud_input);
681 return -EINVAL;
682 }
683
684
685 cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
686
687 cx18_av_and_or(cx, 0x401, ~0x6, input_mode);
688
689
690 adc2_cfg = cx18_av_read(cx, 0x102);
691 if (ch[2] == NONE)
692 adc2_cfg &= ~0x2;
693 else
694 adc2_cfg |= 0x2;
695
696
697 if (ch[1] != NONE && ch[2] != NONE)
698 adc2_cfg |= 0x4;
699 else
700 adc2_cfg &= ~0x4;
701 cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
702
703
704 afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
705 afe_cfg &= 0xff000000;
706 afe_cfg |= 0x00005000;
707 if (ch[1] != NONE && ch[2] != NONE)
708 afe_cfg |= 0x00000030;
709
710 for (i = 0; i < 3; i++) {
711 switch (ch[i]) {
712 default:
713 case NONE:
714
715 afe_cfg |= (0x00000200 << i);
716 break;
717 case CVBS:
718 case Y:
719 if (i > 0)
720 afe_cfg |= 0x00002000;
721 break;
722 case C:
723 case Pb:
724 case Pr:
725
726 afe_cfg |= (0x00000200 << i);
727 if (i == 0 && ch[i] == C)
728 afe_cfg &= ~0x00001000;
729 break;
730 case SIF:
731
732
733
734
735 afe_cfg |= (0x00000240 << i);
736 if (i == 0)
737 afe_cfg &= ~0x00004000;
738 break;
739 }
740 }
741
742 cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
743
744 state->vid_input = vid_input;
745 state->aud_input = aud_input;
746 cx18_av_audio_set_path(cx);
747 input_change(cx);
748 return 0;
749}
750
751static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
752 u32 input, u32 output, u32 config)
753{
754 struct cx18_av_state *state = to_cx18_av_state(sd);
755 struct cx18 *cx = v4l2_get_subdevdata(sd);
756 return set_input(cx, input, state->aud_input);
757}
758
759static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
760 u32 input, u32 output, u32 config)
761{
762 struct cx18_av_state *state = to_cx18_av_state(sd);
763 struct cx18 *cx = v4l2_get_subdevdata(sd);
764 return set_input(cx, state->vid_input, input);
765}
766
767static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
768{
769 struct cx18_av_state *state = to_cx18_av_state(sd);
770 struct cx18 *cx = v4l2_get_subdevdata(sd);
771 u8 vpres;
772 u8 mode;
773 int val = 0;
774
775 if (state->radio)
776 return 0;
777
778 vpres = cx18_av_read(cx, 0x40e) & 0x20;
779 vt->signal = vpres ? 0xffff : 0x0;
780
781 vt->capability |=
782 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
783 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
784
785 mode = cx18_av_read(cx, 0x804);
786
787
788 if ((mode & 0xf) == 1)
789 val |= V4L2_TUNER_SUB_STEREO;
790 else
791 val |= V4L2_TUNER_SUB_MONO;
792
793 if (mode == 2 || mode == 4)
794 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
795
796 if (mode & 0x10)
797 val |= V4L2_TUNER_SUB_SAP;
798
799 vt->rxsubchans = val;
800 vt->audmode = state->audmode;
801 return 0;
802}
803
804static int cx18_av_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
805{
806 struct cx18_av_state *state = to_cx18_av_state(sd);
807 struct cx18 *cx = v4l2_get_subdevdata(sd);
808 u8 v;
809
810 if (state->radio)
811 return 0;
812
813 v = cx18_av_read(cx, 0x809);
814 v &= ~0xf;
815
816 switch (vt->audmode) {
817 case V4L2_TUNER_MODE_MONO:
818
819
820
821 break;
822 case V4L2_TUNER_MODE_STEREO:
823 case V4L2_TUNER_MODE_LANG1:
824
825
826
827 v |= 0x4;
828 break;
829 case V4L2_TUNER_MODE_LANG1_LANG2:
830
831
832
833 v |= 0x7;
834 break;
835 case V4L2_TUNER_MODE_LANG2:
836
837
838
839 v |= 0x1;
840 break;
841 default:
842 return -EINVAL;
843 }
844 cx18_av_write_expect(cx, 0x809, v, v, 0xff);
845 state->audmode = vt->audmode;
846 return 0;
847}
848
849static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
850{
851 struct cx18_av_state *state = to_cx18_av_state(sd);
852 struct cx18 *cx = v4l2_get_subdevdata(sd);
853
854 u8 fmt = 0;
855 u8 pal_m = 0;
856
857 if (state->radio == 0 && state->std == norm)
858 return 0;
859
860 state->radio = 0;
861 state->std = norm;
862
863
864 if (state->std == V4L2_STD_NTSC_M_JP) {
865 fmt = 0x2;
866 } else if (state->std == V4L2_STD_NTSC_443) {
867 fmt = 0x3;
868 } else if (state->std == V4L2_STD_PAL_M) {
869 pal_m = 1;
870 fmt = 0x5;
871 } else if (state->std == V4L2_STD_PAL_N) {
872 fmt = 0x6;
873 } else if (state->std == V4L2_STD_PAL_Nc) {
874 fmt = 0x7;
875 } else if (state->std == V4L2_STD_PAL_60) {
876 fmt = 0x8;
877 } else {
878
879 if (state->std & V4L2_STD_NTSC)
880 fmt = 0x1;
881 else if (state->std & V4L2_STD_PAL)
882 fmt = 0x4;
883 else if (state->std & V4L2_STD_SECAM)
884 fmt = 0xc;
885 }
886
887 CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt);
888
889
890
891
892 if (fmt >= 4 && fmt < 8) {
893
894 cx18_av_and_or(cx, 0x400, ~0xf, 1);
895
896 cx18_av_and_or(cx, 0x47b, ~6, 0);
897 }
898 cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20);
899 cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
900 cx18_av_std_setup(cx);
901 input_change(cx);
902 return 0;
903}
904
905static int cx18_av_s_radio(struct v4l2_subdev *sd)
906{
907 struct cx18_av_state *state = to_cx18_av_state(sd);
908 state->radio = 1;
909 return 0;
910}
911
912static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl)
913{
914 struct v4l2_subdev *sd = to_sd(ctrl);
915 struct cx18 *cx = v4l2_get_subdevdata(sd);
916
917 switch (ctrl->id) {
918 case V4L2_CID_BRIGHTNESS:
919 cx18_av_write(cx, 0x414, ctrl->val - 128);
920 break;
921
922 case V4L2_CID_CONTRAST:
923 cx18_av_write(cx, 0x415, ctrl->val << 1);
924 break;
925
926 case V4L2_CID_SATURATION:
927 cx18_av_write(cx, 0x420, ctrl->val << 1);
928 cx18_av_write(cx, 0x421, ctrl->val << 1);
929 break;
930
931 case V4L2_CID_HUE:
932 cx18_av_write(cx, 0x422, ctrl->val);
933 break;
934
935 default:
936 return -EINVAL;
937 }
938 return 0;
939}
940
941static int cx18_av_set_fmt(struct v4l2_subdev *sd,
942 struct v4l2_subdev_pad_config *cfg,
943 struct v4l2_subdev_format *format)
944{
945 struct v4l2_mbus_framefmt *fmt = &format->format;
946 struct cx18_av_state *state = to_cx18_av_state(sd);
947 struct cx18 *cx = v4l2_get_subdevdata(sd);
948 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
949 int is_50Hz = !(state->std & V4L2_STD_525_60);
950
951 if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)
952 return -EINVAL;
953
954 fmt->field = V4L2_FIELD_INTERLACED;
955 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
956
957 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
958 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
959
960 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
961 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
962
963
964
965
966
967
968
969
970 Vlines = fmt->height + (is_50Hz ? 3 : 1);
971
972
973
974
975
976
977
978
979 if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
980 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
981 CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
982 fmt->width, fmt->height);
983 return -ERANGE;
984 }
985
986 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
987 return 0;
988
989 HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
990 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
991 VSC &= 0x1fff;
992
993 if (fmt->width >= 385)
994 filter = 0;
995 else if (fmt->width > 192)
996 filter = 1;
997 else if (fmt->width > 96)
998 filter = 2;
999 else
1000 filter = 3;
1001
1002 CX18_DEBUG_INFO_DEV(sd,
1003 "decoder set size %dx%d -> scale %ux%u\n",
1004 fmt->width, fmt->height, HSC, VSC);
1005
1006
1007 cx18_av_write(cx, 0x418, HSC & 0xff);
1008 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
1009 cx18_av_write(cx, 0x41a, HSC >> 16);
1010
1011 cx18_av_write(cx, 0x41c, VSC & 0xff);
1012 cx18_av_write(cx, 0x41d, VSC >> 8);
1013
1014 cx18_av_write(cx, 0x41e, 0x8 | filter);
1015 return 0;
1016}
1017
1018static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable)
1019{
1020 struct cx18 *cx = v4l2_get_subdevdata(sd);
1021
1022 CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable");
1023 if (enable) {
1024 cx18_av_write(cx, 0x115, 0x8c);
1025 cx18_av_write(cx, 0x116, 0x07);
1026 } else {
1027 cx18_av_write(cx, 0x115, 0x00);
1028 cx18_av_write(cx, 0x116, 0x00);
1029 }
1030 return 0;
1031}
1032
1033static void log_video_status(struct cx18 *cx)
1034{
1035 static const char *const fmt_strs[] = {
1036 "0x0",
1037 "NTSC-M", "NTSC-J", "NTSC-4.43",
1038 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
1039 "0x9", "0xA", "0xB",
1040 "SECAM",
1041 "0xD", "0xE", "0xF"
1042 };
1043
1044 struct cx18_av_state *state = &cx->av_state;
1045 struct v4l2_subdev *sd = &state->sd;
1046 u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
1047 u8 gen_stat1 = cx18_av_read(cx, 0x40d);
1048 u8 gen_stat2 = cx18_av_read(cx, 0x40e);
1049 int vid_input = state->vid_input;
1050
1051 CX18_INFO_DEV(sd, "Video signal: %spresent\n",
1052 (gen_stat2 & 0x20) ? "" : "not ");
1053 CX18_INFO_DEV(sd, "Detected format: %s\n",
1054 fmt_strs[gen_stat1 & 0xf]);
1055
1056 CX18_INFO_DEV(sd, "Specified standard: %s\n",
1057 vidfmt_sel ? fmt_strs[vidfmt_sel]
1058 : "automatic detection");
1059
1060 if (vid_input >= CX18_AV_COMPOSITE1 &&
1061 vid_input <= CX18_AV_COMPOSITE8) {
1062 CX18_INFO_DEV(sd, "Specified video input: Composite %d\n",
1063 vid_input - CX18_AV_COMPOSITE1 + 1);
1064 } else {
1065 CX18_INFO_DEV(sd, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1066 (vid_input & 0xf0) >> 4,
1067 (vid_input & 0xf00) >> 8);
1068 }
1069
1070 CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n",
1071 state->audclk_freq);
1072}
1073
1074static void log_audio_status(struct cx18 *cx)
1075{
1076 struct cx18_av_state *state = &cx->av_state;
1077 struct v4l2_subdev *sd = &state->sd;
1078 u8 download_ctl = cx18_av_read(cx, 0x803);
1079 u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
1080 u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
1081 u8 audio_config = cx18_av_read(cx, 0x808);
1082 u8 pref_mode = cx18_av_read(cx, 0x809);
1083 u8 afc0 = cx18_av_read(cx, 0x80b);
1084 u8 mute_ctl = cx18_av_read(cx, 0x8d3);
1085 int aud_input = state->aud_input;
1086 char *p;
1087
1088 switch (mod_det_stat0) {
1089 case 0x00: p = "mono"; break;
1090 case 0x01: p = "stereo"; break;
1091 case 0x02: p = "dual"; break;
1092 case 0x04: p = "tri"; break;
1093 case 0x10: p = "mono with SAP"; break;
1094 case 0x11: p = "stereo with SAP"; break;
1095 case 0x12: p = "dual with SAP"; break;
1096 case 0x14: p = "tri with SAP"; break;
1097 case 0xfe: p = "forced mode"; break;
1098 default: p = "not defined"; break;
1099 }
1100 CX18_INFO_DEV(sd, "Detected audio mode: %s\n", p);
1101
1102 switch (mod_det_stat1) {
1103 case 0x00: p = "not defined"; break;
1104 case 0x01: p = "EIAJ"; break;
1105 case 0x02: p = "A2-M"; break;
1106 case 0x03: p = "A2-BG"; break;
1107 case 0x04: p = "A2-DK1"; break;
1108 case 0x05: p = "A2-DK2"; break;
1109 case 0x06: p = "A2-DK3"; break;
1110 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
1111 case 0x08: p = "AM-L"; break;
1112 case 0x09: p = "NICAM-BG"; break;
1113 case 0x0a: p = "NICAM-DK"; break;
1114 case 0x0b: p = "NICAM-I"; break;
1115 case 0x0c: p = "NICAM-L"; break;
1116 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
1117 case 0x0e: p = "IF FM Radio"; break;
1118 case 0x0f: p = "BTSC"; break;
1119 case 0x10: p = "detected chrominance"; break;
1120 case 0xfd: p = "unknown audio standard"; break;
1121 case 0xfe: p = "forced audio standard"; break;
1122 case 0xff: p = "no detected audio standard"; break;
1123 default: p = "not defined"; break;
1124 }
1125 CX18_INFO_DEV(sd, "Detected audio standard: %s\n", p);
1126 CX18_INFO_DEV(sd, "Audio muted: %s\n",
1127 (mute_ctl & 0x2) ? "yes" : "no");
1128 CX18_INFO_DEV(sd, "Audio microcontroller: %s\n",
1129 (download_ctl & 0x10) ? "running" : "stopped");
1130
1131 switch (audio_config >> 4) {
1132 case 0x00: p = "undefined"; break;
1133 case 0x01: p = "BTSC"; break;
1134 case 0x02: p = "EIAJ"; break;
1135 case 0x03: p = "A2-M"; break;
1136 case 0x04: p = "A2-BG"; break;
1137 case 0x05: p = "A2-DK1"; break;
1138 case 0x06: p = "A2-DK2"; break;
1139 case 0x07: p = "A2-DK3"; break;
1140 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
1141 case 0x09: p = "AM-L"; break;
1142 case 0x0a: p = "NICAM-BG"; break;
1143 case 0x0b: p = "NICAM-DK"; break;
1144 case 0x0c: p = "NICAM-I"; break;
1145 case 0x0d: p = "NICAM-L"; break;
1146 case 0x0e: p = "FM radio"; break;
1147 case 0x0f: p = "automatic detection"; break;
1148 default: p = "undefined"; break;
1149 }
1150 CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p);
1151
1152 if ((audio_config >> 4) < 0xF) {
1153 switch (audio_config & 0xF) {
1154 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
1155 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
1156 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
1157 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
1158 case 0x04: p = "STEREO"; break;
1159 case 0x05: p = "DUAL1 (AC)"; break;
1160 case 0x06: p = "DUAL2 (BC)"; break;
1161 case 0x07: p = "DUAL3 (AB)"; break;
1162 default: p = "undefined";
1163 }
1164 CX18_INFO_DEV(sd, "Configured audio mode: %s\n", p);
1165 } else {
1166 switch (audio_config & 0xF) {
1167 case 0x00: p = "BG"; break;
1168 case 0x01: p = "DK1"; break;
1169 case 0x02: p = "DK2"; break;
1170 case 0x03: p = "DK3"; break;
1171 case 0x04: p = "I"; break;
1172 case 0x05: p = "L"; break;
1173 case 0x06: p = "BTSC"; break;
1174 case 0x07: p = "EIAJ"; break;
1175 case 0x08: p = "A2-M"; break;
1176 case 0x09: p = "FM Radio (4.5 MHz)"; break;
1177 case 0x0a: p = "FM Radio (5.5 MHz)"; break;
1178 case 0x0b: p = "S-Video"; break;
1179 case 0x0f: p = "automatic standard and mode detection"; break;
1180 default: p = "undefined"; break;
1181 }
1182 CX18_INFO_DEV(sd, "Configured audio system: %s\n", p);
1183 }
1184
1185 if (aud_input)
1186 CX18_INFO_DEV(sd, "Specified audio input: Tuner (In%d)\n",
1187 aud_input);
1188 else
1189 CX18_INFO_DEV(sd, "Specified audio input: External\n");
1190
1191 switch (pref_mode & 0xf) {
1192 case 0: p = "mono/language A"; break;
1193 case 1: p = "language B"; break;
1194 case 2: p = "language C"; break;
1195 case 3: p = "analog fallback"; break;
1196 case 4: p = "stereo"; break;
1197 case 5: p = "language AC"; break;
1198 case 6: p = "language BC"; break;
1199 case 7: p = "language AB"; break;
1200 default: p = "undefined"; break;
1201 }
1202 CX18_INFO_DEV(sd, "Preferred audio mode: %s\n", p);
1203
1204 if ((audio_config & 0xf) == 0xf) {
1205 switch ((afc0 >> 3) & 0x1) {
1206 case 0: p = "system DK"; break;
1207 case 1: p = "system L"; break;
1208 }
1209 CX18_INFO_DEV(sd, "Selected 65 MHz format: %s\n", p);
1210
1211 switch (afc0 & 0x7) {
1212 case 0: p = "Chroma"; break;
1213 case 1: p = "BTSC"; break;
1214 case 2: p = "EIAJ"; break;
1215 case 3: p = "A2-M"; break;
1216 case 4: p = "autodetect"; break;
1217 default: p = "undefined"; break;
1218 }
1219 CX18_INFO_DEV(sd, "Selected 45 MHz format: %s\n", p);
1220 }
1221}
1222
1223static int cx18_av_log_status(struct v4l2_subdev *sd)
1224{
1225 struct cx18 *cx = v4l2_get_subdevdata(sd);
1226 log_video_status(cx);
1227 log_audio_status(cx);
1228 return 0;
1229}
1230
1231#ifdef CONFIG_VIDEO_ADV_DEBUG
1232static int cx18_av_g_register(struct v4l2_subdev *sd,
1233 struct v4l2_dbg_register *reg)
1234{
1235 struct cx18 *cx = v4l2_get_subdevdata(sd);
1236
1237 if ((reg->reg & 0x3) != 0)
1238 return -EINVAL;
1239 reg->size = 4;
1240 reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
1241 return 0;
1242}
1243
1244static int cx18_av_s_register(struct v4l2_subdev *sd,
1245 const struct v4l2_dbg_register *reg)
1246{
1247 struct cx18 *cx = v4l2_get_subdevdata(sd);
1248
1249 if ((reg->reg & 0x3) != 0)
1250 return -EINVAL;
1251 cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
1252 return 0;
1253}
1254#endif
1255
1256static const struct v4l2_ctrl_ops cx18_av_ctrl_ops = {
1257 .s_ctrl = cx18_av_s_ctrl,
1258};
1259
1260static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
1261 .log_status = cx18_av_log_status,
1262 .load_fw = cx18_av_load_fw,
1263 .reset = cx18_av_reset,
1264#ifdef CONFIG_VIDEO_ADV_DEBUG
1265 .g_register = cx18_av_g_register,
1266 .s_register = cx18_av_s_register,
1267#endif
1268};
1269
1270static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
1271 .s_radio = cx18_av_s_radio,
1272 .s_frequency = cx18_av_s_frequency,
1273 .g_tuner = cx18_av_g_tuner,
1274 .s_tuner = cx18_av_s_tuner,
1275};
1276
1277static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
1278 .s_clock_freq = cx18_av_s_clock_freq,
1279 .s_routing = cx18_av_s_audio_routing,
1280};
1281
1282static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
1283 .s_std = cx18_av_s_std,
1284 .s_routing = cx18_av_s_video_routing,
1285 .s_stream = cx18_av_s_stream,
1286};
1287
1288static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = {
1289 .decode_vbi_line = cx18_av_decode_vbi_line,
1290 .g_sliced_fmt = cx18_av_g_sliced_fmt,
1291 .s_sliced_fmt = cx18_av_s_sliced_fmt,
1292 .s_raw_fmt = cx18_av_s_raw_fmt,
1293};
1294
1295static const struct v4l2_subdev_pad_ops cx18_av_pad_ops = {
1296 .set_fmt = cx18_av_set_fmt,
1297};
1298
1299static const struct v4l2_subdev_ops cx18_av_ops = {
1300 .core = &cx18_av_general_ops,
1301 .tuner = &cx18_av_tuner_ops,
1302 .audio = &cx18_av_audio_ops,
1303 .video = &cx18_av_video_ops,
1304 .vbi = &cx18_av_vbi_ops,
1305 .pad = &cx18_av_pad_ops,
1306};
1307
1308int cx18_av_probe(struct cx18 *cx)
1309{
1310 struct cx18_av_state *state = &cx->av_state;
1311 struct v4l2_subdev *sd;
1312 int err;
1313
1314 state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
1315
1316 state->vid_input = CX18_AV_COMPOSITE7;
1317 state->aud_input = CX18_AV_AUDIO8;
1318 state->audclk_freq = 48000;
1319 state->audmode = V4L2_TUNER_MODE_LANG1;
1320 state->slicer_line_delay = 0;
1321 state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
1322
1323 sd = &state->sd;
1324 v4l2_subdev_init(sd, &cx18_av_ops);
1325 v4l2_set_subdevdata(sd, cx);
1326 snprintf(sd->name, sizeof(sd->name),
1327 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
1328 sd->grp_id = CX18_HW_418_AV;
1329 v4l2_ctrl_handler_init(&state->hdl, 9);
1330 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1331 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1332 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1333 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1334 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1335 V4L2_CID_SATURATION, 0, 127, 1, 64);
1336 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1337 V4L2_CID_HUE, -128, 127, 1, 0);
1338
1339 state->volume = v4l2_ctrl_new_std(&state->hdl,
1340 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
1341 0, 65535, 65535 / 100, 0);
1342 v4l2_ctrl_new_std(&state->hdl,
1343 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
1344 0, 1, 1, 0);
1345 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1346 V4L2_CID_AUDIO_BALANCE,
1347 0, 65535, 65535 / 100, 32768);
1348 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1349 V4L2_CID_AUDIO_BASS,
1350 0, 65535, 65535 / 100, 32768);
1351 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1352 V4L2_CID_AUDIO_TREBLE,
1353 0, 65535, 65535 / 100, 32768);
1354 sd->ctrl_handler = &state->hdl;
1355 if (state->hdl.error) {
1356 int err = state->hdl.error;
1357
1358 v4l2_ctrl_handler_free(&state->hdl);
1359 return err;
1360 }
1361 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
1362 if (err)
1363 v4l2_ctrl_handler_free(&state->hdl);
1364 else
1365 cx18_av_init(cx);
1366 return err;
1367}
1368