Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[linux-2.6] / drivers / media / video / cx18 / cx18-av-core.c
1 /*
2  *  cx18 ADEC audio functions
3  *
4  *  Derived from cx25840-core.c
5  *
6  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
7  *
8  *  This program is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU General Public License
10  *  as published by the Free Software Foundation; either version 2
11  *  of the License, or (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  *  02110-1301, USA.
22  */
23
24 #include "cx18-driver.h"
25
26 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
27 {
28         u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
29         u32 mask = 0xff;
30         int shift = (addr & 3) * 8;
31
32         x = (x & ~(mask << shift)) | ((u32)value << shift);
33         writel(x, cx->reg_mem + 0xc40000 + (addr & ~3));
34         return 0;
35 }
36
37 int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
38 {
39         writel(value, cx->reg_mem + 0xc40000 + addr);
40         return 0;
41 }
42
43 u8 cx18_av_read(struct cx18 *cx, u16 addr)
44 {
45         u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
46         int shift = (addr & 3) * 8;
47
48         return (x >> shift) & 0xff;
49 }
50
51 u32 cx18_av_read4(struct cx18 *cx, u16 addr)
52 {
53         return readl(cx->reg_mem + 0xc40000 + addr);
54 }
55
56 int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
57                    u8 or_value)
58 {
59         return cx18_av_write(cx, addr,
60                              (cx18_av_read(cx, addr) & and_mask) |
61                              or_value);
62 }
63
64 int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
65                    u32 or_value)
66 {
67         return cx18_av_write4(cx, addr,
68                              (cx18_av_read4(cx, addr) & and_mask) |
69                              or_value);
70 }
71
72 int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask)
73 {
74         int retval;
75         u32 saved_reg[8] = {0};
76
77         if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
78                 saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL);
79                 saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL);
80         }
81
82         if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
83                 saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1);
84                 saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC);
85         }
86
87         if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
88                 saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL);
89                 saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL);
90                 saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG);
91                 saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG);
92         }
93
94         retval = cx18_av_write(cx, addr, value);
95
96         if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
97                 cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]);
98                 cx18_av_write4(cx, CXADEC_AFE_CTRL,  saved_reg[1]);
99         }
100
101         if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
102                 cx18_av_write4(cx, CXADEC_PLL_CTRL1,    saved_reg[2]);
103                 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]);
104         }
105
106         if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
107                 cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL,    saved_reg[4]);
108                 cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL,     saved_reg[5]);
109                 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG,      saved_reg[6]);
110                 cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]);
111         }
112
113         return retval;
114 }
115
116 int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask,
117                            u8 or_value, int no_acfg_mask)
118 {
119         return cx18_av_write_no_acfg(cx, addr,
120                                      (cx18_av_read(cx, addr) & and_mask) |
121                                      or_value, no_acfg_mask);
122 }
123
124 /* ----------------------------------------------------------------------- */
125
126 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
127                                         enum cx18_av_audio_input aud_input);
128 static void log_audio_status(struct cx18 *cx);
129 static void log_video_status(struct cx18 *cx);
130
131 /* ----------------------------------------------------------------------- */
132
133 static void cx18_av_initialize(struct cx18 *cx)
134 {
135         u32 v;
136
137         cx18_av_loadfw(cx);
138         /* Stop 8051 code execution */
139         cx18_av_write4(cx, CXADEC_DL_CTL, 0x03000000);
140
141         /* initallize the PLL by toggling sleep bit */
142         v = cx18_av_read4(cx, CXADEC_HOST_REG1);
143         /* enable sleep mode */
144         cx18_av_write4(cx, CXADEC_HOST_REG1, v | 1);
145         /* disable sleep mode */
146         cx18_av_write4(cx, CXADEC_HOST_REG1, v & 0xfffe);
147
148         /* initialize DLLs */
149         v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
150         /* disable FLD */
151         cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
152         /* enable FLD */
153         cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
154
155         v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
156         /* disable FLD */
157         cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
158         /* enable FLD */
159         cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
160
161         /* set analog bias currents. Set Vreg to 1.20V. */
162         cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
163
164         v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
165         /* enable TUNE_FIL_RST */
166         cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v);
167         /* disable TUNE_FIL_RST */
168         cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v & 0xFFFFFFFE);
169
170         /* enable 656 output */
171         cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
172
173         /* video output drive strength */
174         cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
175
176         /* reset video */
177         cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
178         cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
179
180         /* set video to auto-detect */
181         /* Clear bits 11-12 to enable slow locking mode.  Set autodetect mode */
182         /* set the comb notch = 1 */
183         cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
184
185         /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
186         /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
187         cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
188
189         /* Set VGA_TRACK_RANGE to 0x20 */
190         cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
191
192         /* Enable VBI capture */
193         cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
194         /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
195
196         /* Set the video input.
197            The setting in MODE_CTRL gets lost when we do the above setup */
198         /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
199         /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
200
201         v = cx18_av_read4(cx, CXADEC_AFE_CTRL);
202         v &= 0xFFFBFFFF;            /* turn OFF bit 18 for droop_comp_ch1 */
203         v &= 0xFFFF7FFF;            /* turn OFF bit 9 for clamp_sel_ch1 */
204         v &= 0xFFFFFFFE;            /* turn OFF bit 0 for 12db_ch1 */
205         /* v |= 0x00000001;*/            /* turn ON bit 0 for 12db_ch1 */
206         cx18_av_write4(cx, CXADEC_AFE_CTRL, v);
207
208 /*      if(dwEnable && dw3DCombAvailable) { */
209 /*              CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
210 /*    } else { */
211 /*              CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
212 /*    } */
213         cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
214 }
215
216 /* ----------------------------------------------------------------------- */
217
218 static void input_change(struct cx18 *cx)
219 {
220         struct cx18_av_state *state = &cx->av_state;
221         v4l2_std_id std = state->std;
222
223         /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
224         if (std & V4L2_STD_SECAM)
225                 cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL);
226         else {
227                 cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL);
228                 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
229         }
230         cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0,
231                                 CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
232         cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60,
233                                 CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
234
235         if (std & V4L2_STD_525_60) {
236                 if (std == V4L2_STD_NTSC_M_JP) {
237                         /* Japan uses EIAJ audio standard */
238                         cx18_av_write(cx, 0x808, 0xf7);
239                         cx18_av_write(cx, 0x80b, 0x02);
240                 } else if (std == V4L2_STD_NTSC_M_KR) {
241                         /* South Korea uses A2 audio standard */
242                         cx18_av_write(cx, 0x808, 0xf8);
243                         cx18_av_write(cx, 0x80b, 0x03);
244                 } else {
245                         /* Others use the BTSC audio standard */
246                         cx18_av_write(cx, 0x808, 0xf6);
247                         cx18_av_write(cx, 0x80b, 0x01);
248                 }
249         } else if (std & V4L2_STD_PAL) {
250                 /* Follow tuner change procedure for PAL */
251                 cx18_av_write(cx, 0x808, 0xff);
252                 cx18_av_write(cx, 0x80b, 0x03);
253         } else if (std & V4L2_STD_SECAM) {
254                 /* Select autodetect for SECAM */
255                 cx18_av_write(cx, 0x808, 0xff);
256                 cx18_av_write(cx, 0x80b, 0x03);
257         }
258
259         if (cx18_av_read(cx, 0x803) & 0x10) {
260                 /* restart audio decoder microcontroller */
261                 cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
262                 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
263         }
264 }
265
266 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
267                                         enum cx18_av_audio_input aud_input)
268 {
269         struct cx18_av_state *state = &cx->av_state;
270         u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
271                            vid_input <= CX18_AV_COMPOSITE8);
272         u8 reg;
273
274         CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
275                         vid_input, aud_input);
276
277         if (is_composite) {
278                 reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
279         } else {
280                 int luma = vid_input & 0xf0;
281                 int chroma = vid_input & 0xf00;
282
283                 if ((vid_input & ~0xff0) ||
284                     luma < CX18_AV_SVIDEO_LUMA1 ||
285                     luma > CX18_AV_SVIDEO_LUMA8 ||
286                     chroma < CX18_AV_SVIDEO_CHROMA4 ||
287                     chroma > CX18_AV_SVIDEO_CHROMA8) {
288                         CX18_ERR("0x%04x is not a valid video input!\n",
289                                         vid_input);
290                         return -EINVAL;
291                 }
292                 reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
293                 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
294                         reg &= 0x3f;
295                         reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
296                 } else {
297                         reg &= 0xcf;
298                         reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
299                 }
300         }
301
302         switch (aud_input) {
303         case CX18_AV_AUDIO_SERIAL:
304                 /* do nothing, use serial audio input */
305                 break;
306         case CX18_AV_AUDIO4: reg &= ~0x30; break;
307         case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
308         case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
309         case CX18_AV_AUDIO7: reg &= ~0xc0; break;
310         case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
311
312         default:
313                 CX18_ERR("0x%04x is not a valid audio input!\n", aud_input);
314                 return -EINVAL;
315         }
316
317         cx18_av_write(cx, 0x103, reg);
318         /* Set INPUT_MODE to Composite (0) or S-Video (1) */
319         cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02,
320                                 CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
321         /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
322         cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
323         /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
324         if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
325                 cx18_av_and_or(cx, 0x102, ~0x4, 4);
326         else
327                 cx18_av_and_or(cx, 0x102, ~0x4, 0);
328         /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
329
330         state->vid_input = vid_input;
331         state->aud_input = aud_input;
332         cx18_av_audio_set_path(cx);
333         input_change(cx);
334         return 0;
335 }
336
337 /* ----------------------------------------------------------------------- */
338
339 static int set_v4lstd(struct cx18 *cx)
340 {
341         struct cx18_av_state *state = &cx->av_state;
342         u8 fmt = 0;     /* zero is autodetect */
343         u8 pal_m = 0;
344
345         /* First tests should be against specific std */
346         if (state->std == V4L2_STD_NTSC_M_JP) {
347                 fmt = 0x2;
348         } else if (state->std == V4L2_STD_NTSC_443) {
349                 fmt = 0x3;
350         } else if (state->std == V4L2_STD_PAL_M) {
351                 pal_m = 1;
352                 fmt = 0x5;
353         } else if (state->std == V4L2_STD_PAL_N) {
354                 fmt = 0x6;
355         } else if (state->std == V4L2_STD_PAL_Nc) {
356                 fmt = 0x7;
357         } else if (state->std == V4L2_STD_PAL_60) {
358                 fmt = 0x8;
359         } else {
360                 /* Then, test against generic ones */
361                 if (state->std & V4L2_STD_NTSC)
362                         fmt = 0x1;
363                 else if (state->std & V4L2_STD_PAL)
364                         fmt = 0x4;
365                 else if (state->std & V4L2_STD_SECAM)
366                         fmt = 0xc;
367         }
368
369         CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt);
370
371         /* Follow step 9 of section 3.16 in the cx18_av datasheet.
372            Without this PAL may display a vertical ghosting effect.
373            This happens for example with the Yuan MPC622. */
374         if (fmt >= 4 && fmt < 8) {
375                 /* Set format to NTSC-M */
376                 cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE);
377                 /* Turn off LCOMB */
378                 cx18_av_and_or(cx, 0x47b, ~6, 0);
379         }
380         cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE);
381         cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL);
382         cx18_av_vbi_setup(cx);
383         input_change(cx);
384         return 0;
385 }
386
387 /* ----------------------------------------------------------------------- */
388
389 static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
390 {
391         switch (ctrl->id) {
392         case V4L2_CID_BRIGHTNESS:
393                 if (ctrl->value < 0 || ctrl->value > 255) {
394                         CX18_ERR("invalid brightness setting %d\n",
395                                     ctrl->value);
396                         return -ERANGE;
397                 }
398
399                 cx18_av_write(cx, 0x414, ctrl->value - 128);
400                 break;
401
402         case V4L2_CID_CONTRAST:
403                 if (ctrl->value < 0 || ctrl->value > 127) {
404                         CX18_ERR("invalid contrast setting %d\n",
405                                     ctrl->value);
406                         return -ERANGE;
407                 }
408
409                 cx18_av_write(cx, 0x415, ctrl->value << 1);
410                 break;
411
412         case V4L2_CID_SATURATION:
413                 if (ctrl->value < 0 || ctrl->value > 127) {
414                         CX18_ERR("invalid saturation setting %d\n",
415                                     ctrl->value);
416                         return -ERANGE;
417                 }
418
419                 cx18_av_write(cx, 0x420, ctrl->value << 1);
420                 cx18_av_write(cx, 0x421, ctrl->value << 1);
421                 break;
422
423         case V4L2_CID_HUE:
424                 if (ctrl->value < -127 || ctrl->value > 127) {
425                         CX18_ERR("invalid hue setting %d\n", ctrl->value);
426                         return -ERANGE;
427                 }
428
429                 cx18_av_write(cx, 0x422, ctrl->value);
430                 break;
431
432         case V4L2_CID_AUDIO_VOLUME:
433         case V4L2_CID_AUDIO_BASS:
434         case V4L2_CID_AUDIO_TREBLE:
435         case V4L2_CID_AUDIO_BALANCE:
436         case V4L2_CID_AUDIO_MUTE:
437                 return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
438
439         default:
440                 return -EINVAL;
441         }
442
443         return 0;
444 }
445
446 static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
447 {
448         switch (ctrl->id) {
449         case V4L2_CID_BRIGHTNESS:
450                 ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
451                 break;
452         case V4L2_CID_CONTRAST:
453                 ctrl->value = cx18_av_read(cx, 0x415) >> 1;
454                 break;
455         case V4L2_CID_SATURATION:
456                 ctrl->value = cx18_av_read(cx, 0x420) >> 1;
457                 break;
458         case V4L2_CID_HUE:
459                 ctrl->value = (s8)cx18_av_read(cx, 0x422);
460                 break;
461         case V4L2_CID_AUDIO_VOLUME:
462         case V4L2_CID_AUDIO_BASS:
463         case V4L2_CID_AUDIO_TREBLE:
464         case V4L2_CID_AUDIO_BALANCE:
465         case V4L2_CID_AUDIO_MUTE:
466                 return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
467         default:
468                 return -EINVAL;
469         }
470
471         return 0;
472 }
473
474 /* ----------------------------------------------------------------------- */
475
476 static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
477 {
478         switch (fmt->type) {
479         case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
480                 return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
481         default:
482                 return -EINVAL;
483         }
484
485         return 0;
486 }
487
488 static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
489 {
490         struct cx18_av_state *state = &cx->av_state;
491         struct v4l2_pix_format *pix;
492         int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
493         int is_50Hz = !(state->std & V4L2_STD_525_60);
494
495         switch (fmt->type) {
496         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
497                 pix = &(fmt->fmt.pix);
498
499                 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
500                 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
501
502                 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
503                 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
504
505                 Vlines = pix->height + (is_50Hz ? 4 : 7);
506
507                 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
508                     (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
509                         CX18_ERR("%dx%d is not a valid size!\n",
510                                     pix->width, pix->height);
511                         return -ERANGE;
512                 }
513
514                 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
515                 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
516                 VSC &= 0x1fff;
517
518                 if (pix->width >= 385)
519                         filter = 0;
520                 else if (pix->width > 192)
521                         filter = 1;
522                 else if (pix->width > 96)
523                         filter = 2;
524                 else
525                         filter = 3;
526
527                 CX18_DEBUG_INFO("decoder set size %dx%d -> scale  %ux%u\n",
528                             pix->width, pix->height, HSC, VSC);
529
530                 /* HSCALE=HSC */
531                 cx18_av_write(cx, 0x418, HSC & 0xff);
532                 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
533                 cx18_av_write(cx, 0x41a, HSC >> 16);
534                 /* VSCALE=VSC */
535                 cx18_av_write(cx, 0x41c, VSC & 0xff);
536                 cx18_av_write(cx, 0x41d, VSC >> 8);
537                 /* VS_INTRLACE=1 VFILT=filter */
538                 cx18_av_write(cx, 0x41e, 0x8 | filter);
539                 break;
540
541         case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
542                 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
543
544         case V4L2_BUF_TYPE_VBI_CAPTURE:
545                 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
546
547         default:
548                 return -EINVAL;
549         }
550
551         return 0;
552 }
553
554 /* ----------------------------------------------------------------------- */
555
556 int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
557 {
558         struct cx18_av_state *state = &cx->av_state;
559         struct v4l2_tuner *vt = arg;
560         struct v4l2_routing *route = arg;
561
562         /* ignore these commands */
563         switch (cmd) {
564         case TUNER_SET_TYPE_ADDR:
565                 return 0;
566         }
567
568         if (!state->is_initialized) {
569                 CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
570                 /* initialize on first use */
571                 state->is_initialized = 1;
572                 cx18_av_initialize(cx);
573         }
574
575         switch (cmd) {
576         case VIDIOC_INT_DECODE_VBI_LINE:
577                 return cx18_av_vbi(cx, cmd, arg);
578
579         case VIDIOC_INT_AUDIO_CLOCK_FREQ:
580                 return cx18_av_audio(cx, cmd, arg);
581
582         case VIDIOC_STREAMON:
583                 CX18_DEBUG_INFO("enable output\n");
584                 cx18_av_write(cx, 0x115, 0x8c);
585                 cx18_av_write(cx, 0x116, 0x07);
586                 break;
587
588         case VIDIOC_STREAMOFF:
589                 CX18_DEBUG_INFO("disable output\n");
590                 cx18_av_write(cx, 0x115, 0x00);
591                 cx18_av_write(cx, 0x116, 0x00);
592                 break;
593
594         case VIDIOC_LOG_STATUS:
595                 log_video_status(cx);
596                 log_audio_status(cx);
597                 break;
598
599         case VIDIOC_G_CTRL:
600                 return get_v4lctrl(cx, (struct v4l2_control *)arg);
601
602         case VIDIOC_S_CTRL:
603                 return set_v4lctrl(cx, (struct v4l2_control *)arg);
604
605         case VIDIOC_QUERYCTRL:
606         {
607                 struct v4l2_queryctrl *qc = arg;
608
609                 switch (qc->id) {
610                 case V4L2_CID_BRIGHTNESS:
611                 case V4L2_CID_CONTRAST:
612                 case V4L2_CID_SATURATION:
613                 case V4L2_CID_HUE:
614                         return v4l2_ctrl_query_fill_std(qc);
615                 default:
616                         break;
617                 }
618
619                 switch (qc->id) {
620                 case V4L2_CID_AUDIO_VOLUME:
621                 case V4L2_CID_AUDIO_MUTE:
622                 case V4L2_CID_AUDIO_BALANCE:
623                 case V4L2_CID_AUDIO_BASS:
624                 case V4L2_CID_AUDIO_TREBLE:
625                         return v4l2_ctrl_query_fill_std(qc);
626                 default:
627                         return -EINVAL;
628                 }
629                 return -EINVAL;
630         }
631
632         case VIDIOC_G_STD:
633                 *(v4l2_std_id *)arg = state->std;
634                 break;
635
636         case VIDIOC_S_STD:
637                 if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
638                         return 0;
639                 state->radio = 0;
640                 state->std = *(v4l2_std_id *)arg;
641                 return set_v4lstd(cx);
642
643         case AUDC_SET_RADIO:
644                 state->radio = 1;
645                 break;
646
647         case VIDIOC_INT_G_VIDEO_ROUTING:
648                 route->input = state->vid_input;
649                 route->output = 0;
650                 break;
651
652         case VIDIOC_INT_S_VIDEO_ROUTING:
653                 return set_input(cx, route->input, state->aud_input);
654
655         case VIDIOC_INT_G_AUDIO_ROUTING:
656                 route->input = state->aud_input;
657                 route->output = 0;
658                 break;
659
660         case VIDIOC_INT_S_AUDIO_ROUTING:
661                 return set_input(cx, state->vid_input, route->input);
662
663         case VIDIOC_S_FREQUENCY:
664                 input_change(cx);
665                 break;
666
667         case VIDIOC_G_TUNER:
668         {
669                 u8 vpres = cx18_av_read(cx, 0x40e) & 0x20;
670                 u8 mode;
671                 int val = 0;
672
673                 if (state->radio)
674                         break;
675
676                 vt->signal = vpres ? 0xffff : 0x0;
677
678                 vt->capability |=
679                     V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
680                     V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
681
682                 mode = cx18_av_read(cx, 0x804);
683
684                 /* get rxsubchans and audmode */
685                 if ((mode & 0xf) == 1)
686                         val |= V4L2_TUNER_SUB_STEREO;
687                 else
688                         val |= V4L2_TUNER_SUB_MONO;
689
690                 if (mode == 2 || mode == 4)
691                         val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
692
693                 if (mode & 0x10)
694                         val |= V4L2_TUNER_SUB_SAP;
695
696                 vt->rxsubchans = val;
697                 vt->audmode = state->audmode;
698                 break;
699         }
700
701         case VIDIOC_S_TUNER:
702                 if (state->radio)
703                         break;
704
705                 switch (vt->audmode) {
706                 case V4L2_TUNER_MODE_MONO:
707                         /* mono      -> mono
708                            stereo    -> mono
709                            bilingual -> lang1 */
710                         cx18_av_and_or(cx, 0x809, ~0xf, 0x00);
711                         break;
712                 case V4L2_TUNER_MODE_STEREO:
713                 case V4L2_TUNER_MODE_LANG1:
714                         /* mono      -> mono
715                            stereo    -> stereo
716                            bilingual -> lang1 */
717                         cx18_av_and_or(cx, 0x809, ~0xf, 0x04);
718                         break;
719                 case V4L2_TUNER_MODE_LANG1_LANG2:
720                         /* mono      -> mono
721                            stereo    -> stereo
722                            bilingual -> lang1/lang2 */
723                         cx18_av_and_or(cx, 0x809, ~0xf, 0x07);
724                         break;
725                 case V4L2_TUNER_MODE_LANG2:
726                         /* mono      -> mono
727                            stereo    -> stereo
728                            bilingual -> lang2 */
729                         cx18_av_and_or(cx, 0x809, ~0xf, 0x01);
730                         break;
731                 default:
732                         return -EINVAL;
733                 }
734                 state->audmode = vt->audmode;
735                 break;
736
737         case VIDIOC_G_FMT:
738                 return get_v4lfmt(cx, (struct v4l2_format *)arg);
739
740         case VIDIOC_S_FMT:
741                 return set_v4lfmt(cx, (struct v4l2_format *)arg);
742
743         case VIDIOC_INT_RESET:
744                 cx18_av_initialize(cx);
745                 break;
746
747         default:
748                 return -EINVAL;
749         }
750
751         return 0;
752 }
753
754 /* ----------------------------------------------------------------------- */
755
756 /* ----------------------------------------------------------------------- */
757
758 static void log_video_status(struct cx18 *cx)
759 {
760         static const char *const fmt_strs[] = {
761                 "0x0",
762                 "NTSC-M", "NTSC-J", "NTSC-4.43",
763                 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
764                 "0x9", "0xA", "0xB",
765                 "SECAM",
766                 "0xD", "0xE", "0xF"
767         };
768
769         struct cx18_av_state *state = &cx->av_state;
770         u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
771         u8 gen_stat1 = cx18_av_read(cx, 0x40d);
772         u8 gen_stat2 = cx18_av_read(cx, 0x40e);
773         int vid_input = state->vid_input;
774
775         CX18_INFO("Video signal:              %spresent\n",
776                     (gen_stat2 & 0x20) ? "" : "not ");
777         CX18_INFO("Detected format:           %s\n",
778                     fmt_strs[gen_stat1 & 0xf]);
779
780         CX18_INFO("Specified standard:        %s\n",
781                     vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
782
783         if (vid_input >= CX18_AV_COMPOSITE1 &&
784             vid_input <= CX18_AV_COMPOSITE8) {
785                 CX18_INFO("Specified video input:     Composite %d\n",
786                         vid_input - CX18_AV_COMPOSITE1 + 1);
787         } else {
788                 CX18_INFO("Specified video input:     S-Video (Luma In%d, Chroma In%d)\n",
789                         (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
790         }
791
792         CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq);
793 }
794
795 /* ----------------------------------------------------------------------- */
796
797 static void log_audio_status(struct cx18 *cx)
798 {
799         struct cx18_av_state *state = &cx->av_state;
800         u8 download_ctl = cx18_av_read(cx, 0x803);
801         u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
802         u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
803         u8 audio_config = cx18_av_read(cx, 0x808);
804         u8 pref_mode = cx18_av_read(cx, 0x809);
805         u8 afc0 = cx18_av_read(cx, 0x80b);
806         u8 mute_ctl = cx18_av_read(cx, 0x8d3);
807         int aud_input = state->aud_input;
808         char *p;
809
810         switch (mod_det_stat0) {
811         case 0x00: p = "mono"; break;
812         case 0x01: p = "stereo"; break;
813         case 0x02: p = "dual"; break;
814         case 0x04: p = "tri"; break;
815         case 0x10: p = "mono with SAP"; break;
816         case 0x11: p = "stereo with SAP"; break;
817         case 0x12: p = "dual with SAP"; break;
818         case 0x14: p = "tri with SAP"; break;
819         case 0xfe: p = "forced mode"; break;
820         default: p = "not defined"; break;
821         }
822         CX18_INFO("Detected audio mode:       %s\n", p);
823
824         switch (mod_det_stat1) {
825         case 0x00: p = "not defined"; break;
826         case 0x01: p = "EIAJ"; break;
827         case 0x02: p = "A2-M"; break;
828         case 0x03: p = "A2-BG"; break;
829         case 0x04: p = "A2-DK1"; break;
830         case 0x05: p = "A2-DK2"; break;
831         case 0x06: p = "A2-DK3"; break;
832         case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
833         case 0x08: p = "AM-L"; break;
834         case 0x09: p = "NICAM-BG"; break;
835         case 0x0a: p = "NICAM-DK"; break;
836         case 0x0b: p = "NICAM-I"; break;
837         case 0x0c: p = "NICAM-L"; break;
838         case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
839         case 0x0e: p = "IF FM Radio"; break;
840         case 0x0f: p = "BTSC"; break;
841         case 0x10: p = "detected chrominance"; break;
842         case 0xfd: p = "unknown audio standard"; break;
843         case 0xfe: p = "forced audio standard"; break;
844         case 0xff: p = "no detected audio standard"; break;
845         default: p = "not defined"; break;
846         }
847         CX18_INFO("Detected audio standard:   %s\n", p);
848         CX18_INFO("Audio muted:               %s\n",
849                     (mute_ctl & 0x2) ? "yes" : "no");
850         CX18_INFO("Audio microcontroller:     %s\n",
851                     (download_ctl & 0x10) ? "running" : "stopped");
852
853         switch (audio_config >> 4) {
854         case 0x00: p = "undefined"; break;
855         case 0x01: p = "BTSC"; break;
856         case 0x02: p = "EIAJ"; break;
857         case 0x03: p = "A2-M"; break;
858         case 0x04: p = "A2-BG"; break;
859         case 0x05: p = "A2-DK1"; break;
860         case 0x06: p = "A2-DK2"; break;
861         case 0x07: p = "A2-DK3"; break;
862         case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
863         case 0x09: p = "AM-L"; break;
864         case 0x0a: p = "NICAM-BG"; break;
865         case 0x0b: p = "NICAM-DK"; break;
866         case 0x0c: p = "NICAM-I"; break;
867         case 0x0d: p = "NICAM-L"; break;
868         case 0x0e: p = "FM radio"; break;
869         case 0x0f: p = "automatic detection"; break;
870         default: p = "undefined"; break;
871         }
872         CX18_INFO("Configured audio standard: %s\n", p);
873
874         if ((audio_config >> 4) < 0xF) {
875                 switch (audio_config & 0xF) {
876                 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
877                 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
878                 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
879                 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
880                 case 0x04: p = "STEREO"; break;
881                 case 0x05: p = "DUAL1 (AC)"; break;
882                 case 0x06: p = "DUAL2 (BC)"; break;
883                 case 0x07: p = "DUAL3 (AB)"; break;
884                 default: p = "undefined";
885                 }
886                 CX18_INFO("Configured audio mode:     %s\n", p);
887         } else {
888                 switch (audio_config & 0xF) {
889                 case 0x00: p = "BG"; break;
890                 case 0x01: p = "DK1"; break;
891                 case 0x02: p = "DK2"; break;
892                 case 0x03: p = "DK3"; break;
893                 case 0x04: p = "I"; break;
894                 case 0x05: p = "L"; break;
895                 case 0x06: p = "BTSC"; break;
896                 case 0x07: p = "EIAJ"; break;
897                 case 0x08: p = "A2-M"; break;
898                 case 0x09: p = "FM Radio (4.5 MHz)"; break;
899                 case 0x0a: p = "FM Radio (5.5 MHz)"; break;
900                 case 0x0b: p = "S-Video"; break;
901                 case 0x0f: p = "automatic standard and mode detection"; break;
902                 default: p = "undefined"; break;
903                 }
904                 CX18_INFO("Configured audio system:   %s\n", p);
905         }
906
907         if (aud_input)
908                 CX18_INFO("Specified audio input:     Tuner (In%d)\n",
909                                 aud_input);
910         else
911                 CX18_INFO("Specified audio input:     External\n");
912
913         switch (pref_mode & 0xf) {
914         case 0: p = "mono/language A"; break;
915         case 1: p = "language B"; break;
916         case 2: p = "language C"; break;
917         case 3: p = "analog fallback"; break;
918         case 4: p = "stereo"; break;
919         case 5: p = "language AC"; break;
920         case 6: p = "language BC"; break;
921         case 7: p = "language AB"; break;
922         default: p = "undefined"; break;
923         }
924         CX18_INFO("Preferred audio mode:      %s\n", p);
925
926         if ((audio_config & 0xf) == 0xf) {
927                 switch ((afc0 >> 3) & 0x1) {
928                 case 0: p = "system DK"; break;
929                 case 1: p = "system L"; break;
930                 }
931                 CX18_INFO("Selected 65 MHz format:    %s\n", p);
932
933                 switch (afc0 & 0x7) {
934                 case 0: p = "Chroma"; break;
935                 case 1: p = "BTSC"; break;
936                 case 2: p = "EIAJ"; break;
937                 case 3: p = "A2-M"; break;
938                 case 4: p = "autodetect"; break;
939                 default: p = "undefined"; break;
940                 }
941                 CX18_INFO("Selected 45 MHz format:    %s\n", p);
942         }
943 }