GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / media / usb / tm6000 / tm6000-stds.c
1 /*
2  *  tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3  *
4  *  Copyright (C) 2007 Mauro Carvalho Chehab
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation version 2
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  */
15
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include "tm6000.h"
19 #include "tm6000-regs.h"
20
21 static unsigned int tm6010_a_mode;
22 module_param(tm6010_a_mode, int, 0644);
23 MODULE_PARM_DESC(tm6010_a_mode, "set tm6010 sif audio mode");
24
25 struct tm6000_reg_settings {
26         unsigned char req;
27         unsigned char reg;
28         unsigned char value;
29 };
30
31
32 struct tm6000_std_settings {
33         v4l2_std_id id;
34         struct tm6000_reg_settings *common;
35 };
36
37 static struct tm6000_reg_settings composite_pal_m[] = {
38         { TM6010_REQ07_R3F_RESET, 0x01 },
39         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04 },
40         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
41         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
42         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
43         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
44         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
45         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
46         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
47         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
48         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
49         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
50         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
51         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
52         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
53         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20 },
54         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
55         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
56         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
57         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
58         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
59         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
60         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
61         { TM6010_REQ07_R3F_RESET, 0x00 },
62         { 0, 0, 0 }
63 };
64
65 static struct tm6000_reg_settings composite_pal_nc[] = {
66         { TM6010_REQ07_R3F_RESET, 0x01 },
67         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36 },
68         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
69         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
70         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
71         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
72         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
73         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
74         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
75         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
76         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
77         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
78         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
79         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
80         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
81         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
82         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
83         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
84         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
85         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
86         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
87         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
88         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
89         { TM6010_REQ07_R3F_RESET, 0x00 },
90         { 0, 0, 0 }
91 };
92
93 static struct tm6000_reg_settings composite_pal[] = {
94         { TM6010_REQ07_R3F_RESET, 0x01 },
95         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32 },
96         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
97         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
98         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
99         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
100         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
101         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
102         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
103         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
104         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
105         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
106         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
107         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
108         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
109         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
110         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
111         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
112         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
113         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
114         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
115         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
116         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
117         { TM6010_REQ07_R3F_RESET, 0x00 },
118         { 0, 0, 0 }
119 };
120
121 static struct tm6000_reg_settings composite_secam[] = {
122         { TM6010_REQ07_R3F_RESET, 0x01 },
123         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38 },
124         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
125         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
126         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
127         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
128         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
129         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
130         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
131         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
132         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
133         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
134         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
135         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
136         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
137         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
138         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
139         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
140         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
141         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
142         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
143         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
144         { TM6010_REQ07_R3F_RESET, 0x00 },
145         { 0, 0, 0 }
146 };
147
148 static struct tm6000_reg_settings composite_ntsc[] = {
149         { TM6010_REQ07_R3F_RESET, 0x01 },
150         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
151         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
152         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
153         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
154         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
155         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
156         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
157         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
158         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
159         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
160         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
161         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
162         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
163         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
164         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
165         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
166         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
167         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
168         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
169         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
170         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
171         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
172         { TM6010_REQ07_R3F_RESET, 0x00 },
173         { 0, 0, 0 }
174 };
175
176 static struct tm6000_std_settings composite_stds[] = {
177         { .id = V4L2_STD_PAL_M, .common = composite_pal_m, },
178         { .id = V4L2_STD_PAL_Nc, .common = composite_pal_nc, },
179         { .id = V4L2_STD_PAL, .common = composite_pal, },
180         { .id = V4L2_STD_SECAM, .common = composite_secam, },
181         { .id = V4L2_STD_NTSC, .common = composite_ntsc, },
182 };
183
184 static struct tm6000_reg_settings svideo_pal_m[] = {
185         { TM6010_REQ07_R3F_RESET, 0x01 },
186         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05 },
187         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
188         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
189         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
190         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
191         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
192         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
193         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
194         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
195         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
196         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
197         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
198         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
199         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
200         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
201         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
202         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
203         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
204         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
205         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
206         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
207         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
208         { TM6010_REQ07_R3F_RESET, 0x00 },
209         { 0, 0, 0 }
210 };
211
212 static struct tm6000_reg_settings svideo_pal_nc[] = {
213         { TM6010_REQ07_R3F_RESET, 0x01 },
214         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37 },
215         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
216         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
217         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
218         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
219         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
220         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
221         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
222         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
223         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
224         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
225         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
226         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
227         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
228         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
229         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
230         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
231         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
232         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
233         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
234         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
235         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
236         { TM6010_REQ07_R3F_RESET, 0x00 },
237         { 0, 0, 0 }
238 };
239
240 static struct tm6000_reg_settings svideo_pal[] = {
241         { TM6010_REQ07_R3F_RESET, 0x01 },
242         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33 },
243         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
244         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
245         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
246         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
247         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
248         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
249         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
250         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
251         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
252         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
253         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
254         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
255         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
256         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
257         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
258         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
259         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
260         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
261         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
262         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
263         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
264         { TM6010_REQ07_R3F_RESET, 0x00 },
265         { 0, 0, 0 }
266 };
267
268 static struct tm6000_reg_settings svideo_secam[] = {
269         { TM6010_REQ07_R3F_RESET, 0x01 },
270         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39 },
271         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
272         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
273         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
274         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
275         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
276         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
277         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
278         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
279         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
280         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
281         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
282         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
283         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
284         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
285         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
286         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
287         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
288         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
289         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
290         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
291         { TM6010_REQ07_R3F_RESET, 0x00 },
292         { 0, 0, 0 }
293 };
294
295 static struct tm6000_reg_settings svideo_ntsc[] = {
296         { TM6010_REQ07_R3F_RESET, 0x01 },
297         { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01 },
298         { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
299         { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
300         { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
301         { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
302         { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b },
303         { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
304         { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
305         { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
306         { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
307         { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
308         { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
309         { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
310         { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
311         { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
312         { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
313         { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
314         { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
315         { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
316         { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
317         { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
318         { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
319         { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
320         { TM6010_REQ07_R3F_RESET, 0x00 },
321         { 0, 0, 0 }
322 };
323
324 static struct tm6000_std_settings svideo_stds[] = {
325         { .id = V4L2_STD_PAL_M, .common = svideo_pal_m, },
326         { .id = V4L2_STD_PAL_Nc, .common = svideo_pal_nc, },
327         { .id = V4L2_STD_PAL, .common = svideo_pal, },
328         { .id = V4L2_STD_SECAM, .common = svideo_secam, },
329         { .id = V4L2_STD_NTSC, .common = svideo_ntsc, },
330 };
331
332 static int tm6000_set_audio_std(struct tm6000_core *dev)
333 {
334         uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */
335         uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */
336         uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */
337
338         if (dev->radio) {
339                 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
340                 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
341                 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
342                 tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80);
343                 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
344                 /* set mono or stereo */
345                 if (dev->amode == V4L2_TUNER_MODE_MONO)
346                         tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
347                 else if (dev->amode == V4L2_TUNER_MODE_STEREO)
348                         tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x02);
349                 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
350                 tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a);
351                 tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40);
352                 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
353                 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
354                 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
355                 tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0xff);
356                 return 0;
357         }
358
359         /*
360          * STD/MN shouldn't be affected by tm6010_a_mode, as there's just one
361          * audio standard for each V4L2_STD type.
362          */
363         if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_KR) {
364                 areg_05 |= 0x04;
365         } else if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_JP) {
366                 areg_05 |= 0x43;
367         } else if (dev->norm & V4L2_STD_MN) {
368                 areg_05 |= 0x22;
369         } else switch (tm6010_a_mode) {
370         /* auto */
371         case 0:
372                 if ((dev->norm & V4L2_STD_SECAM) == V4L2_STD_SECAM_L)
373                         areg_05 |= 0x00;
374                 else    /* Other PAL/SECAM standards */
375                         areg_05 |= 0x10;
376                 break;
377         /* A2 */
378         case 1:
379                 if (dev->norm & V4L2_STD_DK)
380                         areg_05 = 0x09;
381                 else
382                         areg_05 = 0x05;
383                 break;
384         /* NICAM */
385         case 2:
386                 if (dev->norm & V4L2_STD_DK) {
387                         areg_05 = 0x06;
388                 } else if (dev->norm & V4L2_STD_PAL_I) {
389                         areg_05 = 0x08;
390                 } else if (dev->norm & V4L2_STD_SECAM_L) {
391                         areg_05 = 0x0a;
392                         areg_02 = 0x02;
393                 } else {
394                         areg_05 = 0x07;
395                 }
396                 break;
397         /* other */
398         case 3:
399                 if (dev->norm & V4L2_STD_DK) {
400                         areg_05 = 0x0b;
401                 } else {
402                         areg_05 = 0x02;
403                 }
404                 break;
405         }
406
407         tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
408         tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02);
409         tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
410         tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0);
411         tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, areg_05);
412         tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, areg_06);
413         tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00);
414         tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00);
415         tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x08);
416         tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91);
417         tm6000_set_reg(dev, TM6010_REQ08_R0B_A_ASD_THRES1, 0x20);
418         tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x12);
419         tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x20);
420         tm6000_set_reg(dev, TM6010_REQ08_R0E_A_MONO_THRES1, 0xf0);
421         tm6000_set_reg(dev, TM6010_REQ08_R0F_A_MONO_THRES2, 0x80);
422         tm6000_set_reg(dev, TM6010_REQ08_R10_A_MUTE_THRES1, 0xc0);
423         tm6000_set_reg(dev, TM6010_REQ08_R11_A_MUTE_THRES2, 0x80);
424         tm6000_set_reg(dev, TM6010_REQ08_R12_A_AGC_U, 0x12);
425         tm6000_set_reg(dev, TM6010_REQ08_R13_A_AGC_ERR_T, 0xfe);
426         tm6000_set_reg(dev, TM6010_REQ08_R14_A_AGC_GAIN_INIT, 0x20);
427         tm6000_set_reg(dev, TM6010_REQ08_R15_A_AGC_STEP_THR, 0x14);
428         tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe);
429         tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01);
430         tm6000_set_reg(dev, TM6010_REQ08_R18_A_TR_CTRL, 0xa0);
431         tm6000_set_reg(dev, TM6010_REQ08_R19_A_FH_2FH_GAIN, 0x32);
432         tm6000_set_reg(dev, TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64);
433         tm6000_set_reg(dev, TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20);
434         tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1c, 0x00);
435         tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1d, 0x00);
436         tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
437         tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00);
438         tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00);
439         tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
440
441         return 0;
442 }
443
444 void tm6000_get_std_res(struct tm6000_core *dev)
445 {
446         /* Currently, those are the only supported resoltions */
447         if (dev->norm & V4L2_STD_525_60)
448                 dev->height = 480;
449         else
450                 dev->height = 576;
451
452         dev->width = 720;
453 }
454
455 static int tm6000_load_std(struct tm6000_core *dev, struct tm6000_reg_settings *set)
456 {
457         int i, rc;
458
459         /* Load board's initialization table */
460         for (i = 0; set[i].req; i++) {
461                 rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value);
462                 if (rc < 0) {
463                         printk(KERN_ERR "Error %i while setting req %d, reg %d to value %d\n",
464                                rc, set[i].req, set[i].reg, set[i].value);
465                         return rc;
466                 }
467         }
468
469         return 0;
470 }
471
472 int tm6000_set_standard(struct tm6000_core *dev)
473 {
474         struct tm6000_input *input;
475         int i, rc = 0;
476         u8 reg_07_fe = 0x8a;
477         u8 reg_08_f1 = 0xfc;
478         u8 reg_08_e2 = 0xf0;
479         u8 reg_08_e6 = 0x0f;
480
481         tm6000_get_std_res(dev);
482
483         if (!dev->radio)
484                 input = &dev->vinput[dev->input];
485         else
486                 input = &dev->rinput;
487
488         if (dev->dev_type == TM6010) {
489                 switch (input->vmux) {
490                 case TM6000_VMUX_VIDEO_A:
491                         tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4);
492                         tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
493                         tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
494                         tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
495                         tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
496                         reg_07_fe |= 0x01;
497                         break;
498                 case TM6000_VMUX_VIDEO_B:
499                         tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8);
500                         tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
501                         tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
502                         tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
503                         tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
504                         reg_07_fe |= 0x01;
505                         break;
506                 case TM6000_VMUX_VIDEO_AB:
507                         tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc);
508                         tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8);
509                         reg_08_e6 = 0x00;
510                         tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2);
511                         tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0);
512                         tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
513                         tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe0);
514                         break;
515                 default:
516                         break;
517                 }
518                 switch (input->amux) {
519                 case TM6000_AMUX_ADC1:
520                         tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
521                                 0x00, 0x0f);
522                         /* Mux overflow workaround */
523                         tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
524                                 0x10, 0xf0);
525                         break;
526                 case TM6000_AMUX_ADC2:
527                         tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
528                                 0x08, 0x0f);
529                         /* Mux overflow workaround */
530                         tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
531                                 0x10, 0xf0);
532                         break;
533                 case TM6000_AMUX_SIF1:
534                         reg_08_e2 |= 0x02;
535                         reg_08_e6 = 0x08;
536                         reg_07_fe |= 0x40;
537                         reg_08_f1 |= 0x02;
538                         tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
539                         tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
540                                 0x02, 0x0f);
541                         /* Mux overflow workaround */
542                         tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
543                                 0x30, 0xf0);
544                         break;
545                 case TM6000_AMUX_SIF2:
546                         reg_08_e2 |= 0x02;
547                         reg_08_e6 = 0x08;
548                         reg_07_fe |= 0x40;
549                         reg_08_f1 |= 0x02;
550                         tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7);
551                         tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
552                                 0x02, 0x0f);
553                         /* Mux overflow workaround */
554                         tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
555                                 0x30, 0xf0);
556                         break;
557                 default:
558                         break;
559                 }
560                 tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, reg_08_e2);
561                 tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, reg_08_e6);
562                 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, reg_08_f1);
563                 tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, reg_07_fe);
564         } else {
565                 switch (input->vmux) {
566                 case TM6000_VMUX_VIDEO_A:
567                         tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
568                         tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
569                         tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
570                         tm6000_set_reg(dev,
571                             REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
572                         break;
573                 case TM6000_VMUX_VIDEO_B:
574                         tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
575                         tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
576                         tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
577                         tm6000_set_reg(dev,
578                             REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
579                         break;
580                 case TM6000_VMUX_VIDEO_AB:
581                         tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
582                         tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x10);
583                         tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00);
584                         tm6000_set_reg(dev,
585                             REQ_03_SET_GET_MCU_PIN, input->v_gpio, 1);
586                         break;
587                 default:
588                         break;
589                 }
590                 switch (input->amux) {
591                 case TM6000_AMUX_ADC1:
592                         tm6000_set_reg_mask(dev,
593                                 TM6000_REQ07_REB_VADC_AADC_MODE, 0x00, 0x0f);
594                         break;
595                 case TM6000_AMUX_ADC2:
596                         tm6000_set_reg_mask(dev,
597                                 TM6000_REQ07_REB_VADC_AADC_MODE, 0x04, 0x0f);
598                         break;
599                 default:
600                         break;
601                 }
602         }
603         if (input->type == TM6000_INPUT_SVIDEO) {
604                 for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
605                         if (dev->norm & svideo_stds[i].id) {
606                                 rc = tm6000_load_std(dev, svideo_stds[i].common);
607                                 goto ret;
608                         }
609                 }
610                 return -EINVAL;
611         } else {
612                 for (i = 0; i < ARRAY_SIZE(composite_stds); i++) {
613                         if (dev->norm & composite_stds[i].id) {
614                                 rc = tm6000_load_std(dev, composite_stds[i].common);
615                                 goto ret;
616                         }
617                 }
618                 return -EINVAL;
619         }
620
621 ret:
622         if (rc < 0)
623                 return rc;
624
625         if ((dev->dev_type == TM6010) &&
626             ((input->amux == TM6000_AMUX_SIF1) ||
627             (input->amux == TM6000_AMUX_SIF2)))
628                 tm6000_set_audio_std(dev);
629
630         msleep(40);
631
632         return 0;
633 }