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