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