diff options
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-vbi.c')
| -rw-r--r-- | drivers/media/video/cx25840/cx25840-vbi.c | 155 |
1 files changed, 112 insertions, 43 deletions
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index c124974c55b1..6cc8bf215e85 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
| @@ -86,61 +86,130 @@ void cx25840_vbi_setup(struct i2c_client *client) | |||
| 86 | { | 86 | { |
| 87 | struct cx25840_state *state = i2c_get_clientdata(client); | 87 | struct cx25840_state *state = i2c_get_clientdata(client); |
| 88 | v4l2_std_id std = cx25840_get_v4lstd(client); | 88 | v4l2_std_id std = cx25840_get_v4lstd(client); |
| 89 | int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; | ||
| 90 | int luma_lpf,uv_lpf, comb; | ||
| 91 | u32 pll_int,pll_frac,pll_post; | ||
| 89 | 92 | ||
| 93 | /* datasheet startup, step 8d */ | ||
| 90 | if (std & ~V4L2_STD_NTSC) { | 94 | if (std & ~V4L2_STD_NTSC) { |
| 91 | /* datasheet startup, step 8d */ | ||
| 92 | cx25840_write(client, 0x49f, 0x11); | 95 | cx25840_write(client, 0x49f, 0x11); |
| 96 | } else { | ||
| 97 | cx25840_write(client, 0x49f, 0x14); | ||
| 98 | } | ||
| 93 | 99 | ||
| 94 | cx25840_write(client, 0x470, 0x84); | 100 | if (std & V4L2_STD_625_50) { |
| 95 | cx25840_write(client, 0x471, 0x00); | 101 | hblank=0x084; |
| 96 | cx25840_write(client, 0x472, 0x2d); | 102 | hactive=0x2d0; |
| 97 | cx25840_write(client, 0x473, 0x5d); | 103 | burst=0x5d; |
| 98 | 104 | vblank=0x024; | |
| 99 | cx25840_write(client, 0x474, 0x24); | 105 | vactive=0x244; |
| 100 | cx25840_write(client, 0x475, 0x40); | 106 | vblank656=0x28; |
| 101 | cx25840_write(client, 0x476, 0x24); | 107 | src_decimation=0x21f; |
| 102 | cx25840_write(client, 0x477, 0x28); | ||
| 103 | |||
| 104 | cx25840_write(client, 0x478, 0x1f); | ||
| 105 | cx25840_write(client, 0x479, 0x02); | ||
| 106 | 108 | ||
| 109 | luma_lpf=2; | ||
| 107 | if (std & V4L2_STD_SECAM) { | 110 | if (std & V4L2_STD_SECAM) { |
| 108 | cx25840_write(client, 0x47a, 0x80); | 111 | uv_lpf=0; |
| 109 | cx25840_write(client, 0x47b, 0x00); | 112 | comb=0; |
| 110 | cx25840_write(client, 0x47c, 0x5f); | 113 | sc=0x0a425f; |
| 111 | cx25840_write(client, 0x47d, 0x42); | ||
| 112 | } else { | 114 | } else { |
| 113 | cx25840_write(client, 0x47a, 0x90); | 115 | uv_lpf=1; |
| 114 | cx25840_write(client, 0x47b, 0x20); | 116 | comb=0x20; |
| 115 | cx25840_write(client, 0x47c, 0x63); | 117 | sc=0x0a8263; |
| 116 | cx25840_write(client, 0x47d, 0x82); | ||
| 117 | } | 118 | } |
| 118 | |||
| 119 | cx25840_write(client, 0x47e, 0x0a); | ||
| 120 | cx25840_write(client, 0x47f, 0x01); | ||
| 121 | state->vbi_line_offset = 5; | ||
| 122 | } else { | 119 | } else { |
| 123 | /* datasheet startup, step 8d */ | 120 | hactive=720; |
| 124 | cx25840_write(client, 0x49f, 0x14); | 121 | hblank=122; |
| 122 | vactive=487; | ||
| 123 | luma_lpf=1; | ||
| 124 | uv_lpf=1; | ||
| 125 | |||
| 126 | src_decimation=0x21f; | ||
| 127 | if (std == V4L2_STD_PAL_M) { | ||
| 128 | vblank=20; | ||
| 129 | vblank656=24; | ||
| 130 | burst=0x61; | ||
| 131 | comb=0x20; | ||
| 132 | |||
| 133 | sc=555452; | ||
| 134 | } else { | ||
| 135 | vblank=26; | ||
| 136 | vblank656=26; | ||
| 137 | burst=0x5b; | ||
| 138 | comb=0x66; | ||
| 139 | sc=556063; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | /* DEBUG: Displays configured PLL frequency */ | ||
| 144 | pll_int=cx25840_read(client, 0x108); | ||
| 145 | pll_frac=cx25840_read4(client, 0x10c)&0x1ffffff; | ||
| 146 | pll_post=cx25840_read(client, 0x109); | ||
| 147 | v4l_dbg(1, cx25840_debug, client, | ||
| 148 | "PLL regs = int: %u, frac: %u, post: %u\n", | ||
| 149 | pll_int,pll_frac,pll_post); | ||
| 150 | |||
| 151 | if (pll_post) { | ||
| 152 | int fin, fsc; | ||
| 153 | int pll= (28636363L*((((u64)pll_int)<<25L)+pll_frac)) >>25L; | ||
| 154 | |||
| 155 | pll/=pll_post; | ||
| 156 | v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n", | ||
| 157 | pll/1000000, pll%1000000); | ||
| 158 | v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n", | ||
| 159 | pll/8000000, (pll/8)%1000000); | ||
| 160 | |||
| 161 | fin=((u64)src_decimation*pll)>>12; | ||
| 162 | v4l_dbg(1, cx25840_debug, client, "ADC Sampling freq = " | ||
| 163 | "%d.%06d MHz\n", | ||
| 164 | fin/1000000,fin%1000000); | ||
| 165 | |||
| 166 | fsc= (((u64)sc)*pll) >> 24L; | ||
| 167 | v4l_dbg(1, cx25840_debug, client, "Chroma sub-carrier freq = " | ||
| 168 | "%d.%06d MHz\n", | ||
| 169 | fsc/1000000,fsc%1000000); | ||
| 170 | |||
| 171 | v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, " | ||
| 172 | "vblank %i , vactive %i, vblank656 %i, src_dec %i," | ||
| 173 | "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," | ||
| 174 | " sc 0x%06x\n", | ||
| 175 | hblank, hactive, vblank, vactive, vblank656, | ||
| 176 | src_decimation, burst, luma_lpf, uv_lpf, comb, sc); | ||
| 177 | } | ||
| 178 | |||
| 179 | /* Sets horizontal blanking delay and active lines */ | ||
| 180 | cx25840_write(client, 0x470, hblank); | ||
| 181 | cx25840_write(client, 0x471, 0xff&(((hblank>>8)&0x3)|(hactive <<4))); | ||
| 182 | cx25840_write(client, 0x472, hactive>>4); | ||
| 183 | |||
| 184 | /* Sets burst gate delay */ | ||
| 185 | cx25840_write(client, 0x473, burst); | ||
| 125 | 186 | ||
| 126 | cx25840_write(client, 0x470, 0x7a); | 187 | /* Sets vertical blanking delay and active duration */ |
| 127 | cx25840_write(client, 0x471, 0x00); | 188 | cx25840_write(client, 0x474, vblank); |
| 128 | cx25840_write(client, 0x472, 0x2d); | 189 | cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4))); |
| 129 | cx25840_write(client, 0x473, 0x5b); | 190 | cx25840_write(client, 0x476, vactive>>4); |
| 191 | cx25840_write(client, 0x477, vblank656); | ||
| 130 | 192 | ||
| 131 | cx25840_write(client, 0x474, 0x1a); | 193 | /* Sets src decimation rate */ |
| 132 | cx25840_write(client, 0x475, 0x70); | 194 | cx25840_write(client, 0x478, 0xff&src_decimation); |
| 133 | cx25840_write(client, 0x476, 0x1e); | 195 | cx25840_write(client, 0x479, 0xff&(src_decimation>>8)); |
| 134 | cx25840_write(client, 0x477, 0x1e); | ||
| 135 | 196 | ||
| 136 | cx25840_write(client, 0x478, 0x1f); | 197 | /* Sets Luma and UV Low pass filters */ |
| 137 | cx25840_write(client, 0x479, 0x02); | 198 | cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30)); |
| 138 | cx25840_write(client, 0x47a, 0x50); | ||
| 139 | cx25840_write(client, 0x47b, 0x66); | ||
| 140 | 199 | ||
| 141 | cx25840_write(client, 0x47c, 0x1f); | 200 | /* Enables comb filters */ |
| 142 | cx25840_write(client, 0x47d, 0x7c); | 201 | cx25840_write(client, 0x47b, comb); |
| 143 | cx25840_write(client, 0x47e, 0x08); | 202 | |
| 203 | /* Sets SC Step*/ | ||
| 204 | cx25840_write(client, 0x47c, sc); | ||
| 205 | cx25840_write(client, 0x47d, 0xff&sc>>8); | ||
| 206 | cx25840_write(client, 0x47e, 0xff&sc>>16); | ||
| 207 | |||
| 208 | /* Sets VBI parameters */ | ||
| 209 | if (std & V4L2_STD_625_50) { | ||
| 210 | cx25840_write(client, 0x47f, 0x01); | ||
| 211 | state->vbi_line_offset = 5; | ||
| 212 | } else { | ||
| 144 | cx25840_write(client, 0x47f, 0x00); | 213 | cx25840_write(client, 0x47f, 0x00); |
| 145 | state->vbi_line_offset = 8; | 214 | state->vbi_line_offset = 8; |
| 146 | } | 215 | } |
| @@ -186,7 +255,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 186 | 255 | ||
| 187 | case VIDIOC_S_FMT: | 256 | case VIDIOC_S_FMT: |
| 188 | { | 257 | { |
| 189 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); | 258 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); |
| 190 | int vbi_offset = is_pal ? 1 : 0; | 259 | int vbi_offset = is_pal ? 1 : 0; |
| 191 | int i, x; | 260 | int i, x; |
| 192 | u8 lcr[24]; | 261 | u8 lcr[24]; |
