Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
0003 //
0004 // Copyright (c) 2007 Mauro Carvalho Chehab <mchehab@kernel.org>
0005 
0006 #include <linux/module.h>
0007 #include <linux/kernel.h>
0008 #include "tm6000.h"
0009 #include "tm6000-regs.h"
0010 
0011 static unsigned int tm6010_a_mode;
0012 module_param(tm6010_a_mode, int, 0644);
0013 MODULE_PARM_DESC(tm6010_a_mode, "set tm6010 sif audio mode");
0014 
0015 struct tm6000_reg_settings {
0016     unsigned char req;
0017     unsigned char reg;
0018     unsigned char value;
0019 };
0020 
0021 
0022 struct tm6000_std_settings {
0023     v4l2_std_id id;
0024     struct tm6000_reg_settings *common;
0025 };
0026 
0027 static struct tm6000_reg_settings composite_pal_m[] = {
0028     { TM6010_REQ07_R3F_RESET, 0x01 },
0029     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04 },
0030     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0031     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0032     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
0033     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0034     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
0035     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
0036     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
0037     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
0038     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0039     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0040     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0041     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0042     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
0043     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20 },
0044     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
0045     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
0046     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0047     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
0048     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0049     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
0050     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0051     { TM6010_REQ07_R3F_RESET, 0x00 },
0052     { 0, 0, 0 }
0053 };
0054 
0055 static struct tm6000_reg_settings composite_pal_nc[] = {
0056     { TM6010_REQ07_R3F_RESET, 0x01 },
0057     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36 },
0058     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0059     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0060     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
0061     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0062     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
0063     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
0064     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
0065     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
0066     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0067     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0068     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0069     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0070     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
0071     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
0072     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
0073     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
0074     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0075     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
0076     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0077     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
0078     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0079     { TM6010_REQ07_R3F_RESET, 0x00 },
0080     { 0, 0, 0 }
0081 };
0082 
0083 static struct tm6000_reg_settings composite_pal[] = {
0084     { TM6010_REQ07_R3F_RESET, 0x01 },
0085     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32 },
0086     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0087     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0088     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
0089     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0090     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
0091     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
0092     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
0093     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
0094     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0095     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0096     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0097     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0098     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
0099     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
0100     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
0101     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
0102     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0103     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
0104     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0105     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
0106     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0107     { TM6010_REQ07_R3F_RESET, 0x00 },
0108     { 0, 0, 0 }
0109 };
0110 
0111 static struct tm6000_reg_settings composite_secam[] = {
0112     { TM6010_REQ07_R3F_RESET, 0x01 },
0113     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38 },
0114     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0115     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0116     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
0117     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0118     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
0119     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
0120     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
0121     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
0122     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0123     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0124     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0125     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0126     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
0127     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
0128     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
0129     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
0130     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
0131     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
0132     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
0133     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0134     { TM6010_REQ07_R3F_RESET, 0x00 },
0135     { 0, 0, 0 }
0136 };
0137 
0138 static struct tm6000_reg_settings composite_ntsc[] = {
0139     { TM6010_REQ07_R3F_RESET, 0x01 },
0140     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
0141     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
0142     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0143     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
0144     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0145     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
0146     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
0147     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
0148     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
0149     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0150     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0151     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0152     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0153     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
0154     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
0155     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
0156     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
0157     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0158     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
0159     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0160     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
0161     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0162     { TM6010_REQ07_R3F_RESET, 0x00 },
0163     { 0, 0, 0 }
0164 };
0165 
0166 static struct tm6000_std_settings composite_stds[] = {
0167     { .id = V4L2_STD_PAL_M, .common = composite_pal_m, },
0168     { .id = V4L2_STD_PAL_Nc, .common = composite_pal_nc, },
0169     { .id = V4L2_STD_PAL, .common = composite_pal, },
0170     { .id = V4L2_STD_SECAM, .common = composite_secam, },
0171     { .id = V4L2_STD_NTSC, .common = composite_ntsc, },
0172 };
0173 
0174 static struct tm6000_reg_settings svideo_pal_m[] = {
0175     { TM6010_REQ07_R3F_RESET, 0x01 },
0176     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05 },
0177     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0178     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0179     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
0180     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0181     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
0182     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
0183     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
0184     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
0185     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0186     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0187     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0188     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0189     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
0190     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
0191     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
0192     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
0193     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0194     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
0195     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0196     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
0197     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0198     { TM6010_REQ07_R3F_RESET, 0x00 },
0199     { 0, 0, 0 }
0200 };
0201 
0202 static struct tm6000_reg_settings svideo_pal_nc[] = {
0203     { TM6010_REQ07_R3F_RESET, 0x01 },
0204     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37 },
0205     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0206     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0207     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
0208     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0209     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
0210     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
0211     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
0212     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
0213     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0214     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0215     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0216     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0217     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
0218     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
0219     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
0220     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
0221     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0222     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
0223     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0224     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
0225     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0226     { TM6010_REQ07_R3F_RESET, 0x00 },
0227     { 0, 0, 0 }
0228 };
0229 
0230 static struct tm6000_reg_settings svideo_pal[] = {
0231     { TM6010_REQ07_R3F_RESET, 0x01 },
0232     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33 },
0233     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0234     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0235     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
0236     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
0237     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
0238     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
0239     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
0240     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
0241     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0242     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0243     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0244     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0245     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
0246     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
0247     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
0248     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
0249     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0250     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
0251     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0252     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
0253     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0254     { TM6010_REQ07_R3F_RESET, 0x00 },
0255     { 0, 0, 0 }
0256 };
0257 
0258 static struct tm6000_reg_settings svideo_secam[] = {
0259     { TM6010_REQ07_R3F_RESET, 0x01 },
0260     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39 },
0261     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
0262     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0263     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
0264     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
0265     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
0266     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
0267     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
0268     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
0269     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0270     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0271     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0272     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0273     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
0274     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
0275     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
0276     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
0277     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
0278     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
0279     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
0280     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0281     { TM6010_REQ07_R3F_RESET, 0x00 },
0282     { 0, 0, 0 }
0283 };
0284 
0285 static struct tm6000_reg_settings svideo_ntsc[] = {
0286     { TM6010_REQ07_R3F_RESET, 0x01 },
0287     { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01 },
0288     { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
0289     { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
0290     { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
0291     { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
0292     { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b },
0293     { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
0294     { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
0295     { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
0296     { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
0297     { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
0298     { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
0299     { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
0300     { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
0301     { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
0302     { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
0303     { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
0304     { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
0305     { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
0306     { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
0307     { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
0308     { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
0309     { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
0310     { TM6010_REQ07_R3F_RESET, 0x00 },
0311     { 0, 0, 0 }
0312 };
0313 
0314 static struct tm6000_std_settings svideo_stds[] = {
0315     { .id = V4L2_STD_PAL_M, .common = svideo_pal_m, },
0316     { .id = V4L2_STD_PAL_Nc, .common = svideo_pal_nc, },
0317     { .id = V4L2_STD_PAL, .common = svideo_pal, },
0318     { .id = V4L2_STD_SECAM, .common = svideo_secam, },
0319     { .id = V4L2_STD_NTSC, .common = svideo_ntsc, },
0320 };
0321 
0322 static int tm6000_set_audio_std(struct tm6000_core *dev)
0323 {
0324     uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */
0325     uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */
0326     uint8_t areg_06 = 0x02; /* Auto de-emphasis, manual channel mode */
0327 
0328     if (dev->radio) {
0329         tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
0330         tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
0331         tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
0332         tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80);
0333         tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
0334         /* set mono or stereo */
0335         if (dev->amode == V4L2_TUNER_MODE_MONO)
0336             tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
0337         else if (dev->amode == V4L2_TUNER_MODE_STEREO)
0338             tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x02);
0339         tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
0340         tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a);
0341         tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40);
0342         tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
0343         tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
0344         tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
0345         tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0xff);
0346         return 0;
0347     }
0348 
0349     /*
0350      * STD/MN shouldn't be affected by tm6010_a_mode, as there's just one
0351      * audio standard for each V4L2_STD type.
0352      */
0353     if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_KR) {
0354         areg_05 |= 0x04;
0355     } else if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_JP) {
0356         areg_05 |= 0x43;
0357     } else if (dev->norm & V4L2_STD_MN) {
0358         areg_05 |= 0x22;
0359     } else switch (tm6010_a_mode) {
0360     /* auto */
0361     case 0:
0362         if ((dev->norm & V4L2_STD_SECAM) == V4L2_STD_SECAM_L)
0363             areg_05 |= 0x00;
0364         else    /* Other PAL/SECAM standards */
0365             areg_05 |= 0x10;
0366         break;
0367     /* A2 */
0368     case 1:
0369         if (dev->norm & V4L2_STD_DK)
0370             areg_05 = 0x09;
0371         else
0372             areg_05 = 0x05;
0373         break;
0374     /* NICAM */
0375     case 2:
0376         if (dev->norm & V4L2_STD_DK) {
0377             areg_05 = 0x06;
0378         } else if (dev->norm & V4L2_STD_PAL_I) {
0379             areg_05 = 0x08;
0380         } else if (dev->norm & V4L2_STD_SECAM_L) {
0381             areg_05 = 0x0a;
0382             areg_02 = 0x02;
0383         } else {
0384             areg_05 = 0x07;
0385         }
0386         break;
0387     /* other */
0388     case 3:
0389         if (dev->norm & V4L2_STD_DK) {
0390             areg_05 = 0x0b;
0391         } else {
0392             areg_05 = 0x02;
0393         }
0394         break;
0395     }
0396 
0397     tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
0398     tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02);
0399     tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
0400     tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0);
0401     tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, areg_05);
0402     tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, areg_06);
0403     tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00);
0404     tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00);
0405     tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x08);
0406     tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91);
0407     tm6000_set_reg(dev, TM6010_REQ08_R0B_A_ASD_THRES1, 0x20);
0408     tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x12);
0409     tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x20);
0410     tm6000_set_reg(dev, TM6010_REQ08_R0E_A_MONO_THRES1, 0xf0);
0411     tm6000_set_reg(dev, TM6010_REQ08_R0F_A_MONO_THRES2, 0x80);
0412     tm6000_set_reg(dev, TM6010_REQ08_R10_A_MUTE_THRES1, 0xc0);
0413     tm6000_set_reg(dev, TM6010_REQ08_R11_A_MUTE_THRES2, 0x80);
0414     tm6000_set_reg(dev, TM6010_REQ08_R12_A_AGC_U, 0x12);
0415     tm6000_set_reg(dev, TM6010_REQ08_R13_A_AGC_ERR_T, 0xfe);
0416     tm6000_set_reg(dev, TM6010_REQ08_R14_A_AGC_GAIN_INIT, 0x20);
0417     tm6000_set_reg(dev, TM6010_REQ08_R15_A_AGC_STEP_THR, 0x14);
0418     tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe);
0419     tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01);
0420     tm6000_set_reg(dev, TM6010_REQ08_R18_A_TR_CTRL, 0xa0);
0421     tm6000_set_reg(dev, TM6010_REQ08_R19_A_FH_2FH_GAIN, 0x32);
0422     tm6000_set_reg(dev, TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64);
0423     tm6000_set_reg(dev, TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20);
0424     tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1c, 0x00);
0425     tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1d, 0x00);
0426     tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
0427     tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00);
0428     tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00);
0429     tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
0430 
0431     return 0;
0432 }
0433 
0434 void tm6000_get_std_res(struct tm6000_core *dev)
0435 {
0436     /* Currently, those are the only supported resoltions */
0437     if (dev->norm & V4L2_STD_525_60)
0438         dev->height = 480;
0439     else
0440         dev->height = 576;
0441 
0442     dev->width = 720;
0443 }
0444 
0445 static int tm6000_load_std(struct tm6000_core *dev, struct tm6000_reg_settings *set)
0446 {
0447     int i, rc;
0448 
0449     /* Load board's initialization table */
0450     for (i = 0; set[i].req; i++) {
0451         rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value);
0452         if (rc < 0) {
0453             printk(KERN_ERR "Error %i while setting req %d, reg %d to value %d\n",
0454                    rc, set[i].req, set[i].reg, set[i].value);
0455             return rc;
0456         }
0457     }
0458 
0459     return 0;
0460 }
0461 
0462 int tm6000_set_standard(struct tm6000_core *dev)
0463 {
0464     struct tm6000_input *input;
0465     int i, rc = 0;
0466     u8 reg_07_fe = 0x8a;
0467     u8 reg_08_f1 = 0xfc;
0468     u8 reg_08_e2 = 0xf0;
0469     u8 reg_08_e6 = 0x0f;
0470 
0471     tm6000_get_std_res(dev);
0472 
0473     if (!dev->radio)
0474         input = &dev->vinput[dev->input];
0475     else
0476         input = &dev->rinput;
0477 
0478     if (dev->dev_type == TM6010) {
0479         switch (input->vmux) {
0480         case TM6000_VMUX_VIDEO_A:
0481             tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4);
0482             tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
0483             tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
0484             tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
0485             tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
0486             reg_07_fe |= 0x01;
0487             break;
0488         case TM6000_VMUX_VIDEO_B:
0489             tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8);
0490             tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
0491             tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
0492             tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
0493             tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
0494             reg_07_fe |= 0x01;
0495             break;
0496         case TM6000_VMUX_VIDEO_AB:
0497             tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc);
0498             tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8);
0499             reg_08_e6 = 0x00;
0500             tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2);
0501             tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0);
0502             tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
0503             tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe0);
0504             break;
0505         default:
0506             break;
0507         }
0508         switch (input->amux) {
0509         case TM6000_AMUX_ADC1:
0510             tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
0511                 0x00, 0x0f);
0512             /* Mux overflow workaround */
0513             tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
0514                 0x10, 0xf0);
0515             break;
0516         case TM6000_AMUX_ADC2:
0517             tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
0518                 0x08, 0x0f);
0519             /* Mux overflow workaround */
0520             tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
0521                 0x10, 0xf0);
0522             break;
0523         case TM6000_AMUX_SIF1:
0524             reg_08_e2 |= 0x02;
0525             reg_08_e6 = 0x08;
0526             reg_07_fe |= 0x40;
0527             reg_08_f1 |= 0x02;
0528             tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
0529             tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
0530                 0x02, 0x0f);
0531             /* Mux overflow workaround */
0532             tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
0533                 0x30, 0xf0);
0534             break;
0535         case TM6000_AMUX_SIF2:
0536             reg_08_e2 |= 0x02;
0537             reg_08_e6 = 0x08;
0538             reg_07_fe |= 0x40;
0539             reg_08_f1 |= 0x02;
0540             tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7);
0541             tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
0542                 0x02, 0x0f);
0543             /* Mux overflow workaround */
0544             tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
0545                 0x30, 0xf0);
0546             break;
0547         default:
0548             break;
0549         }
0550         tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, reg_08_e2);
0551         tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, reg_08_e6);
0552         tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, reg_08_f1);
0553         tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, reg_07_fe);
0554     } else {
0555         switch (input->vmux) {
0556         case TM6000_VMUX_VIDEO_A:
0557             tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
0558             tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
0559             tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
0560             tm6000_set_reg(dev,
0561                 REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
0562             break;
0563         case TM6000_VMUX_VIDEO_B:
0564             tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
0565             tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
0566             tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
0567             tm6000_set_reg(dev,
0568                 REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
0569             break;
0570         case TM6000_VMUX_VIDEO_AB:
0571             tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
0572             tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x10);
0573             tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00);
0574             tm6000_set_reg(dev,
0575                 REQ_03_SET_GET_MCU_PIN, input->v_gpio, 1);
0576             break;
0577         default:
0578             break;
0579         }
0580         switch (input->amux) {
0581         case TM6000_AMUX_ADC1:
0582             tm6000_set_reg_mask(dev,
0583                 TM6000_REQ07_REB_VADC_AADC_MODE, 0x00, 0x0f);
0584             break;
0585         case TM6000_AMUX_ADC2:
0586             tm6000_set_reg_mask(dev,
0587                 TM6000_REQ07_REB_VADC_AADC_MODE, 0x04, 0x0f);
0588             break;
0589         default:
0590             break;
0591         }
0592     }
0593     if (input->type == TM6000_INPUT_SVIDEO) {
0594         for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
0595             if (dev->norm & svideo_stds[i].id) {
0596                 rc = tm6000_load_std(dev, svideo_stds[i].common);
0597                 goto ret;
0598             }
0599         }
0600         return -EINVAL;
0601     } else {
0602         for (i = 0; i < ARRAY_SIZE(composite_stds); i++) {
0603             if (dev->norm & composite_stds[i].id) {
0604                 rc = tm6000_load_std(dev, composite_stds[i].common);
0605                 goto ret;
0606             }
0607         }
0608         return -EINVAL;
0609     }
0610 
0611 ret:
0612     if (rc < 0)
0613         return rc;
0614 
0615     if ((dev->dev_type == TM6010) &&
0616         ((input->amux == TM6000_AMUX_SIF1) ||
0617         (input->amux == TM6000_AMUX_SIF2)))
0618         tm6000_set_audio_std(dev);
0619 
0620     msleep(40);
0621 
0622     return 0;
0623 }